/*
 * Copyright 1994-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.tools.java;

import sun.tools.tree.Node;
import sun.tools.tree.Vset;
import sun.tools.tree.Expression;
import sun.tools.tree.Statement;
import sun.tools.tree.Context;
import sun.tools.asm.Assembler;
import java.io.PrintStream;
import java.util.Vector;
import java.util.Map;
import java.util.HashMap;

/**
 * This class defines a member of a Java class:
 * a variable, a method, or an inner class.
 *
 * 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 MemberDefinition implements Constants {
    protected long where;
    protected int modifiers;
    protected Type type;
    protected String documentation;
    protected IdentifierToken expIds[];
    protected ClassDeclaration exp[];
    protected Node value;
    protected ClassDefinition clazz;
    protected Identifier name;
    protected ClassDefinition innerClass;
    protected MemberDefinition nextMember;
    protected MemberDefinition nextMatch;
    protected MemberDefinition accessPeer;
    protected boolean superAccessMethod;

    /**
     * Constructor
     */
    public MemberDefinition(long where, ClassDefinition clazz, int modifiers,
                            Type type, Identifier name,
                            IdentifierToken expIds[], Node value) {
        if (expIds == null) {
            expIds = new IdentifierToken[0];
        }
        this.where = where;
        this.clazz = clazz;
        this.modifiers = modifiers;
        this.type = type;
        this.name = name;
        this.expIds = expIds;
        this.value = value;
    }

    /**
     * Constructor for an inner class.
     * Inner classes are represented as fields right along with
     * variables and methods for simplicity of data structure,
     * and to reflect properly the textual declaration order.
     * <p>
     * This constructor calls the generic constructor for this
     * class, extracting all necessary values from the innerClass.
     */
    public MemberDefinition(ClassDefinition innerClass) {
        this(innerClass.getWhere(),
             innerClass.getOuterClass(),
             innerClass.getModifiers(),
             innerClass.getType(),
             innerClass.getName().getFlatName().getName(),
             null, null);
        this.innerClass = innerClass;
    }

    /**
     * A cache of previously created proxy members.  Used to ensure
     * uniqueness of proxy objects.  See the makeProxyMember method
     * defined below.
     */
    static private Map proxyCache;

    /**
     * Create a member which is externally the same as `field' but
     * is defined in class `classDef'.  This is used by code
     * in sun.tools.tree.(MethodExpression,FieldExpression) as
     * part of the fix for bug 4135692.
     *
     * Proxy members should not be added, ala addMember(), to classes.
     * They are merely "stand-ins" to produce modified MethodRef
     * constant pool entries during code generation.
     *
     * We keep a cache of previously created proxy members not to
     * save time or space, but to ensure uniqueness of the proxy
     * member for any (field,classDef) pair.  If these are not made
     * unique then we can end up generating duplicate MethodRef
     * constant pool entries during code generation.
     */
    public static MemberDefinition makeProxyMember(MemberDefinition field,
                                                   ClassDefinition classDef,
                                                   Environment env) {

        if (proxyCache == null) {
            proxyCache = new HashMap();
        }

        String key = field.toString() + "@" + classDef.toString();
        // System.out.println("Key is : " + key);
        MemberDefinition proxy = (MemberDefinition)proxyCache.get(key);

        if (proxy != null)
            return proxy;

        proxy = new MemberDefinition(field.getWhere(), classDef,
                                     field.getModifiers(), field.getType(),
                                     field.getName(), field.getExceptionIds(),
                                     null);
        proxy.exp = field.getExceptions(env);
        proxyCache.put(key, proxy);

        return proxy;
    }

    /**
     * Get the position in the input
     */
    public final long getWhere() {
        return where;
    }

    /**
     * Get the class declaration
     */
    public final ClassDeclaration getClassDeclaration() {
        return clazz.getClassDeclaration();
    }

    /**
     * A stub.  Subclasses can do more checking.
     */
    public void resolveTypeStructure(Environment env) {
    }

    /**
     * Get the class declaration in which the field is actually defined
     */
    public ClassDeclaration getDefiningClassDeclaration() {
        return getClassDeclaration();
    }

    /**
     * Get the class definition
     */
    public final ClassDefinition getClassDefinition() {
        return clazz;
    }

    /**
     * Get the field's top-level enclosing class
     */
    public final ClassDefinition getTopClass() {
        return clazz.getTopClass();
    }

    /**
     * Get the field's modifiers
     */
    public final int getModifiers() {
        return modifiers;
    }
    public final void subModifiers(int mod) {
        modifiers &= ~mod;
    }
    public final void addModifiers(int mod) {
        modifiers |= mod;
    }

    /**
     * Get the field's type
     */
    public final Type getType() {
        return type;
    }

    /**
     * Get the field's name
     */
    public final Identifier getName() {
        return name;
    }

    /**
     * Get arguments (a vector of LocalMember)
     */
    public Vector getArguments() {
        return isMethod() ? new Vector() : null;
    }

    /**
     * Get the exceptions that are thrown by this method.
     */
    public ClassDeclaration[] getExceptions(Environment env) {
        if (expIds != null && exp == null) {
            if (expIds.length == 0)
                exp = new ClassDeclaration[0];
            else
                // we should have translated this already!
                throw new CompilerError("getExceptions "+this);
        }
        return exp;
    }

    public final IdentifierToken[] getExceptionIds() {
        return expIds;
    }

    /**
     * Get an inner class.
     */
    public ClassDefinition getInnerClass() {
        return innerClass;
    }

    /**
     * Is this a synthetic field which holds a copy of,
     * or reference to, a local variable or enclosing instance?
     */
    public boolean isUplevelValue() {
        if (!isSynthetic() || !isVariable() || isStatic()) {
            return false;
        }
        String name = this.name.toString();
        return name.startsWith(prefixVal)
            || name.toString().startsWith(prefixLoc)
            || name.toString().startsWith(prefixThis);
    }

    public boolean isAccessMethod() {
        // This no longer works, because access methods
        // for constructors do not use the standard naming
        // scheme.
        //    return isSynthetic() && isMethod()
        //        && name.toString().startsWith(prefixAccess);
        // Assume that a method is an access method if it has
        // an access peer.  NOTE: An access method will not be
        // recognized as such until 'setAccessMethodTarget' has
        // been called on it.
        return isSynthetic() && isMethod() && (accessPeer != null);
    }

    /**
     * Is this a synthetic method which provides access to a
     * visible private member?
     */
    public MemberDefinition getAccessMethodTarget() {
        if (isAccessMethod()) {
            for (MemberDefinition f = accessPeer; f != null; f = f.accessPeer) {
                // perhaps skip over another access for the same field
                if (!f.isAccessMethod()) {
                    return f;
                }
            }
        }
        return null;
    }


    public void setAccessMethodTarget(MemberDefinition target) {
        if (getAccessMethodTarget() != target) {
            /*-------------------*
            if (!isAccessMethod() || accessPeer != null ||
                    target.accessPeer != null) {
                throw new CompilerError("accessPeer");
            }
            *-------------------*/
            if (accessPeer != null || target.accessPeer != null) {
                throw new CompilerError("accessPeer");
            }
            accessPeer = target;
        }
    }

    /**
     * If this method is a getter for a private field, return the setter.
     */
    public MemberDefinition getAccessUpdateMember() {
        if (isAccessMethod()) {
            for (MemberDefinition f = accessPeer; f != null; f = f.accessPeer) {
                if (f.isAccessMethod()) {
                    return f;
                }
            }
        }
        return null;
    }

    public void setAccessUpdateMember(MemberDefinition updater) {
        if (getAccessUpdateMember() != updater) {
            if (!isAccessMethod() ||
                    updater.getAccessMethodTarget() != getAccessMethodTarget()) {
                throw new CompilerError("accessPeer");
            }
            updater.accessPeer = accessPeer;
            accessPeer = updater;
        }
    }

    /**
     * Is this an access method for a field selection or method call
     * of the form '...super.foo' or '...super.foo()'?
     */
    public final boolean isSuperAccessMethod() {
        return superAccessMethod;
    }

    /**
     * Mark this member as an access method for a field selection
     * or method call via the 'super' keyword.
     */
    public final void setIsSuperAccessMethod(boolean b) {
        superAccessMethod = b;
    }

    /**
     * Tell if this is a final variable without an initializer.
     * Such variables are subject to definite single assignment.
     */
    public final boolean isBlankFinal() {
        return isFinal() && !isSynthetic() && getValue() == null;
    }

    public boolean isNeverNull() {
        if (isUplevelValue()) {
            // loc$x and this$C are never null
            return !name.toString().startsWith(prefixVal);
        }
        return false;
    }

    /**
     * Get the field's final value (may return null)
     */
    public Node getValue(Environment env) throws ClassNotFound {
        return value;
    }
    public final Node getValue() {
        return value;
    }
    public final void setValue(Node value) {
        this.value = value;
    }
    public Object getInitialValue() {
        return null;
    }

    /**
     * Get the next field or the next match
     */
    public final MemberDefinition getNextMember() {
        return nextMember;
    }
    public final MemberDefinition getNextMatch() {
        return nextMatch;
    }

    /**
     * Get the field's documentation
     */
    public String getDocumentation() {
        return documentation;
    }

    /**
     * Request a check of the field definition.
     */
    public void check(Environment env) throws ClassNotFound {
    }

    /**
     * Really check the field definition.
     */
    public Vset check(Environment env, Context ctx, Vset vset) throws ClassNotFound {
        return vset;
    }

    /**
     * Generate code
     */
    public void code(Environment env, Assembler asm) throws ClassNotFound {
        throw new CompilerError("code");
    }
    public void codeInit(Environment env, Context ctx, Assembler asm) throws ClassNotFound {
        throw new CompilerError("codeInit");
    }

    /**
     * Tells whether to report a deprecation error for this field.
     */
    public boolean reportDeprecated(Environment env) {
        return (isDeprecated() || clazz.reportDeprecated(env));
    }

    /**
     * Check if a field can reach another field (only considers
     * forward references, not the access modifiers).
     */
    public final boolean canReach(Environment env, MemberDefinition f) {
        if (f.isLocal() || !f.isVariable() || !(isVariable() || isInitializer()))
            return true;
        if ((getClassDeclaration().equals(f.getClassDeclaration())) &&
            (isStatic() == f.isStatic())) {
            // They are located in the same class, and are either both
            // static or both non-static.  Check the initialization order.
            while (((f = f.getNextMember()) != null) && (f != this));
            return f != null;
        }
        return true;
    }

    //-----------------------------------------------------------------
    // The code in this section is intended to test certain kinds of
    // compatibility between methods.  There are two kinds of compatibility
    // that the compiler may need to test.  The first is whether one
    // method can legally override another.  The second is whether two
    // method definitions can legally coexist.  We use the word `meet'
    // to mean the intersection of two legally coexisting methods.
    // For more information on these kinds of compatibility, see the
    // comments/code for checkOverride() and checkMeet() below.

    /**
     * Constants used by getAccessLevel() to represent the access
     * modifiers as numbers.
     */
    static final int PUBLIC_ACCESS = 1;
    static final int PROTECTED_ACCESS = 2;
    static final int PACKAGE_ACCESS = 3;
    static final int PRIVATE_ACCESS = 4;

    /**
     * Return the access modifier of this member as a number.  The idea
     * is that this number may be used to check properties like "the
     * access modifier of x is more restrictive than the access
     * modifier of y" with a simple inequality test:
     * "x.getAccessLevel() > y.getAccessLevel.
     *
     * This is an internal utility method.
     */
    private int getAccessLevel() {
        // Could just compute this once instead of recomputing.
        // Check to see if this is worth it.
        if (isPublic()) {
            return PUBLIC_ACCESS;
        } else if (isProtected()) {
            return PROTECTED_ACCESS;
        } else if (isPackagePrivate()) {
            return PACKAGE_ACCESS;
        } else if (isPrivate()) {
            return PRIVATE_ACCESS;
        } else {
            throw new CompilerError("getAccessLevel()");
        }
    }

    /**
     * Munge our error message to report whether the override conflict
     * came from an inherited method or a declared method.
     */
    private void reportError(Environment env, String errorString,
                             ClassDeclaration clazz,
                             MemberDefinition method) {

        if (clazz == null) {
            // For example:
            // "Instance method BLAH inherited from CLASSBLAH1 cannot be
            //  overridden by the static method declared in CLASSBLAH2."
            env.error(getWhere(), errorString,
                      this, getClassDeclaration(),
                      method.getClassDeclaration());
        } else {
            // For example:
            // "In CLASSBLAH1, instance method BLAH inherited from CLASSBLAH2
            //  cannot be overridden by the static method inherited from
            //  CLASSBLAH3."
            env.error(clazz.getClassDefinition().getWhere(),
                      //"inherit." + errorString,
                      errorString,
                      //clazz,
                      this, getClassDeclaration(),
                      method.getClassDeclaration());
        }
    }

    /**
     * Convenience method to see if two methods return the same type
     */
    public boolean sameReturnType(MemberDefinition method) {
        // Make sure both are methods.
        if (!isMethod() || !method.isMethod()) {
            throw new CompilerError("sameReturnType: not method");
        }

        Type myReturnType = getType().getReturnType();
        Type yourReturnType = method.getType().getReturnType();

        return (myReturnType == yourReturnType);
    }

    /**
     * Check to see if `this' can override/hide `method'.  Caller is
     * responsible for verifying that `method' has the same signature
     * as `this'.  Caller is also responsible for verifying that
     * `method' is visible to the class where this override is occurring.
     * This method is called for the case when class B extends A and both
     * A and B define some method.
     * <pre>
     *       A - void foo() throws e1
     *       |
     *       |
     *       B - void foo() throws e2
     * </pre>
     */
    public boolean checkOverride(Environment env, MemberDefinition method) {
        return checkOverride(env, method, null);
    }

    /**
     * Checks whether `this' can override `method'.  It `clazz' is
     * null, it reports the errors in the class where `this' is
     * declared.  If `clazz' is not null, it reports the error in `clazz'.
     */
    private boolean checkOverride(Environment env,
                                  MemberDefinition method,
                                  ClassDeclaration clazz) {
        // This section of code is largely based on section 8.4.6.3
        // of the JLS.

        boolean success = true;

        // Sanity
        if (!isMethod()) {
            throw new CompilerError("checkOverride(), expected method");
        }

        // Suppress checks for synthetic methods, as the compiler presumably
        // knows what it is doing, e.g., access methods.
        if (isSynthetic()) {
            // Sanity check: We generally do not intend for one synthetic
            // method to override another, though hiding of static members
            // is expected.  This check may need to be changed if new uses
            // of synthetic methods are devised.
            //
            // Query: this code was copied from elsewhere.  What
            // exactly is the role of the !isStatic() in the test?
            if (method.isFinal() ||
                (!method.isConstructor() &&
                 !method.isStatic() && !isStatic())) {
                ////////////////////////////////////////////////////////////
                // NMG 2003-01-28 removed the following test because it is
                // invalidated by bridge methods inserted by the "generic"
                // (1.5) Java compiler.  In 1.5, this code is used,
                // indirectly, by rmic
                ////////////////////////////////////////////////////////////
                // throw new CompilerError("checkOverride() synthetic");
                ////////////////////////////////////////////////////////////
            }

            // We trust the compiler.  (Ha!)  We're done checking.
            return true;
        }

        // Our caller should have verified that the method had the
        // same signature.
        if (getName() != method.getName() ||
            !getType().equalArguments(method.getType())) {

            throw new CompilerError("checkOverride(), signature mismatch");
        }

        // It is forbidden to `override' a static method with an instance
        // method.
        if (method.isStatic() && !isStatic()) {
            reportError(env, "override.static.with.instance", clazz, method);
            success = false;
        }

        // It is forbidden to `hide' an instance method with a static
        // method.
        if (!method.isStatic() && isStatic()) {
            reportError(env, "hide.instance.with.static", clazz, method);
            success = false;
        }

        // We cannot override a final method.
        if (method.isFinal()) {
            reportError(env, "override.final.method", clazz, method);
            success = false;
        }

        // Give a warning when we override a deprecated method with
        // a non-deprecated one.
        //
        // We bend over backwards to suppress this warning if
        // the `method' has not been already compiled or
        // `this' has been already compiled.
        if (method.reportDeprecated(env) && !isDeprecated()
               && this instanceof sun.tools.javac.SourceMember) {
            reportError(env, "warn.override.is.deprecated",
                        clazz, method);
        }

        // Visibility may not be more restrictive
        if (getAccessLevel() > method.getAccessLevel()) {
            reportError(env, "override.more.restrictive", clazz, method);
            success = false;
        }

        // Return type equality
        if (!sameReturnType(method)) {
            ////////////////////////////////////////////////////////////
            // PCJ 2003-07-30 removed the following error because it is
            // invalidated by the covariant return type feature of the
            // 1.5 compiler.  The resulting check is now much looser
            // than the actual 1.5 language spec, but that should be OK
            // because this code is only still used by rmic.  See 4892308.
            ////////////////////////////////////////////////////////////
            // reportError(env, "override.different.return", clazz, method);
            // success = false;
            ////////////////////////////////////////////////////////////
        }

        // Exception agreeement
        if (!exceptionsFit(env, method)) {
            reportError(env, "override.incompatible.exceptions",
                        clazz, method);
            success = false;
        }

        return success;
    }

    /**
     * Check to see if two method definitions are compatible, that is
     * do they have a `meet'.  The meet of two methods is essentially
     * and `intersection' of
     * two methods.  This method is called when some class C inherits
     * declarations for some method foo from two parents (superclass,
     * interfaces) but it does not, itself, have a declaration of foo.
     * Caller is responsible for making sure that both methods are
     * indeed visible in clazz.
     * <pre>
     *     A - void foo() throws e1
     *      \
     *       \     B void foo() throws e2
     *        \   /
     *         \ /
     *          C
     * </pre>
     */
    public boolean checkMeet(Environment env,
                             MemberDefinition method,
                             ClassDeclaration clazz) {
        // This section of code is largely based on Section 8.4.6
        // and 9.4.1 of the JLS.

        // Sanity
        if (!isMethod()) {
            throw new CompilerError("checkMeet(), expected method");
        }

        // Check for both non-abstract.
        if (!isAbstract() && !method.isAbstract()) {
            throw new CompilerError("checkMeet(), no abstract method");
        }

        // If either method is non-abstract, then we need to check that
        // the abstract method can be properly overridden.  We call
        // the checkOverride method to check this and generate any errors.
        // This test must follow the previous test.
        else if (!isAbstract()) {
            return checkOverride(env, method, clazz);
        } else if (!method.isAbstract()) {
            return method.checkOverride(env, this, clazz);
        }

        // Both methods are abstract.

        // Our caller should have verified that the method has the
        // same signature.
        if (getName() != method.getName() ||
            !getType().equalArguments(method.getType())) {

            throw new CompilerError("checkMeet(), signature mismatch");
        }

        // Check for return type equality
        if (!sameReturnType(method)) {
            // More args?
            env.error(clazz.getClassDefinition().getWhere(),
                      "meet.different.return",
                      this, this.getClassDeclaration(),
                      method.getClassDeclaration());
            return false;
        }

        // We don't have to check visibility -- there always
        // potentially exists a meet.  Similarly with exceptions.

        // There does exist a meet.
        return true;
    }

    /**
     * This method is meant to be used to determine if one of two inherited
     * methods could override the other.  Unlike checkOverride(), failure
     * is not an error.  This method is only meant to be called after
     * checkMeet() has succeeded on the two methods.
     *
     * If you call couldOverride() without doing a checkMeet() first, then
     * you are on your own.
     */
    public boolean couldOverride(Environment env,
                                 MemberDefinition method) {

        // Sanity
        if (!isMethod()) {
            throw new CompilerError("coulcOverride(), expected method");
        }

        // couldOverride() is only called with `this' and `method' both
        // being inherited methods.  Neither of them is defined in the
        // class which we are currently working on.  Even though an
        // abstract method defined *in* a class can override a non-abstract
        // method defined in a superclass, an abstract method inherited
        // from an interface *never* can override a non-abstract method.
        // This comment may sound odd, but that's the way inheritance is.
        // The following check makes sure we aren't trying to override
        // an inherited non-abstract definition with an abstract definition
        // from an interface.
        if (!method.isAbstract()) {
            return false;
        }

        // Visibility should be less restrictive
        if (getAccessLevel() > method.getAccessLevel()) {
            return false;
        }

        // Exceptions
        if (!exceptionsFit(env, method)) {
            return false;
        }

        // Potentially some deprecation warnings could be given here
        // when we merge two abstract methods, one of which is deprecated.
        // This is not currently reported.

        return true;
    }

    /**
     * Check to see if the exceptions of `this' fit within the
     * exceptions of `method'.
     */
    private boolean exceptionsFit(Environment env,
                                  MemberDefinition method) {
        ClassDeclaration e1[] = getExceptions(env);        // my exceptions
        ClassDeclaration e2[] = method.getExceptions(env); // parent's

        // This code is taken nearly verbatim from the old implementation
        // of checkOverride() in SourceClass.
    outer:
        for (int i = 0 ; i < e1.length ; i++) {
            try {
                ClassDefinition c1 = e1[i].getClassDefinition(env);
                for (int j = 0 ; j < e2.length ; j++) {
                    if (c1.subClassOf(env, e2[j])) {
                        continue outer;
                    }
                }
                if (c1.subClassOf(env,
                                  env.getClassDeclaration(idJavaLangError)))
                    continue outer;
                if (c1.subClassOf(env,
                                  env.getClassDeclaration(idJavaLangRuntimeException)))
                    continue outer;

                // the throws was neither something declared by a parent,
                // nor one of the ignorables.
                return false;

            } catch (ClassNotFound ee) {
                // We were unable to find one of the exceptions.
                env.error(getWhere(), "class.not.found",
                          ee.name, method.getClassDeclaration());
            }
        }

        // All of the exceptions `fit'.
        return true;
    }

    //-----------------------------------------------------------------

    /**
     * Checks
     */
    public final boolean isPublic() {
        return (modifiers & M_PUBLIC) != 0;
    }
    public final boolean isPrivate() {
        return (modifiers & M_PRIVATE) != 0;
    }
    public final boolean isProtected() {
        return (modifiers & M_PROTECTED) != 0;
    }
    public final boolean isPackagePrivate() {
        return (modifiers & (M_PUBLIC | M_PRIVATE | M_PROTECTED)) == 0;
    }
    public final boolean isFinal() {
        return (modifiers & M_FINAL) != 0;
    }
    public final boolean isStatic() {
        return (modifiers & M_STATIC) != 0;
    }
    public final boolean isSynchronized() {
        return (modifiers & M_SYNCHRONIZED) != 0;
    }
    public final boolean isAbstract() {
        return (modifiers & M_ABSTRACT) != 0;
    }
    public final boolean isNative() {
        return (modifiers & M_NATIVE) != 0;
    }
    public final boolean isVolatile() {
        return (modifiers & M_VOLATILE) != 0;
    }
    public final boolean isTransient() {
        return (modifiers & M_TRANSIENT) != 0;
    }
    public final boolean isMethod() {
        return type.isType(TC_METHOD);
    }
    public final boolean isVariable() {
        return !type.isType(TC_METHOD) && innerClass == null;
    }
    public final boolean isSynthetic() {
        return (modifiers & M_SYNTHETIC) != 0;
    }
    public final boolean isDeprecated() {
        return (modifiers & M_DEPRECATED) != 0;
    }
    public final boolean isStrict() {
        return (modifiers & M_STRICTFP) != 0;
    }
    public final boolean isInnerClass() {
        return innerClass != null;
    }
    public final boolean isInitializer() {
        return getName().equals(idClassInit);
    }
    public final boolean isConstructor() {
        return getName().equals(idInit);
    }
    public boolean isLocal() {
        return false;
    }
    public boolean isInlineable(Environment env, boolean fromFinal) throws ClassNotFound {
        return (isStatic() || isPrivate() || isFinal() || isConstructor() || fromFinal) &&
            !(isSynchronized() || isNative());
    }

    /**
     * Check if constant:  Will it inline away to a constant?
     */
    public boolean isConstant() {
        if (isFinal() && isVariable() && value != null) {
            try {
                // If an infinite regress requeries this name,
                // deny that it is a constant.
                modifiers &= ~M_FINAL;
                return ((Expression)value).isConstant();
            } finally {
                modifiers |= M_FINAL;
            }
        }
        return false;
    }

    /**
     * toString
     */
    public String toString() {
        Identifier name = getClassDefinition().getName();
        if (isInitializer()) {
            return isStatic() ? "static {}" : "instance {}";
        } else if (isConstructor()) {
            StringBuffer buf = new StringBuffer();
            buf.append(name);
            buf.append('(');
            Type argTypes[] = getType().getArgumentTypes();
            for (int i = 0 ; i < argTypes.length ; i++) {
                if (i > 0) {
                    buf.append(',');
                }
                buf.append(argTypes[i].toString());
            }
            buf.append(')');
            return buf.toString();
        } else if (isInnerClass()) {
            return getInnerClass().toString();
        }
        return type.typeString(getName().toString());
    }

    /**
     * Print for debugging
     */
    public void print(PrintStream out) {
        if (isPublic()) {
            out.print("public ");
        }
        if (isPrivate()) {
            out.print("private ");
        }
        if (isProtected()) {
            out.print("protected ");
        }
        if (isFinal()) {
            out.print("final ");
        }
        if (isStatic()) {
            out.print("static ");
        }
        if (isSynchronized()) {
            out.print("synchronized ");
        }
        if (isAbstract()) {
            out.print("abstract ");
        }
        if (isNative()) {
            out.print("native ");
        }
        if (isVolatile()) {
            out.print("volatile ");
        }
        if (isTransient()) {
            out.print("transient ");
        }
        out.println(toString() + ";");
    }

    public void cleanup(Environment env) {
        documentation = null;
        if (isMethod() && value != null) {
            int cost = 0;
            if (isPrivate() || isInitializer()) {
                value = Statement.empty;
            } else if ((cost =
                        ((Statement)value)
                       .costInline(Statement.MAXINLINECOST, null, null))
                                >= Statement.MAXINLINECOST) {
                // will never be inlined
                value = Statement.empty;
            } else {
                try {
                    if (!isInlineable(null, true)) {
                        value = Statement.empty;
                    }
                }
                catch (ClassNotFound ee) { }
            }
            if (value != Statement.empty && env.dump()) {
                env.output("[after cleanup of " + getName() + ", " +
                           cost + " expression cost units remain]");
            }
        } else if (isVariable()) {
            if (isPrivate() || !isFinal() || type.isType(TC_ARRAY)) {
                value = null;
            }
        }
    }
}
