jdk/src/share/classes/sun/tools/javac/SourceMember.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1994-2004 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.tools.javac;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import sun.tools.java.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import sun.tools.tree.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import sun.tools.asm.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.util.Vector;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.Enumeration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.util.Hashtable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.io.PrintStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * A Source Member
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * WARNING: The contents of this source file are not part of any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * supported API.  Code that depends on them does so at its own risk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * they are subject to change or removal without notice.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
@Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
public
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
class SourceMember extends MemberDefinition implements Constants {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
     * The argument names (if it is a method)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    Vector args;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    // set to the MemberDefinition in the interface if we have this field because
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    // it has been forced on us
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    MemberDefinition abstractSource;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
     * The status of the field
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    int status;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    static final int PARSED     = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    static final int CHECKING   = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    static final int CHECKED    = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    static final int INLINING   = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    static final int INLINED    = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    static final int ERROR      = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    public Vector getArguments() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        return args;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
     * Constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     * @param argNames a vector of IdentifierToken
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    public SourceMember(long where, ClassDefinition clazz,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
                       String doc, int modifiers, Type type,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
                       Identifier name, Vector argNames,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
                       IdentifierToken exp[], Node value) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
        super(where, clazz, modifiers, type, name, exp, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
        this.documentation = doc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        this.args = argNames;   // for the moment
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        // not until type names are resolved: createArgumentFields(argNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
        if (ClassDefinition.containsDeprecated(documentation)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
            this.modifiers |= M_DEPRECATED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    void createArgumentFields(Vector argNames) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        // Create a list of arguments
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        if (isMethod()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
            args = new Vector();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            if (isConstructor() || !(isStatic() || isInitializer())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
                args.addElement(((SourceClass)clazz).getThisArgument());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
            if (argNames != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
                Enumeration e = argNames.elements();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
                Type argTypes[] = getType().getArgumentTypes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
                for (int i = 0 ; i < argTypes.length ; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
                    Object x = e.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                    if (x instanceof LocalMember) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                        // This should not happen, but it does
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                        // in cases of vicious cyclic inheritance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
                        args = argNames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
                        return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
                    Identifier id;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
                    int mod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
                    long where;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
                    if (x instanceof Identifier) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                        // allow argNames to be simple Identifiers (deprecated!)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                        id = (Identifier)x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                        mod = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                        where = getWhere();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                        IdentifierToken token = (IdentifierToken)x;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                        id = token.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                        mod = token.getModifiers();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
                        where = token.getWhere();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
                    args.addElement(new LocalMember(where, clazz, mod,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
                                                   argTypes[i], id));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    // The methods addOuterThis() and addUplevelArguments() were
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    // both originally part of a single method called addUplevelArguments()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    // which took a single boolean parameter describing which of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    // two behaviors it wanted.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    // The original addUplevelArguments() claimed to keep the arguments in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    // the following order:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    // (1) <this> <early outer this> <uplevel arguments...> <true arguments...>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    // (By <early outer this> I am referring to the clientOuterField added
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    // to some constructors when they are created.  If an outer this is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    // added later, on demand, then this is mixed in with the rest of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    // uplevel arguments and is added by addUplevelArguments.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    // In reality, the `args' Vector was generated in this order, but the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    // Type array `argTypes' was generated as:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    // (2) <this> <uplevel arguments...> <early outer this> <true arguments...>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    // This didn't make a difference in the common case -- that is, when
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    // a class had an <outer.this> or <uplevel arguments...> but not both.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    // Both can happen in the case that a member class is declared inside
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    // of a local class.  It seems that the calling sequences, generated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    // in places like NewInstanceExpression.codeCommon(), use order (2),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    // so I have changed the code below to stick with that order.  Since
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    // the only time this happens is in classes which are insideLocal, no
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    // one should be able to tell the difference between these orders.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    // (bug number 4085633)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    LocalMember outerThisArg = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * Get outer instance link, or null if none.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    public LocalMember getOuterThisArg() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        return outerThisArg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * Add the outer.this argument to the list of arguments for this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * constructor.  This is called from resolveTypeStructure.  Any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     * additional uplevel arguments get added later by addUplevelArguments().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    void addOuterThis() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        UplevelReference refs = clazz.getReferences();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        // See if we have a client outer field.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        while (refs != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
               !refs.isClientOuterField()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            refs = refs.getNext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        // There is no outer this argument.  Quit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        if (refs == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        // Get the old arg types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        Type oldArgTypes[] = type.getArgumentTypes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        // And make an array for the new ones with space for one more.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        Type argTypes[] = new Type[oldArgTypes.length + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        LocalMember arg = refs.getLocalArgument();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        outerThisArg = arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        // args is our list of arguments.  It contains a `this', so
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        // we insert at position 1.  The list of types does not have a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        // this, so we insert at position 0.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        args.insertElementAt(arg, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        argTypes[0] = arg.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        // Add on the rest of the constructor arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        for (int i = 0; i < oldArgTypes.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            argTypes[i + 1] = oldArgTypes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        type = Type.tMethod(type.getReturnType(), argTypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     * Prepend argument names and argument types for local variable references.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     * This information is never seen by the type-check phase,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * but it affects code generation, which is the earliest moment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     * we have comprehensive information on uplevel references.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     * The code() methods tweaks the constructor calls, prepending
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
     * the proper values to the argument list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    void addUplevelArguments() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        UplevelReference refs = clazz.getReferences();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        clazz.getReferencesFrozen();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        // Count how many uplevels we have to add.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        int count = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        for (UplevelReference r = refs; r != null; r = r.getNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            if (!r.isClientOuterField()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                count += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        if (count == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            // None to add, quit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        // Get the old argument types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        Type oldArgTypes[] = type.getArgumentTypes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        // Make an array with enough room for the new.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        Type argTypes[] = new Type[oldArgTypes.length + count];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        // Add all of the late uplevel references to args and argTypes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        // Note that they are `off-by-one' because of the `this'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        int ins = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        for (UplevelReference r = refs; r != null; r = r.getNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            if (!r.isClientOuterField()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                LocalMember arg = r.getLocalArgument();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                args.insertElementAt(arg, 1 + ins);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                argTypes[ins] = arg.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                ins++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        // Add the rest of the old arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        for (int i = 0; i < oldArgTypes.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            argTypes[ins + i] = oldArgTypes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        type = Type.tMethod(type.getReturnType(), argTypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     * Constructor for an inner class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    public SourceMember(ClassDefinition innerClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        super(innerClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * Constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     * Used only to generate an abstract copy of a method that a class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * inherits from an interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    public SourceMember(MemberDefinition f, ClassDefinition c, Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        this(f.getWhere(), c, f.getDocumentation(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
             f.getModifiers() | M_ABSTRACT, f.getType(), f.getName(), null,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
             f.getExceptionIds(), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        this.args = f.getArguments();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        this.abstractSource = f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        this.exp = f.getExceptions(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * Get exceptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    public ClassDeclaration[] getExceptions(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        if ((!isMethod()) || (exp != null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            return exp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        if (expIds == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            // (should not happen)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            exp = new ClassDeclaration[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            return exp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        // be sure to get the imports right:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        env = ((SourceClass)getClassDefinition()).setupEnv(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        exp = new ClassDeclaration[expIds.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        for (int i = 0; i < exp.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            Identifier e = expIds[i].getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            Identifier rexp = getClassDefinition().resolveName(env, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            exp[i] = env.getClassDeclaration(rexp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        return exp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
     * Set array of name-resolved exceptions directly, e.g., for access methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    public void setExceptions(ClassDeclaration[] exp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        this.exp = exp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * Resolve types in a field, after parsing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     * @see ClassDefinition.resolveTypeStructure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    public boolean resolved = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    public void resolveTypeStructure(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        if (tracing) env.dtEnter("SourceMember.resolveTypeStructure: " + this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        // A member should only be resolved once.  For a constructor, it is imperative
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        // that 'addOuterThis' be called only once, else the outer instance argument may
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        // be inserted into the argument list multiple times.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        if (resolved) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            if (tracing) env.dtEvent("SourceMember.resolveTypeStructure: OK " + this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            // This case shouldn't be happening.  It is the responsibility
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
            // of our callers to avoid attempting multiple resolutions of a member.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            // *** REMOVE FOR SHIPMENT? ***
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            throw new CompilerError("multiple member type resolution");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            //return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            if (tracing) env.dtEvent("SourceMember.resolveTypeStructure: RESOLVING " + this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            resolved = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        super.resolveTypeStructure(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        if (isInnerClass()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            ClassDefinition nc = getInnerClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            if (nc instanceof SourceClass && !nc.isLocal()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                ((SourceClass)nc).resolveTypeStructure(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            type = innerClass.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            // Expand all class names in 'type', including those that are not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            // fully-qualified or refer to inner classes, into fully-qualified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            // names.  Local and anonymous classes get synthesized names here,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            // corresponding to the class files that will be generated.  This is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            // currently the only place where 'resolveNames' is used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            type = env.resolveNames(getClassDefinition(), type, isSynthetic());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            // do the throws also:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            getExceptions(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            if (isMethod()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                Vector argNames = args; args = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                createArgumentFields(argNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                // Add outer instance argument for constructors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                if (isConstructor()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                    addOuterThis();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        if (tracing) env.dtExit("SourceMember.resolveTypeStructure: " + this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     * Get the class declaration in which the field is actually defined
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    public ClassDeclaration getDefiningClassDeclaration() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        if (abstractSource == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            return super.getDefiningClassDeclaration();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            return abstractSource.getDefiningClassDeclaration();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     * A source field never reports deprecation, since the compiler
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     * allows access to deprecated features that are being compiled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     * in the same job.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    public boolean reportDeprecated(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     * Check this field.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     * This is the method which requests checking.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     * The real work is done by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     * <tt>Vset check(Environment, Context, Vset)</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
    public void check(Environment env) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        if (tracing) env.dtEnter("SourceMember.check: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
                                 getName() + ", status = " + status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        // rely on the class to check all fields in the proper order
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        if (status == PARSED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            if (isSynthetic() && getValue() == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                // break a big cycle for small synthetic variables
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                status = CHECKED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                if (tracing)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                    env.dtExit("SourceMember.check: BREAKING CYCLE");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
            if (tracing) env.dtEvent("SourceMember.check: CHECKING CLASS");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
            clazz.check(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            if (status == PARSED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                if (getClassDefinition().getError()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                    status = ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                    if (tracing)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                        env.dtExit("SourceMember.check: CHECK FAILED");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                    throw new CompilerError("check failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        if (tracing) env.dtExit("SourceMember.check: DONE " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                                getName() + ", status = " + status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     * Check a field.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
     * @param vset tells which uplevel variables are definitely assigned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     * The vset is also used to track the initialization of blank finals
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
     * by whichever fields which are relevant to them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    public Vset check(Environment env, Context ctx, Vset vset) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        if (tracing) env.dtEvent("SourceMember.check: MEMBER " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                                 getName() + ", status = " + status);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        if (status == PARSED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            if (isInnerClass()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                // some classes are checked separately
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                ClassDefinition nc = getInnerClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                if (nc instanceof SourceClass && !nc.isLocal()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                    && nc.isInsideLocal()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                    status = CHECKING;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                    vset = ((SourceClass)nc).checkInsideClass(env, ctx, vset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                status = CHECKED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                return vset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            if (env.dump()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                System.out.println("[check field " + getClassDeclaration().getName() + "." + getName() + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                if (getValue() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                    getValue().print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                    System.out.println();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            env = new Environment(env, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            // This is where all checking of names appearing within the type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            // of the member is done.  Includes return type and argument types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            // Since only one location ('where') for error messages is provided,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            // localization of errors is poor.  Throws clauses are handled below.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            env.resolve(where, getClassDefinition(), getType());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
            // Make sure that all the classes that we claim to throw really
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            // are subclasses of Throwable, and are classes that we can reach
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
            if (isMethod()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                ClassDeclaration throwable =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                    env.getClassDeclaration(idJavaLangThrowable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                ClassDeclaration exp[] = getExceptions(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                for (int i = 0 ; i < exp.length ; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                    ClassDefinition def;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                    long where = getWhere();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                    if (expIds != null && i < expIds.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                        where = IdentifierToken.getWhere(expIds[i], where);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                        def = exp[i].getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                        // Validate access for all inner-class components
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                        // of a qualified name, not just the last one, which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                        // is checked below.  Yes, this is a dirty hack...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                        // Part of fix for 4094658.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                        env.resolveByName(where, getClassDefinition(), def.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                    } catch (ClassNotFound e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                        env.error(where, "class.not.found", e.name, "throws");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                        break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                    def.noteUsedBy(getClassDefinition(), where, env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                    if (!getClassDefinition().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                          canAccess(env, def.getClassDeclaration())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                        env.error(where, "cant.access.class", def);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                    } else if (!def.subClassOf(env, throwable)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                        env.error(where, "throws.not.throwable", def);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
            status = CHECKING;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            if (isMethod() && args != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                int length = args.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            outer_loop:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                for (int i = 0; i < length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                    LocalMember lf = (LocalMember)(args.elementAt(i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                    Identifier name_i = lf.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                    for (int j = i + 1; j < length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                        LocalMember lf2 = (LocalMember)(args.elementAt(j));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                        Identifier name_j = lf2.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                        if (name_i.equals(name_j)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                            env.error(lf2.getWhere(), "duplicate.argument",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                                      name_i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                            break outer_loop;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            if (getValue() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                ctx = new Context(ctx, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                if (isMethod()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                    Statement s = (Statement)getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                    // initialize vset, indication that each of the arguments
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                    // to the function has a value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                    for (Enumeration e = args.elements(); e.hasMoreElements();){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                        LocalMember f = (LocalMember)e.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                        vset.addVar(ctx.declare(env, f));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
                    if (isConstructor()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                        // Undefine "this" in some constructors, until after
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                        // the super constructor has been called.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                        vset.clearVar(ctx.getThisNumber());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                        // If the first thing in the definition isn't a call
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                        // to either super() or this(), then insert one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
                        Expression supCall = s.firstConstructor();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                        if ((supCall == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                            && (getClassDefinition().getSuperClass() != null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                            supCall = getDefaultSuperCall(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                            Statement scs = new ExpressionStatement(where,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                                                                    supCall);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                            s = Statement.insertStatement(scs, s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                            setValue(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                    //System.out.println("VSET = " + vset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                    ClassDeclaration exp[] = getExceptions(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                    int htsize = (exp.length > 3) ? 17 : 7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                    Hashtable thrown = new Hashtable(htsize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
                    vset = s.checkMethod(env, ctx, vset, thrown);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                    ClassDeclaration ignore1 =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                        env.getClassDeclaration(idJavaLangError);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                    ClassDeclaration ignore2 =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                        env.getClassDeclaration(idJavaLangRuntimeException);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                    for (Enumeration e = thrown.keys(); e.hasMoreElements();) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                        ClassDeclaration c = (ClassDeclaration)e.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                        ClassDefinition def = c.getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                        if (def.subClassOf(env, ignore1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                                 || def.subClassOf(env, ignore2)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                            continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                        boolean ok = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                        if (!isInitializer()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                            for (int i = 0 ; i < exp.length ; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                                if (def.subClassOf(env, exp[i])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                                    ok = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                        if (!ok) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                            Node n = (Node)thrown.get(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
                            long where = n.getWhere();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                            String errorMsg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                            if (isConstructor()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                                if (where ==
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
                                    getClassDefinition().getWhere()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                                    // If this message is being generated for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                                    // a default constructor, we should give
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
                                    // a different error message.  Currently
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                                    // we check for this by seeing if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                                    // constructor has the same "where" as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                                    // its class.  This is a bit kludgy, but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                                    // works. (bug id 4034836)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                                    errorMsg = "def.constructor.exception";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
                                    // Constructor with uncaught exception.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                                    errorMsg = "constructor.exception";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
                            } else if (isInitializer()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                                // Initializer with uncaught exception.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                                errorMsg = "initializer.exception";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                                // Method with uncaught exception.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                                errorMsg = "uncaught.exception";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                            env.error(where, errorMsg, c.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                    Hashtable thrown = new Hashtable(3);  // small & throw-away
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                    Expression val = (Expression)getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
                    vset = val.checkInitializer(env, ctx, vset,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
                                                getType(), thrown);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                    setValue(val.convert(env, ctx, getType(), val));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                    // Complain about static final members of inner classes that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
                    // do not have an initializer that is a constant expression.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                    // In general, static members are not permitted for inner
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
                    // classes, but an exception is made for named constants.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                    // Other cases of static members, including non-final ones,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                    // are handled in 'SourceClass'.  Part of fix for 4095568.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                    if (isStatic() && isFinal() && !clazz.isTopLevel()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                        if (!((Expression)getValue()).isConstant()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                            env.error(where, "static.inner.field", getName(), this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
                            setValue(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                    // Both RuntimeExceptions and Errors should be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                    // allowed in initializers.  Fix for bug 4102541.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                    ClassDeclaration except =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                         env.getClassDeclaration(idJavaLangThrowable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                    ClassDeclaration ignore1 =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                        env.getClassDeclaration(idJavaLangError);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                    ClassDeclaration ignore2 =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                        env.getClassDeclaration(idJavaLangRuntimeException);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
                    for (Enumeration e = thrown.keys(); e.hasMoreElements(); ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
                        ClassDeclaration c = (ClassDeclaration)e.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
                        ClassDefinition def = c.getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
                        if (!def.subClassOf(env, ignore1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                            && !def.subClassOf(env, ignore2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                            && def.subClassOf(env, except)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                            Node n = (Node)thrown.get(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                            env.error(n.getWhere(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                                      "initializer.exception", c.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                if (env.dump()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                    getValue().print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                    System.out.println();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
            status = getClassDefinition().getError() ? ERROR : CHECKED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
        // Initializers (static and instance) must be able to complete normally.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        if (isInitializer() && vset.isDeadEnd()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
            env.error(where, "init.no.normal.completion");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            vset = vset.clearDeadEnd();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
        return vset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
    // helper to check(): synthesize a missing super() call
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
    private Expression getDefaultSuperCall(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        Expression se = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        ClassDefinition sclass = getClassDefinition().getSuperClass().getClassDefinition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        // does the superclass constructor require an enclosing instance?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        ClassDefinition reqc = (sclass == null) ? null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                             : sclass.isTopLevel() ? null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                             : sclass.getOuterClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        ClassDefinition thisc = getClassDefinition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
        if (reqc != null && !Context.outerLinkExists(env, reqc, thisc)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
            se = new SuperExpression(where, new NullExpression(where));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
            env.error(where, "no.default.outer.arg", reqc, getClassDefinition());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        if (se == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            se = new SuperExpression(where);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        return new MethodExpression(where, se, idInit, new Expression[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * Inline the field
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    void inline(Environment env) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        switch (status) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
          case PARSED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            check(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
            inline(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
          case CHECKED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
            if (env.dump()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
                System.out.println("[inline field " + getClassDeclaration().getName() + "." + getName() + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            status = INLINING;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
            env = new Environment(env, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            if (isMethod()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
                if ((!isNative()) && (!isAbstract())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                    Statement s = (Statement)getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                    Context ctx = new Context((Context)null, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                    for (Enumeration e = args.elements() ; e.hasMoreElements() ;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                        LocalMember local = (LocalMember)e.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                        ctx.declare(env, local);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                    setValue(s.inline(env, ctx));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
            } else if (isInnerClass()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                // some classes are checked and inlined separately
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                ClassDefinition nc = getInnerClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                if (nc instanceof SourceClass && !nc.isLocal()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                    && nc.isInsideLocal()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                    status = INLINING;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                    ((SourceClass)nc).inlineLocalClass(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                status = INLINED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
                if (getValue() != null)  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
                    Context ctx = new Context((Context)null, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
                    if (!isStatic()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
                        // Cf. "thisArg" in SourceClass.checkMembers().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
                        Context ctxInst = new Context(ctx, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
                        LocalMember thisArg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
                                    ((SourceClass)clazz).getThisArgument();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
                        ctxInst.declare(env, thisArg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                        setValue(((Expression)getValue())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
                                    .inlineValue(env, ctxInst));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                        setValue(((Expression)getValue())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                                    .inlineValue(env, ctx));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            if (env.dump()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                System.out.println("[inlined field " + getClassDeclaration().getName() + "." + getName() + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                if (getValue() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                    getValue().print(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
                    System.out.println();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                    System.out.println("<empty>");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
            status = INLINED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
     * Get the value of the field (or null if the value can't be determined)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
    public Node getValue(Environment env) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        Node value = getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        if (value != null && status != INLINED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
            // be sure to get the imports right:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            env = ((SourceClass)clazz).setupEnv(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            inline(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            value = (status == INLINED) ? getValue() : null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        return value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    public boolean isInlineable(Environment env, boolean fromFinal) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        if (super.isInlineable(env, fromFinal)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            getValue(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
            return (status == INLINED) && !getClassDefinition().getError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
     * Get the initial value of the field
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    public Object getInitialValue() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
        if (isMethod() || (getValue() == null) || (!isFinal()) || (status != INLINED)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
        return ((Expression)getValue()).getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     * Generate code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
    public void code(Environment env, Assembler asm) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        switch (status) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
          case PARSED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
            check(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
            code(env, asm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
          case CHECKED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
            inline(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            code(env, asm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
          case INLINED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
            // Actually generate code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            if (env.dump()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                System.out.println("[code field " + getClassDeclaration().getName() + "." + getName() + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            if (isMethod() && (!isNative()) && (!isAbstract())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                env = new Environment(env, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                Context ctx = new Context((Context)null, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                Statement s = (Statement)getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                for (Enumeration e = args.elements() ; e.hasMoreElements() ; ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
                    LocalMember f = (LocalMember)e.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                    ctx.declare(env, f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
                    //ctx.declare(env, (LocalMember)e.nextElement());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
                /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
                if (isConstructor() && ((s == null) || (s.firstConstructor() == null))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                    ClassDeclaration c = getClassDefinition().getSuperClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                    if (c != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                        MemberDefinition field = c.getClassDefinition(env).matchMethod(env, getClassDefinition(), idInit);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
                        asm.add(getWhere(), opc_aload, new Integer(0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
                        asm.add(getWhere(), opc_invokespecial, field);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
                        asm.add(getWhere(), opc_pop);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
                    // Output initialization code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
                    for (MemberDefinition f = getClassDefinition().getFirstMember() ; f != null ; f = f.getNextMember()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
                        if (!f.isStatic()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
                            f.codeInit(env, ctx, asm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
                if (s != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                    s.code(env, ctx, asm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                if (getType().getReturnType().isType(TC_VOID) && !isInitializer()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                   asm.add(getWhere(), opc_return, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
    public void codeInit(Environment env, Context ctx, Assembler asm) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
        if (isMethod()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        switch (status) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
          case PARSED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
            check(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
            codeInit(env, ctx, asm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
          case CHECKED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            inline(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
            codeInit(env, ctx, asm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
          case INLINED:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            // Actually generate code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
            if (env.dump()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                System.out.println("[code initializer  " + getClassDeclaration().getName() + "." + getName() + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
            if (getValue() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                Expression e = (Expression)getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
                // The JLS Section 8.5 specifies that static (non-final)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
                // initializers should be executed in textual order.  Eliding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
                // initializations to default values can interfere with this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                // so the tests for !e.equalsDefault() have been eliminated,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                // below.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                if (isStatic()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
                    if (getInitialValue() == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
                        // removed: && !e.equalsDefault()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                        e.codeValue(env, ctx, asm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                        asm.add(getWhere(), opc_putstatic, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
                } else { // removed: if (!e.equalsDefault()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
                    // This code doesn't appear to be reached for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
                    // instance initializers.  Code for these is generated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                    // in the makeVarInits() method of the class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                    // MethodExpression.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                    asm.add(getWhere(), opc_aload, new Integer(0));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
                    e.codeValue(env, ctx, asm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
                    asm.add(getWhere(), opc_putfield, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
     * Print for debugging
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    public void print(PrintStream out) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
        super.print(out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
        if (getValue() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
            getValue().print(out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
            out.println();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
}