/*
 * 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.
 */

public
class 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;
    }
}
