231 lines · 6.8 KB · Java
RawDownload
/* * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.tools.tree; import sun.tools.java.*;import sun.tools.tree.*;import java.util.Vector; /** * A local Field * * WARNING: The contents of this source file are not part of any * supported API.  Code that depends on them does so at its own risk: * they are subject to change or removal without notice. */ publicclass LocalMember extends MemberDefinition {    /**     * The number of the variable     */    int number = -1;     /**     * Some statistics     */    int readcount;    int writecount;     /**     * An indication of which block the variable comes from.     * Helps identify uplevel references.     */    int scopeNumber;     /**     * Return current nesting level, i.e., the value of 'scopeNumber'.     * Made public for the benefit of 'ClassDefinition.resolveName'.     */    public int getScopeNumber() {        return scopeNumber;    }     /**     * Used by copyInline to record the original of this copy.     */    LocalMember originalOfCopy;     /**     * The previous local variable, this list is used to build a nested     * context of local variables.     */    LocalMember prev;     /**     * Constructor     */    public LocalMember(long where, ClassDefinition clazz, int modifiers, Type type,                      Identifier name) {        super(where, clazz, modifiers, type, name, null, null);    }     /**     * Constructor for a block-inner class.     */    public LocalMember(ClassDefinition innerClass) {        super(innerClass);         // The class's "real" name is something like "foo$1$bar", but locally:        name = innerClass.getLocalName();    }     /**     * Constructor for a proxy to an instance or class variable.     */    LocalMember(MemberDefinition field) {        this(0, null, 0, field.getType(), idClass);        // use this random slot to store the info:        accessPeer = field;    }     /**     * Is this a proxy for the given field?     */    final MemberDefinition getMember() {        return (name == idClass) ? accessPeer : null;    }     /**     * Special checks     */    public boolean isLocal() {        return true;    }     /**     * Make a copy of this field, which is an argument to a method     * or constructor.  Arrange so that when occurrences of the field     * are encountered in an immediately following copyInline() operation,     * the expression nodes will replace the original argument by the     * fresh copy.     */    public LocalMember copyInline(Context ctx) {        LocalMember copy = new LocalMember(where, clazz, modifiers, type, name);        copy.readcount = this.readcount;        copy.writecount = this.writecount;         copy.originalOfCopy = this;         // Make a temporary link from the original.        // It only stays valid through the next call to copyInline().        // (This means that recursive inlining won't work.)        // To stay honest, we mark these inline copies:        copy.addModifiers(M_LOCAL);        if (this.accessPeer != null            && (this.accessPeer.getModifiers() & M_LOCAL) == 0) {            throw new CompilerError("local copyInline");        }        this.accessPeer = copy;         return copy;    }     /**     * Returns the previous result of copyInline(ctx).     * Must be called in the course of an Expression.copyInline()     * operation that immediately follows the LocalMember.copyInline().     * Return "this" if there is no such copy.     */    public LocalMember getCurrentInlineCopy(Context ctx) {        MemberDefinition accessPeer = this.accessPeer;        if (accessPeer != null && (accessPeer.getModifiers() & M_LOCAL) != 0) {            LocalMember copy = (LocalMember)accessPeer;            return copy;        }        return this;    }     /**     * May inline copies of all the arguments of the given method.     */    static public LocalMember[] copyArguments(Context ctx, MemberDefinition field) {        Vector v = field.getArguments();        LocalMember res[] = new LocalMember[v.size()];        v.copyInto(res);        for (int i = 0; i < res.length; i++) {            res[i] = res[i].copyInline(ctx);        }        return res;    }     /**     * Call this when finished with the result of a copyArguments() call.     */    static public void doneWithArguments(Context ctx, LocalMember res[]) {        for (int i = 0; i < res.length; i++) {            if (res[i].originalOfCopy.accessPeer == res[i]) {                res[i].originalOfCopy.accessPeer = null;            }        }    }     /**     * Is this local variable's value stable and simple enough to be directly     * substituted for occurrences of the variable itself?     * (This decision is made by VarDeclarationStatement.inline().)     */    public boolean isInlineable(Environment env, boolean fromFinal) {        return (getModifiers() & M_INLINEABLE) != 0;    }     /**     * Check if used     */    public boolean isUsed() {        return (readcount != 0) || (writecount != 0);    }     // Used by class Context, only on members of MemberDefinition.available:    LocalMember getAccessVar() {        return (LocalMember)accessPeer;    }    void setAccessVar(LocalMember f) {        accessPeer = f;    }    // Used by class Context, only on "AccessVar" constructor args    MemberDefinition getAccessVarMember() {        return accessPeer;    }    void setAccessVarMember(MemberDefinition f) {        accessPeer = f;    }      /**     * Return value     */    public Node getValue(Environment env) {        return (Expression)getValue();    }     /**     * Value number for vsets, or -1 if none.     */    public int getNumber(Context ctx) {        return number;    }}