jdk/src/share/classes/sun/tools/java/ClassDefinition.java
author ntoda
Thu, 31 Jul 2014 17:01:24 -0700
changeset 25799 1afc4675dc75
parent 5506 202f599c92aa
permissions -rw-r--r--
8044867: Fix raw and unchecked lint warnings in sun.tools.* Reviewed-by: darcy
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
2
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
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
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
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
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.java;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.OutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.PrintStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import sun.tools.tree.Context;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import sun.tools.tree.Vset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import sun.tools.tree.Expression;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import sun.tools.tree.LocalMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import sun.tools.tree.UplevelReference;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * This class is a Java class definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * WARNING: The contents of this source file are not part of any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * supported API.  Code that depends on them does so at its own risk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * they are subject to change or removal without notice.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
public
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
class ClassDefinition implements Constants {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
    protected Object source;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
    protected long where;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
    protected int modifiers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
    protected Identifier localName; // for local classes
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    protected ClassDeclaration declaration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    protected IdentifierToken superClassId;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    protected IdentifierToken interfaceIds[];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    protected ClassDeclaration superClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    protected ClassDeclaration interfaces[];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    protected ClassDefinition outerClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    protected MemberDefinition outerMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    protected MemberDefinition innerClassMember;        // field for me in outerClass
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    protected MemberDefinition firstMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    protected MemberDefinition lastMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    protected boolean resolved;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    protected String documentation;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    protected boolean error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    protected boolean nestError;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    protected UplevelReference references;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    protected boolean referencesFrozen;
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
    67
    private Hashtable<Identifier, MemberDefinition> fieldHash = new Hashtable<>(31);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    private int abstr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    // Table of local and anonymous classes whose internal names are constructed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    // using the current class as a prefix.  This is part of a fix for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    // bugid 4054523 and 4030421.  See also 'Environment.getClassDefinition'
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    // and 'BatchEnvironment.makeClassDefinition'.  Allocated on demand.
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
    74
    private Hashtable<String, ClassDefinition> localClasses = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    private final int LOCAL_CLASSES_SIZE = 31;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    // The immediately surrounding context in which the class appears.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    // Set at the beginning of checking, upon entry to 'SourceClass.checkInternal'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    // Null for classes that are not local or inside a local class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    // At present, this field exists only for the benefit of 'resolveName' as part
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    // of the fix for 4095716.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    protected Context classContext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    // The saved class context is now also used in 'SourceClass.getAccessMember'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    // Provide read-only access via this method.  Part of fix for 4098093.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    public Context getClassContext() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
        return classContext;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     * Constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    protected ClassDefinition(Object source, long where, ClassDeclaration declaration,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
                              int modifiers, IdentifierToken superClass, IdentifierToken interfaces[]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
        this.source = source;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        this.where = where;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        this.declaration = declaration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
        this.modifiers = modifiers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        this.superClassId = superClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
        this.interfaceIds = interfaces;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     * Get the source of the class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    public final Object getSource() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        return source;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
     * Check if there were any errors in this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    public final boolean getError() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        return error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * Mark this class to be erroneous.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    public final void setError() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        this.error = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        setNestError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     * Check if there were any errors in our class nest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    public final boolean getNestError() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        // Check to see if our error value is set, or if any of our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        // outer classes' error values are set.  This will work in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        // conjunction with setError(), which sets the error value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        // of its outer class, to yield true is any of our nest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        // siblings has an error.  This addresses bug 4111488: either
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        // code should be generated for all classes in a nest, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        // none of them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        return nestError || ((outerClass != null) ? outerClass.getNestError() : false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * Mark this class, and all siblings in its class nest, to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * erroneous.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    public final void setNestError() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        this.nestError = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        if (outerClass != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
            // If we have an outer class, set it to be erroneous as well.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            // This will work in conjunction with getError(), which checks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            // the error value of its outer class, to set the whole class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            // nest to be erroneous.  This address bug 4111488: either
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            // code should be generated for all classes in a nest, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            // none of them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            outerClass.setNestError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * Get the position in the input
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    public final long getWhere() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        return where;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * Get the class declaration
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    public final ClassDeclaration getClassDeclaration() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        return declaration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * Get the class' modifiers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    public final int getModifiers() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        return modifiers;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    public final void subModifiers(int mod) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        modifiers &= ~mod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    public final void addModifiers(int mod) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        modifiers |= mod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    // *** DEBUG ***
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    protected boolean supersCheckStarted = !(this instanceof sun.tools.javac.SourceClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     * Get the class' super class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    public final ClassDeclaration getSuperClass() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        /*---
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        if (superClass == null && superClassId != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            throw new CompilerError("getSuperClass "+superClassId);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        // There are obscure cases where null is the right answer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        // in order to enable some error reporting later on.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        // For example:  class T extends T.N { class N { } }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        ---*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        // *** DEBUG ***
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        // This method should not be called if the superclass has not been resolved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        if (!supersCheckStarted) throw new CompilerError("unresolved super");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        return superClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * Get the super class, and resolve names now if necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     * It is only possible to resolve names at this point if we are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     * a source class.  The provision of this method at this level
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
     * in the class hierarchy is dubious, but see 'getInnerClass' below.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     * All other calls to 'getSuperClass(env)' appear in 'SourceClass'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     * NOTE: An older definition of this method has been moved to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     * 'SourceClass', where it overrides this one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * @see #resolveTypeStructure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    public ClassDeclaration getSuperClass(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        return getSuperClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     * Get the class' interfaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    public final ClassDeclaration getInterfaces()[] {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        if (interfaces == null)  throw new CompilerError("getInterfaces");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        return interfaces;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     * Get the class' enclosing class (or null if not inner)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    public final ClassDefinition getOuterClass() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        return outerClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * Set the class' enclosing class.  Must be done at most once.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    protected final void setOuterClass(ClassDefinition outerClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        if (this.outerClass != null)  throw new CompilerError("setOuterClass");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        this.outerClass = outerClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * Set the class' enclosing current instance pointer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     * Must be done at most once.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    protected final void setOuterMember(MemberDefinition outerMember) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        if (isStatic() || !isInnerClass())  throw new CompilerError("setOuterField");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        if (this.outerMember != null)  throw new CompilerError("setOuterField");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        this.outerMember = outerMember;
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
     * Tell if the class is inner.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * This predicate also returns true for top-level nested types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * To test for a true inner class as seen by the programmer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     * use <tt>!isTopLevel()</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    public final boolean isInnerClass() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        return outerClass != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     * Tell if the class is a member of another class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     * This is false for package members and for block-local classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    public final boolean isMember() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        return outerClass != null && !isLocal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * Tell if the class is "top-level", which is either a package member,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     * or a static member of another top-level class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    public final boolean isTopLevel() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        return outerClass == null || isStatic() || isInterface();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
     * Tell if the class is local or inside a local class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
     * which means it cannot be mentioned outside of its file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    // The comment above is true only because M_LOCAL is set
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    // whenever M_ANONYMOUS is.  I think it is risky to assume that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    // isAnonymous(x) => isLocal(x).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
    public final boolean isInsideLocal() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        return isLocal() ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            (outerClass != null && outerClass.isInsideLocal());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     * Tell if the class is local or or anonymous class, or inside
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     * such a class, which means it cannot be mentioned outside of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * its file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    public final boolean isInsideLocalOrAnonymous() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        return isLocal() || isAnonymous () ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            (outerClass != null && outerClass.isInsideLocalOrAnonymous());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     * Return a simple identifier for this class (idNull if anonymous).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    public Identifier getLocalName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        if (localName != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            return localName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        // This is also the name of the innerClassMember, if any:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        return getName().getFlatName().getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     * Set the local name of a class.  Must be a local class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    public void setLocalName(Identifier name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        if (isLocal()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            localName = name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * If inner, get the field for this class in the enclosing class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    public final MemberDefinition getInnerClassMember() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        if (outerClass == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        if (innerClassMember == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
            // We must find the field in the outer class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            Identifier nm = getName().getFlatName().getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
            for (MemberDefinition field = outerClass.getFirstMatch(nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                 field != null; field = field.getNextMatch()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                if (field.isInnerClass()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                    innerClassMember = field;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            if (innerClassMember == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                throw new CompilerError("getInnerClassField");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        return innerClassMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     * If inner, return an innermost uplevel self pointer, if any exists.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * Otherwise, return null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    public final MemberDefinition findOuterMember() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        return outerMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     * See if this is a (nested) static class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    public final boolean isStatic() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        return (modifiers & ACC_STATIC) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * Get the class' top-level enclosing class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    public final ClassDefinition getTopClass() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        ClassDefinition p, q;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        for (p = this; (q = p.outerClass) != null; p = q)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
            ;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        return p;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     * Get the class' first field or first match
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    public final MemberDefinition getFirstMember() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        return firstMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
    public final MemberDefinition getFirstMatch(Identifier name) {
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
   381
        return fieldHash.get(name);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     * Get the class' name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    public final Identifier getName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        return declaration.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     * Get the class' type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    public final Type getType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        return declaration.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * Get the class' documentation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    public String getDocumentation() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        return documentation;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     * Return true if the given documentation string contains a deprecation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     * paragraph.  This is true if the string contains the tag @deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     * is the first word in a line.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    public static boolean containsDeprecated(String documentation) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        if (documentation == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
    doScan:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        for (int scan = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
             (scan = documentation.indexOf(paraDeprecated, scan)) >= 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
             scan += paraDeprecated.length()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            // make sure there is only whitespace between this word
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            // and the beginning of the line
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
            for (int beg = scan-1; beg >= 0; beg--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                char ch = documentation.charAt(beg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                if (ch == '\n' || ch == '\r') {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                    break;      // OK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
                if (!Character.isSpace(ch)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
                    continue doScan;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            // make sure the char after the word is space or end of line
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            int end = scan+paraDeprecated.length();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
            if (end < documentation.length()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                char ch = documentation.charAt(end);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
                if (!(ch == '\n' || ch == '\r') && !Character.isSpace(ch)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                    continue doScan;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
    public final boolean inSamePackage(ClassDeclaration c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        // find out if the class stored in c is defined in the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        // package as the current class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        return inSamePackage(c.getName().getQualifier());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    public final boolean inSamePackage(ClassDefinition c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        // find out if the class stored in c is defined in the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        // package as the current class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        return inSamePackage(c.getName().getQualifier());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    public final boolean inSamePackage(Identifier packageName) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        return (getName().getQualifier().equals(packageName));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
     * Checks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
    public final boolean isInterface() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        return (getModifiers() & M_INTERFACE) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
    public final boolean isClass() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        return (getModifiers() & M_INTERFACE) == 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    public final boolean isPublic() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        return (getModifiers() & M_PUBLIC) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
    public final boolean isPrivate() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        return (getModifiers() & M_PRIVATE) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
    public final boolean isProtected() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        return (getModifiers() & M_PROTECTED) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    public final boolean isPackagePrivate() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        return (modifiers & (M_PUBLIC | M_PRIVATE | M_PROTECTED)) == 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
    public final boolean isFinal() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        return (getModifiers() & M_FINAL) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
    public final boolean isAbstract() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        return (getModifiers() & M_ABSTRACT) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    public final boolean isSynthetic() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        return (getModifiers() & M_SYNTHETIC) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    public final boolean isDeprecated() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        return (getModifiers() & M_DEPRECATED) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    public final boolean isAnonymous() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        return (getModifiers() & M_ANONYMOUS) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
    public final boolean isLocal() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        return (getModifiers() & M_LOCAL) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
    public final boolean hasConstructor() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        return getFirstMatch(idInit) != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
     * Check to see if a class must be abstract.  This method replaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
     * isAbstract(env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
    public final boolean mustBeAbstract(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        // If it is declared abstract, return true.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        // (Fix for 4110534.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        if (isAbstract()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        // Check to see if the class should have been declared to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        // abstract.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
        // We make sure that the inherited method collection has been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        // performed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        collectInheritedMethods(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        // We check for any abstract methods inherited or declared
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        // by this class.
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
   522
        Iterator<MemberDefinition> methods = getMethods();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        while (methods.hasNext()) {
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
   524
            MemberDefinition method = methods.next();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            if (method.isAbstract()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        // We check for hidden "permanently abstract" methods in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        // our superclasses.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        return getPermanentlyAbstractMethods().hasNext();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
     * Check if this is a super class of another class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
    public boolean superClassOf(Environment env, ClassDeclaration otherClass)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                                                                throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
        while (otherClass != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            if (getClassDeclaration().equals(otherClass)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            otherClass = otherClass.getClassDefinition(env).getSuperClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
     * Check if this is an enclosing class of another class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    public boolean enclosingClassOf(ClassDefinition otherClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
        while ((otherClass = otherClass.getOuterClass()) != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
            if (this == otherClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     * Check if this is a sub class of another class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    public boolean subClassOf(Environment env, ClassDeclaration otherClass) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
        ClassDeclaration c = getClassDeclaration();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        while (c != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
            if (c.equals(otherClass)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
            c = c.getClassDefinition(env).getSuperClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        return false;
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
     * Check if this class is implemented by another class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    public boolean implementedBy(Environment env, ClassDeclaration c) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        for (; c != null ; c = c.getClassDefinition(env).getSuperClass()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            if (getClassDeclaration().equals(c)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            ClassDeclaration intf[] = c.getClassDefinition(env).getInterfaces();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            for (int i = 0 ; i < intf.length ; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                if (implementedBy(env, intf[i])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                    return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
     * Check to see if a class which implements interface `this' could
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
     * possibly implement the interface `intDef'.  Note that the only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
     * way that this can fail is if `this' and `intDef' have methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
     * which are of the same signature and different return types.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
     * method is used by Environment.explicitCast() to determine if a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     * cast between two interfaces is legal.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
     * This method should only be called on a class after it has been
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
     * basicCheck()'ed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    public boolean couldImplement(ClassDefinition intDef) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        // Check to see if we could have done the necessary checks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        if (!doInheritanceChecks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
            throw new CompilerError("couldImplement: no checks");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        // This method should only be called for interfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        if (!isInterface() || !intDef.isInterface()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
            throw new CompilerError("couldImplement: not interface");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        // Make sure we are not called before we have collected our
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
        // inheritance information.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        if (allMethods == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
            throw new CompilerError("couldImplement: called early");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        // Get the other classes' methods.  getMethods() in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        // general can return methods which are not visible to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        // current package.  We need to make sure that these do not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        // prevent this class from being implemented.
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
   626
        Iterator<MemberDefinition> otherMethods = intDef.getMethods();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
        while (otherMethods.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
            // Get one of the methods from intDef...
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
   630
            MemberDefinition method = otherMethods.next();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            Identifier name = method.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
            Type type = method.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            // See if we implement a method of the same signature...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
            MemberDefinition myMethod = allMethods.lookupSig(name, type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
            //System.out.println("Comparing\n\t" + myMethod +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            //                   "\nand\n\t" + method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            if (myMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                // We do.  Make sure the methods have the same return type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
                if (!myMethod.sameReturnType(method)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     * Check if another class can be accessed from the 'extends' or 'implements'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     * clause of this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    public boolean extendsCanAccess(Environment env, ClassDeclaration c) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        // Names in the 'extends' or 'implements' clause of an inner class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        // are checked as if they appeared in the body of the surrounding class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        if (outerClass != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            return outerClass.canAccess(env, c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        // We are a package member.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        ClassDefinition cdef = c.getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
        if (cdef.isLocal()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            // No locals should be in scope in the 'extends' or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
            // 'implements' clause of a package member.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
            throw new CompilerError("top local");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        if (cdef.isInnerClass()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            MemberDefinition f = cdef.getInnerClassMember();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            // Access to public member is always allowed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            if (f.isPublic()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
                return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
            // Private access is ok only from the same class nest.  This can
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
            // happen only if the class represented by 'this' encloses the inner
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            // class represented by 'f'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            if (f.isPrivate()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
                return getClassDeclaration().equals(f.getTopClass().getClassDeclaration());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
            // Protected or default access -- allow access if in same package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            return getName().getQualifier().equals(f.getClassDeclaration().getName().getQualifier());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        // Access to public member is always allowed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
        if (cdef.isPublic()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        // Default access -- allow access if in same package.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        return getName().getQualifier().equals(c.getName().getQualifier());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
     * Check if another class can be accessed from within the body of this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
    public boolean canAccess(Environment env, ClassDeclaration c) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
        ClassDefinition cdef = c.getClassDefinition(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
        if (cdef.isLocal()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
            // if it's in scope, it's accessible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        if (cdef.isInnerClass()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
            return canAccess(env, cdef.getInnerClassMember());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        // Public access is always ok
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        if (cdef.isPublic()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        // It must be in the same package
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        return getName().getQualifier().equals(c.getName().getQualifier());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
     * Check if a field can be accessed from a class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
    public boolean canAccess(Environment env, MemberDefinition f)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
                throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
        // Public access is always ok
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
        if (f.isPublic()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        // Protected access is ok from a subclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        if (f.isProtected() && subClassOf(env, f.getClassDeclaration())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        // Private access is ok only from the same class nest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        if (f.isPrivate()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            return getTopClass().getClassDeclaration()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                .equals(f.getTopClass().getClassDeclaration());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        // It must be in the same package
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        return getName().getQualifier().equals(f.getClassDeclaration().getName().getQualifier());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
     * Check if a class is entitled to inline access to a class from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
     * another class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
    public boolean permitInlinedAccess(Environment env, ClassDeclaration c)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                       throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        return (env.opt() && c.equals(declaration)) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
               (env.opt_interclass() && canAccess(env, c));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
     * Check if a class is entitled to inline access to a method from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
     * another class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
    public boolean permitInlinedAccess(Environment env, MemberDefinition f)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
                       throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        return (env.opt()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
                    && (f.clazz.getClassDeclaration().equals(declaration))) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
               (env.opt_interclass() && canAccess(env, f));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
     * We know the the field is marked protected (and not public) and that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
     * the field is visible (as per canAccess).  Can we access the field as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
     * <accessor>.<field>, where <accessor> has the type <accessorType>?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
     * Protected fields can only be accessed when the accessorType is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
     * subclass of the current class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    public boolean protectedAccess(Environment env, MemberDefinition f,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                                   Type accessorType)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
        throws ClassNotFound
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
        return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
               // static protected fields are accessible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
               f.isStatic()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
            || // allow array.clone()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
               (accessorType.isType(TC_ARRAY) && (f.getName() == idClone)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                 && (f.getType().getArgumentTypes().length == 0))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
            || // <accessorType> is a subtype of the current class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
               (accessorType.isType(TC_CLASS)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                 && env.getClassDefinition(accessorType.getClassName())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
                         .subClassOf(env, getClassDeclaration()))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
            || // we are accessing the field from a friendly class (same package)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
               (getName().getQualifier()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
                   .equals(f.getClassDeclaration().getName().getQualifier()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
     * Find or create an access method for a private member,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
     * or return null if this is not possible.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
    public MemberDefinition getAccessMember(Environment env, Context ctx,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                                          MemberDefinition field, boolean isSuper) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
        throw new CompilerError("binary getAccessMember");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
     * Find or create an update method for a private member,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
     * or return null if this is not possible.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
    public MemberDefinition getUpdateMember(Environment env, Context ctx,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
                                            MemberDefinition field, boolean isSuper) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        throw new CompilerError("binary getUpdateMember");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
     * Get a field from this class.  Report ambiguous fields.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
     * If no accessible field is found, this method may return an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
     * inaccessible field to allow a useful error message.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
     * getVariable now takes the source class `source' as an argument.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
     * This allows getVariable to check whether a field is inaccessible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
     * before it signals that a field is ambiguous.  The compiler used to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
     * signal an ambiguity even when one of the fields involved was not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
     * accessible.  (bug 4053724)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
    public MemberDefinition getVariable(Environment env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
                                        Identifier nm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
                                        ClassDefinition source)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
        throws AmbiguousMember, ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        return getVariable0(env, nm, source, true, true);
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
     * private fields are never inherited.  package-private fields are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
     * not inherited across package boundaries.  To capture this, we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
     * take two booleans as parameters: showPrivate indicates whether
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
     * we have passed a class boundary, and showPackage indicates whether
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
     * we have crossed a package boundary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
    private MemberDefinition getVariable0(Environment env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                                          Identifier nm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                                          ClassDefinition source,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
                                          boolean showPrivate,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
                                          boolean showPackage)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
        throws AmbiguousMember, ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        // Check to see if this field is defined in the current class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
        for (MemberDefinition member = getFirstMatch(nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
             member != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
             member = member.getNextMatch()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
            if (member.isVariable()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
                if ((showPrivate || !member.isPrivate()) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                    (showPackage || !member.isPackagePrivate())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                    // It is defined in this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                    return member;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                    // Even though this definition is not inherited,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    // it hides all definitions in supertypes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                    return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
        // Find the field in our superclass.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        ClassDeclaration sup = getSuperClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
        MemberDefinition field = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
        if (sup != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
            field =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
                sup.getClassDefinition(env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                  .getVariable0(env, nm, source,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                                false,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                                showPackage && inSamePackage(sup));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
        // Find the field in our superinterfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
        for (int i = 0 ; i < interfaces.length ; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
            // Try to look up the field in an interface.  Since interfaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
            // only have public fields, the values of the two boolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
            // arguments are not important.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
            MemberDefinition field2 =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                interfaces[i].getClassDefinition(env)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                  .getVariable0(env, nm, source, true, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
            if (field2 != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
                // If we have two different, accessible fields, then
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
                // we've found an ambiguity.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
                if (field != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
                    source.canAccess(env, field) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
                    field2 != field) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
                    throw new AmbiguousMember(field2, field);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
                field = field2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
        return field;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
     * Tells whether to report a deprecation error for this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
    public boolean reportDeprecated(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
        return (isDeprecated()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
                || (outerClass != null && outerClass.reportDeprecated(env)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
     * Note that this class is being used somehow by <tt>ref</tt>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
     * Report deprecation errors, etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
    public void noteUsedBy(ClassDefinition ref, long where, Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
        // (Have this deal with canAccess() checks, too?)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
        if (reportDeprecated(env)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
            env.error(where, "warn.class.is.deprecated", this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
   /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
     * Get an inner class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
     * Look in supers but not outers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
     * (This is used directly to resolve expressions like "site.K", and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
     * inside a loop to resolve lone names like "K" or the "K" in "K.L".)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
     * Called from 'Context' and 'FieldExpression' as well as this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
     * @see FieldExpression.checkCommon
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
     * @see resolveName
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
    public MemberDefinition getInnerClass(Environment env, Identifier nm)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
                                                        throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
        // Note:  AmbiguousClass will not be thrown unless and until
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        // inner classes can be defined inside interfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
        // Check if it is defined in the current class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
        for (MemberDefinition field = getFirstMatch(nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
                field != null ; field = field.getNextMatch()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
            if (field.isInnerClass()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
                if (field.getInnerClass().isLocal()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
                    continue;   // ignore this name; it is internally generated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
                return field;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
        // Get it from the super class
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
        // It is likely that 'getSuperClass()' could be made to work here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
        // but we would have to assure somehow that 'resolveTypeStructure'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
        // has been called on the current class nest.  Since we can get
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
        // here from 'resolveName', which is called from 'resolveSupers',
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        // it is possible that the first attempt to resolve the superclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
        // will originate here, instead of in the call to 'getSuperClass'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
        // in 'checkSupers'.  See 'resolveTypeStructure', in which a call
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
        // to 'resolveSupers' precedes the call to 'checkSupers'.  Why is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
        // name resolution done twice, first in 'resolveName'?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
        // NOTE: 'SourceMember.resolveTypeStructure' may initiate type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
        // structure resolution for an inner class.  Normally, this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
        // occurs during the resolution of the outer class, but fields
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
        // added after the resolution of their containing class will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
        // be resolved late -- see 'addMember(env,field)' below.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
        // This should only happen for synthetic members, which should
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
        // never be an inner class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
        ClassDeclaration sup = getSuperClass(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        if (sup != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
            return sup.getClassDefinition(env).getInnerClass(env, nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
     * Lookup a method.  This code implements the method lookup
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
     * mechanism specified in JLS 15.11.2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
     * This mechanism cannot be used to lookup synthetic methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
    private MemberDefinition matchMethod(Environment env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
                                         ClassDefinition accessor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
                                         Identifier methodName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
                                         Type[] argumentTypes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
                                         boolean isAnonConstCall,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
                                         Identifier accessPackage)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
        throws AmbiguousMember, ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
        if (allMethods == null || !allMethods.isFrozen()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
            // This may be too restrictive.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
            throw new CompilerError("matchMethod called early");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
            // collectInheritedMethods(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
        // A tentative maximally specific method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
        MemberDefinition tentative = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
        // A list of other methods which may be maximally specific too.
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
   998
        List<MemberDefinition> candidateList = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
        // Get all the methods inherited by this class which
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
        // have the name `methodName'.
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1002
        Iterator<MemberDefinition> methods = allMethods.lookupName(methodName);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
        while (methods.hasNext()) {
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1005
            MemberDefinition method = methods.next();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
            // See if this method is applicable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
            if (!env.isApplicable(method, argumentTypes)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
            // See if this method is accessible.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
            if (accessor != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
                if (!accessor.canAccess(env, method)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
            } else if (isAnonConstCall) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
                if (method.isPrivate() ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
                    (method.isPackagePrivate() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
                     accessPackage != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
                     !inSamePackage(accessPackage))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
                    // For anonymous constructor accesses, we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
                    // haven't yet built an accessing class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
                    // We disallow anonymous classes from seeing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
                    // private/package-private inaccessible
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
                    // constructors in their superclass.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
                // If accessor is null, we assume that the access
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
                // is allowed.  Query: is this option used?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
            if (tentative == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
                // `method' becomes our tentative maximally specific match.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
                tentative = method;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
                if (env.isMoreSpecific(method, tentative)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
                    // We have found a method which is a strictly better
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
                    // match than `tentative'.  Replace it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
                    tentative = method;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
                    // If this method could possibly be another
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
                    // maximally specific method, add it to our
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
                    // list of other candidates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
                    if (!env.isMoreSpecific(tentative,method)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
                        if (candidateList == null) {
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1048
                            candidateList = new ArrayList<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
                        candidateList.add(method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
        if (tentative != null && candidateList != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
            // Find out if our `tentative' match is a uniquely
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
            // maximally specific.
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1059
            Iterator<MemberDefinition> candidates = candidateList.iterator();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
            while (candidates.hasNext()) {
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1061
                MemberDefinition method = candidates.next();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
                if (!env.isMoreSpecific(tentative, method)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
                    throw new AmbiguousMember(tentative, method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
        return tentative;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
     * Lookup a method.  This code implements the method lookup
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
     * mechanism specified in JLS 15.11.2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
     * This mechanism cannot be used to lookup synthetic methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
    public MemberDefinition matchMethod(Environment env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
                                        ClassDefinition accessor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
                                        Identifier methodName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
                                        Type[] argumentTypes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
        throws AmbiguousMember, ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
        return matchMethod(env, accessor, methodName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
                           argumentTypes, false, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
     * Lookup a method.  This code implements the method lookup
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
     * mechanism specified in JLS 15.11.2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
     * This mechanism cannot be used to lookup synthetic methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
    public MemberDefinition matchMethod(Environment env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
                                        ClassDefinition accessor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
                                        Identifier methodName)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
        throws AmbiguousMember, ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
        return matchMethod(env, accessor, methodName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
                           Type.noArgs, false, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
     * A version of matchMethod to be used only for constructors
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
     * when we cannot pass in a sourceClass argument.  We just assert
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
     * our package name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
     * This is used only for anonymous classes, where we have to look up
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
     * a (potentially) protected constructor with no valid sourceClass
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
     * parameter available.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
    public MemberDefinition matchAnonConstructor(Environment env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
                                                 Identifier accessPackage,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
                                                 Type argumentTypes[])
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
        throws AmbiguousMember, ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
        return matchMethod(env, null, idInit, argumentTypes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
                           true, accessPackage);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
     * Find a method, ie: exact match in this class or any of the super
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
     * classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
     * Only called by javadoc.  For now I am holding off rewriting this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
     * code to rely on collectInheritedMethods(), as that code has
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
     * not gotten along with javadoc in the past.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
    public MemberDefinition findMethod(Environment env, Identifier nm, Type t)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
    throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
        // look in the current class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
        MemberDefinition f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
        for (f = getFirstMatch(nm) ; f != null ; f = f.getNextMatch()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
            // Note that non-method types return false for equalArguments().
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
            if (f.getType().equalArguments(t)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
                return f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
        // constructors are not inherited
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
        if (nm.equals(idInit)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
        // look in the super class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
        ClassDeclaration sup = getSuperClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
        if (sup == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
        return sup.getClassDefinition(env).findMethod(env, nm, t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
    // We create a stub for this.  Source classes do more work.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
    protected void basicCheck(Environment env) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
        // Do the outer class first.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
        if (outerClass != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
            outerClass.basicCheck(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
     * Check this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
    public void check(Environment env) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
    public Vset checkLocalClass(Environment env, Context ctx,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
                                Vset vset, ClassDefinition sup,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
                                Expression args[], Type argTypes[]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
                                ) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
        throw new CompilerError("checkLocalClass");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
    //---------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
    // The non-synthetic methods defined in this class or in any
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
    // of its parents (class or interface).  This member is used
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
    // to cache work done in collectInheritedMethods for use by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
    // getMethods() and matchMethod().  It should be accessed by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
    // no other method without forethought.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
    MethodSet allMethods = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
    // One of our superclasses may contain an abstract method which
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
    // we are unable to ever implement.  This happens when there is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
    // a package-private abstract method in our parent and we are in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
    // a different package than our parent.  In these cases, we
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
    // keep a list of the "permanently abstract" or "unimplementable"
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
    // methods so that we can correctly detect that this class is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
    // indeed abstract and so that we can give somewhat comprehensible
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
    // error messages.
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1188
    private List<MemberDefinition> permanentlyAbstractMethods = new ArrayList<>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
     * This method returns an Iterator of all abstract methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
     * in our superclasses which we are unable to implement.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
     */
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1194
    protected Iterator<MemberDefinition> getPermanentlyAbstractMethods() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
        // This method can only be called after collectInheritedMethods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
        if (allMethods == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
            throw new CompilerError("isPermanentlyAbstract() called early");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
        return permanentlyAbstractMethods.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
     * A flag used by turnOffInheritanceChecks() to indicate if
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
     * inheritance checks are on or off.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
    protected static boolean doInheritanceChecks = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
     * This is a workaround to allow javadoc to turn off certain
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
     * inheritance/override checks which interfere with javadoc
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
     * badly.  In the future it might be good to eliminate the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
     * shared sources of javadoc and javac to avoid the need for this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
     * sort of workaround.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
    public static void turnOffInheritanceChecks() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
        doInheritanceChecks = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
     * Add all of the methods declared in or above `parent' to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
     * `allMethods', the set of methods in the current class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
     * `myMethods' is the set of all methods declared in this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
     * class, and `mirandaMethods' is a repository for Miranda methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
     * If mirandaMethods is null, no mirandaMethods will be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
     * generated.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
     * For a definition of Miranda methods, see the comment above the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
     * method addMirandaMethods() which occurs later in this file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
    private void collectOneClass(Environment env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
                                 ClassDeclaration parent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
                                 MethodSet myMethods,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
                                 MethodSet allMethods,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
                                 MethodSet mirandaMethods) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
        // System.out.println("Inheriting methods from " + parent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
            ClassDefinition pClass = parent.getClassDefinition(env);
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1241
            Iterator<MemberDefinition> methods = pClass.getMethods(env);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
            while (methods.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
                MemberDefinition method =
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1244
                    methods.next();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
                // Private methods are not inherited.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
                //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
                // Constructors are not inherited.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
                //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
                // Any non-abstract methods in an interface come
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
                // from java.lang.Object.  This means that they
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
                // should have already been added to allMethods
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
                // when we walked our superclass lineage.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
                if (method.isPrivate() ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
                    method.isConstructor() ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
                    (pClass.isInterface() && !method.isAbstract())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
                // Get the components of the methods' signature.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
                Identifier name = method.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
                Type type = method.getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
                // Check for a method of the same signature which
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
                // was locally declared.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
                MemberDefinition override =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
                    myMethods.lookupSig(name, type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
                // Is this method inaccessible due to package-private
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
                // visibility?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
                if (method.isPackagePrivate() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
                    !inSamePackage(method.getClassDeclaration())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
                    if (override != null && this instanceof
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
                        sun.tools.javac.SourceClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
                        // We give a warning when a class shadows an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
                        // inaccessible package-private method from
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
                        // its superclass.  This warning is meant
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
                        // to prevent people from relying on overriding
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
                        // when it does not happen.  This warning should
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
                        // probably be removed to be consistent with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
                        // general "no warnings" policy of this
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
                        // compiler.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
                        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
                        // The `instanceof' above is a hack so that only
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
                        // SourceClass generates this warning, not a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
                        // BinaryClass, for example.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
                        env.error(method.getWhere(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
                                  "warn.no.override.access",
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
                                  override,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
                                  override.getClassDeclaration(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
                                  method.getClassDeclaration());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
                    // If our superclass has a package-private abstract
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
                    // method that we have no access to, then we add
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
                    // this method to our list of permanently abstract
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
                    // methods.  The idea is, since we cannot override
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
                    // the method, we can never make this class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
                    // non-abstract.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
                    if (method.isAbstract()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
                        permanentlyAbstractMethods.add(method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
                    // `method' is inaccessible.  We do not inherit it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
                if (override != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
                    // `method' and `override' have the same signature.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
                    // We are required to check that `override' is a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
                    // legal override of `method'
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
                    //System.out.println ("About to check override of " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
                    //              method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
                    override.checkOverride(env, method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
                    // In the absence of a definition in the class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
                    // itself, we check to see if this definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
                    // can be successfully merged with any other
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
                    // inherited definitions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
                    // Have we added a member of the same signature
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
                    // to `allMethods' already?
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
                    MemberDefinition formerMethod =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
                        allMethods.lookupSig(name, type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
                    // If the previous definition is nonexistent or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
                    // ignorable, replace it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
                    if (formerMethod == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
                        //System.out.println("Added " + method + " to " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
                        //             this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
                        if (mirandaMethods != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
                            pClass.isInterface() && !isInterface()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
                            // Whenever a class inherits a method
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
                            // from an interface, that method is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
                            // one of our "miranda" methods.  Early
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
                            // VMs require that these methods be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
                            // added as true members to the class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
                            // to enable method lookup to work in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
                            // VM.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
                            method =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
                                new sun.tools.javac.SourceMember(method,this,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
                                                                 env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
                            mirandaMethods.add(method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
                            //System.out.println("Added " + method +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
                            // " to " + this + " as a Miranda");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
                        // There is no previous inherited definition.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
                        // Add `method' to `allMethods'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
                        allMethods.add(method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
                    } else if (isInterface() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
                               !formerMethod.isAbstract() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
                               method.isAbstract()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
                        // If we are in an interface and we have inherited
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
                        // both an abstract method and a non-abstract method
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
                        // then we know that the non-abstract method is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
                        // a placeholder from Object put in for type checking
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
                        // and the abstract method was already checked to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
                        // be proper by our superinterface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
                        allMethods.replace(method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
                        // Okay, `formerMethod' and `method' both have the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
                        // same signature.  See if they are compatible.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
                        //System.out.println ("About to check meet of " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
                        //              method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
                        if (!formerMethod.checkMeet(env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
                                           method,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
                                           this.getClassDeclaration())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
                                // The methods are incompatible.  Skip to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
                                // next method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
                            continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
                        if (formerMethod.couldOverride(env, method)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
                                // Do nothing.  The current definition
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
                                // is specific enough.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
                                //System.out.println("trivial meet of " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
                                //                 method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
                            continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
                        if (method.couldOverride(env, formerMethod)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
                                // `method' is more specific than
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
                                // `formerMethod'.  replace `formerMethod'.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
                                //System.out.println("new def of " + method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
                            if (mirandaMethods != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
                                pClass.isInterface() && !isInterface()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
                                // Whenever a class inherits a method
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
                                // from an interface, that method is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
                                // one of our "miranda" methods.  Early
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
                                // VMs require that these methods be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
                                // added as true members to the class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
                                // to enable method lookup to work in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
                                // VM.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
                                method =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
                                    new sun.tools.javac.SourceMember(method,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
                                                                     this,env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
                                mirandaMethods.replace(method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
                                //System.out.println("Added " + method +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
                                // " to " + this + " as a Miranda");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
                            allMethods.replace(method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
                            continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
                        // Neither method is more specific than the other.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
                        // Oh well.  We need to construct a nontrivial
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
                        // meet of the two methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
                        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
                        // This is not yet implemented, so we give
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
                        // a message with a helpful workaround.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
                        env.error(this.where,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
                                  "nontrivial.meet", method,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
                                  formerMethod.getClassDefinition(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
                                  method.getClassDeclaration()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
                                  );
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
        } catch (ClassNotFound ee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
            env.error(getWhere(), "class.not.found", ee.name, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
     * <p>Collect all methods defined in this class or inherited from
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
     * any of our superclasses or interfaces.  Look for any
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
     * incompatible definitions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
     * <p>This function is also responsible for collecting the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
     * <em>Miranda</em> methods for a class.  For a definition of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
     * Miranda methods, see the comment in addMirandaMethods()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
     * below.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
    protected void collectInheritedMethods(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
        // The methods defined in this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
        MethodSet myMethods;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
        MethodSet mirandaMethods;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
        //System.out.println("Called collectInheritedMethods() for " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
        //                 this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
        if (allMethods != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
            if (allMethods.isFrozen()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
                // We have already done the collection.  No need to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
                // do it again.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
                // We have run into a circular need to collect our methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
                // This should not happen at this stage.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
                throw new CompilerError("collectInheritedMethods()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
        myMethods = new MethodSet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
        allMethods = new MethodSet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
        // For testing, do not generate miranda methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
        if (env.version12()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
            mirandaMethods = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
            mirandaMethods = new MethodSet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
        // Any methods defined in the current class get added
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
        // to both the myMethods and the allMethods MethodSets.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
        for (MemberDefinition member = getFirstMember();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
             member != null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
             member = member.nextMember) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
            // We only collect methods.  Initializers are not relevant.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
            if (member.isMethod() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
                !member.isInitializer()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
                //System.out.println("Declared in " + this + ", " + member);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
                ////////////////////////////////////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
                // PCJ 2003-07-30 modified the following code because with
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
                // the covariant return type feature of the 1.5 compiler,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
                // there might be multiple methods with the same signature
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
                // but different return types, and MethodSet doesn't
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
                // support that.  We use a new utility method that attempts
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
                // to ensure that the appropriate method winds up in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
                // MethodSet.  See 4892308.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
                ////////////////////////////////////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
                // myMethods.add(member);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
                // allMethods.add(member);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
                ////////////////////////////////////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
                methodSetAdd(env, myMethods, member);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
                methodSetAdd(env, allMethods, member);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
                ////////////////////////////////////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
        // We're ready to start adding inherited methods.  First add
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
        // the methods from our superclass.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
        //System.out.println("About to start superclasses for " + this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
        ClassDeclaration scDecl = getSuperClass(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
        if (scDecl != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
            collectOneClass(env, scDecl,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
                            myMethods, allMethods, mirandaMethods);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
            // Make sure that we add all unimplementable methods from our
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
            // superclass to our list of unimplementable methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
            ClassDefinition sc = scDecl.getClassDefinition();
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1524
            Iterator<MemberDefinition> supIter = sc.getPermanentlyAbstractMethods();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
            while (supIter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
                permanentlyAbstractMethods.add(supIter.next());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
        // Now we inherit all of the methods from our interfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
        //System.out.println("About to start interfaces for " + this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
        for (int i = 0; i < interfaces.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
            collectOneClass(env, interfaces[i],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
                            myMethods, allMethods, mirandaMethods);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
        allMethods.freeze();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
        // Now we have collected all of our methods from our superclasses
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
        // and interfaces into our `allMethods' member.  Good.  As a last
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
        // task, we add our collected miranda methods to this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
        // If we do not add the mirandas to the class explicitly, there
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
        // will be no code generated for them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
        if (mirandaMethods != null && mirandaMethods.size() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
            addMirandaMethods(env, mirandaMethods.iterator());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
    ////////////////////////////////////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
    // PCJ 2003-07-30 added this utility method to insulate
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
    // MethodSet additions from the covariant return type
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
    // feature of the 1.5 compiler.  When there are multiple
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
    // methods with the same signature and different return
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
    // types to be added, we try to ensure that the one with
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
    // the most specific return type winds up in the MethodSet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
    // This logic was not put into MethodSet itself because it
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
    // requires access to an Environment for type relationship
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
    // checking.  No error checking is performed here, but that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
    // should be OK because this code is only still used by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
    // rmic.  See 4892308.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
    ////////////////////////////////////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
    private static void methodSetAdd(Environment env,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1565
                                     MethodSet methodSet,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1566
                                     MemberDefinition newMethod)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1567
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1568
        MemberDefinition oldMethod = methodSet.lookupSig(newMethod.getName(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1569
                                                         newMethod.getType());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1570
        if (oldMethod != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1571
            Type oldReturnType = oldMethod.getType().getReturnType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1572
            Type newReturnType = newMethod.getType().getReturnType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1573
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1574
                if (env.isMoreSpecific(newReturnType, oldReturnType)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1575
                    methodSet.replace(newMethod);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1576
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1577
            } catch (ClassNotFound ignore) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1578
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1579
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1580
            methodSet.add(newMethod);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1581
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1582
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1583
    ////////////////////////////////////////////////////////////
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1584
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1585
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1586
     * Get an Iterator of all methods which could be accessed in an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1587
     * instance of this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1588
     */
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1589
    public Iterator<MemberDefinition> getMethods(Environment env) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1590
        if (allMethods == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1591
            collectInheritedMethods(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1592
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1593
        return getMethods();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1594
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1595
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1596
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1597
     * Get an Iterator of all methods which could be accessed in an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1598
     * instance of this class.  Throw a compiler error if we haven't
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1599
     * generated this information yet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1600
     */
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1601
    public Iterator<MemberDefinition> getMethods() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1602
        if (allMethods == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1603
            throw new CompilerError("getMethods: too early");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1604
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1605
        return allMethods.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1606
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1607
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1608
    // In early VM's there was a bug -- the VM didn't walk the interfaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1609
    // of a class looking for a method, they only walked the superclass
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1610
    // chain.  This meant that abstract methods defined only in interfaces
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1611
    // were not being found.  To fix this bug, a counter-bug was introduced
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1612
    // in the compiler -- the so-called Miranda methods.  If a class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1613
    // does not provide a definition for an abstract method in one of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1614
    // its interfaces then the compiler inserts one in the class artificially.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1615
    // That way the VM didn't have to bother looking at the interfaces.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1616
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1617
    // This is a problem.  Miranda methods are not part of the specification.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1618
    // But they continue to be inserted so that old VM's can run new code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1619
    // Someday, when the old VM's are gone, perhaps classes can be compiled
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1620
    // without Miranda methods.  Towards this end, the compiler has a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1621
    // flag, -nomiranda, which can turn off the creation of these methods.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1622
    // Eventually that behavior should become the default.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1623
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1624
    // Why are they called Miranda methods?  Well the sentence "If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1625
    // class is not able to provide a method, then one will be provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1626
    // by the compiler" is very similar to the sentence "If you cannot
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1627
    // afford an attorney, one will be provided by the court," -- one
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1628
    // of the so-called "Miranda" rights in the United States.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1629
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1630
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1631
     * Add a list of methods to this class as miranda methods.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1632
     * gets overridden with a meaningful implementation in SourceClass.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1633
     * BinaryClass should not need to do anything -- it should already
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1634
     * have its miranda methods and, if it doesn't, then that doesn't
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1635
     * affect our compilation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1636
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1637
    protected void addMirandaMethods(Environment env,
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1638
                                     Iterator<MemberDefinition> mirandas) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1639
        // do nothing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1640
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1641
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1642
    //---------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1643
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1644
    public void inlineLocalClass(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1645
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1646
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1647
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1648
     * We create a stub for this.  Source classes do more work.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1649
     * Some calls from 'SourceClass.checkSupers' execute this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1650
     * @see sun.tools.javac.SourceClass#resolveTypeStructure
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1651
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1652
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1653
    public void resolveTypeStructure(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1654
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1655
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1656
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1657
     * Look up an inner class name, from somewhere inside this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1658
     * Since supers and outers are in scope, search them too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1659
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1660
     * If no inner class is found, env.resolveName() is then called,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1661
     * to interpret the ambient package and import directives.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1662
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1663
     * This routine operates on a "best-efforts" basis.  If
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1664
     * at some point a class is not found, the partially-resolved
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1665
     * identifier is returned.  Eventually, someone else has to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1666
     * try to get the ClassDefinition and diagnose the ClassNotFound.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1667
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1668
     * resolveName() looks at surrounding scopes, and hence
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1669
     * pulling in both inherited and uplevel types.  By contrast,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1670
     * resolveInnerClass() is intended only for interpreting
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1671
     * explicitly qualified names, and so look only at inherited
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1672
     * types.  Also, resolveName() looks for package prefixes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1673
     * which appear similar to "very uplevel" outer classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1674
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1675
     * A similar (but more complex) name-lookup process happens
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1676
     * when field and identifier expressions denoting qualified names
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1677
     * are type-checked.  The added complexity comes from the fact
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1678
     * that variables may occur in such names, and take precedence
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1679
     * over class and package names.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1680
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1681
     * In the expression type-checker, resolveInnerClass() is paralleled
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1682
     * by code in FieldExpression.checkAmbigName(), which also calls
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1683
     * ClassDefinition.getInnerClass() to interpret names of the form
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1684
     * "OuterClass.Inner" (and also outerObject.Inner).  The checking
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1685
     * of an identifier expression that fails to be a variable is referred
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1686
     * directly to resolveName().
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1687
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1688
    public Identifier resolveName(Environment env, Identifier name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1689
        if (tracing) env.dtEvent("ClassDefinition.resolveName: " + name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1690
        // This logic is pretty much exactly parallel to that of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1691
        // Environment.resolveName().
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1692
        if (name.isQualified()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1693
            // Try to resolve the first identifier component,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1694
            // because inner class names take precedence over
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1695
            // package prefixes.  (Cf. Environment.resolveName.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1696
            Identifier rhead = resolveName(env, name.getHead());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1697
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1698
            if (rhead.hasAmbigPrefix()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1699
                // The first identifier component refers to an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1700
                // ambiguous class.  Limp on.  We throw away the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1701
                // rest of the classname as it is irrelevant.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1702
                // (part of solution for 4059855).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1703
                return rhead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1704
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1705
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1706
            if (!env.classExists(rhead)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1707
                return env.resolvePackageQualifiedName(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1708
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1709
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1710
                return env.getClassDefinition(rhead).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1711
                    resolveInnerClass(env, name.getTail());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1712
            } catch (ClassNotFound ee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1713
                // return partially-resolved name someone else can fail on
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1714
                return Identifier.lookupInner(rhead, name.getTail());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1715
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1716
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1717
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1718
        // This method used to fail to look for local classes, thus a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1719
        // reference to a local class within, e.g., the type of a member
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1720
        // declaration, would fail to resolve if the immediately enclosing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1721
        // context was an inner class.  The code added below is ugly, but
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1722
        // it works, and is lifted from existing code in 'Context.resolveName'
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1723
        // and 'Context.getClassCommon'. See the comments there about the design.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1724
        // Fixes 4095716.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1725
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1726
        int ls = -2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1727
        LocalMember lf = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1728
        if (classContext != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1729
            lf = classContext.getLocalClass(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1730
            if (lf != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1731
                ls = lf.getScopeNumber();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1732
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1733
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1734
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1735
        // Look for an unqualified name in enclosing scopes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1736
        for (ClassDefinition c = this; c != null; c = c.outerClass) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1737
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1738
                MemberDefinition f = c.getInnerClass(env, name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1739
                if (f != null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1740
                    (lf == null || classContext.getScopeNumber(c) > ls)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1741
                    // An uplevel member was found, and was nested more deeply than
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1742
                    // any enclosing local of the same name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1743
                    return f.getInnerClass().getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1744
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1745
            } catch (ClassNotFound ee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1746
                // a missing superclass, or something catastrophic
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1747
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1748
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1749
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1750
        // No uplevel member found, so use the enclosing local if one was found.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1751
        if (lf != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1752
           return lf.getInnerClass().getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1753
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1754
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1755
        // look in imports, etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1756
        return env.resolveName(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1757
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1758
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1759
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1760
     * Interpret a qualified class name, which may have further subcomponents..
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1761
     * Follow inheritance links, as in:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1762
     *  class C { class N { } }  class D extends C { }  ... new D.N() ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1763
     * Ignore outer scopes and packages.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1764
     * @see resolveName
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1765
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1766
    public Identifier resolveInnerClass(Environment env, Identifier nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1767
        if (nm.isInner())  throw new CompilerError("inner");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1768
        if (nm.isQualified()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1769
            Identifier rhead = resolveInnerClass(env, nm.getHead());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1770
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1771
                return env.getClassDefinition(rhead).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1772
                    resolveInnerClass(env, nm.getTail());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1773
            } catch (ClassNotFound ee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1774
                // return partially-resolved name someone else can fail on
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1775
                return Identifier.lookupInner(rhead, nm.getTail());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1776
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1777
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1778
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1779
                MemberDefinition f = getInnerClass(env, nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1780
                if (f != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1781
                    return f.getInnerClass().getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1782
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1783
            } catch (ClassNotFound ee) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1784
                // a missing superclass, or something catastrophic
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1785
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1786
            // Fake a good name for a diagnostic.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1787
            return Identifier.lookupInner(this.getName(), nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1788
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1789
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1790
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1791
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1792
     * While resolving import directives, the question has arisen:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1793
     * does a given inner class exist?  If the top-level class exists,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1794
     * we ask it about an inner class via this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1795
     * This method looks only at the literal name of the class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1796
     * and does not attempt to follow inheritance links.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1797
     * This is necessary, since at the time imports are being
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1798
     * processed, inheritance links have not been resolved yet.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1799
     * (Thus, an import directive must always spell a class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1800
     * name exactly.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1801
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1802
    public boolean innerClassExists(Identifier nm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1803
        for (MemberDefinition field = getFirstMatch(nm.getHead()) ; field != null ; field = field.getNextMatch()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1804
            if (field.isInnerClass()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1805
                if (field.getInnerClass().isLocal()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1806
                    continue;   // ignore this name; it is internally generated
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1807
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1808
                return !nm.isQualified() ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1809
                    field.getInnerClass().innerClassExists(nm.getTail());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1810
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1811
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1812
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1813
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1814
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1815
   /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1816
     * Find any method with a given name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1817
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1818
    public MemberDefinition findAnyMethod(Environment env, Identifier nm) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1819
        MemberDefinition f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1820
        for (f = getFirstMatch(nm) ; f != null ; f = f.getNextMatch()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1821
            if (f.isMethod()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1822
                return f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1823
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1824
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1825
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1826
        // look in the super class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1827
        ClassDeclaration sup = getSuperClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1828
        if (sup == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1829
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1830
        return sup.getClassDefinition(env).findAnyMethod(env, nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1831
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1832
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1833
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1834
      * Given the fact that this class has no method "nm" matching "argTypes",
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1835
      * find out if the mismatch can be blamed on a particular actual argument
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1836
      * which disagrees with all of the overloadings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1837
      * If so, return the code (i<<2)+(castOK<<1)+ambig, where
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1838
      * "i" is the number of the offending argument, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1839
      * "castOK" is 1 if a cast could fix the problem.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1840
      * The target type for the argument is returned in margTypeResult[0].
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1841
      * If not all methods agree on this type, "ambig" is 1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1842
      * If there is more than one method, the choice of target type is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1843
      * arbitrary.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1844
      * Return -1 if every argument is acceptable to at least one method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1845
      * Return -2 if there are no methods of the required arity.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1846
      * The value "start" gives the index of the first argument to begin
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1847
      * checking.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1848
      */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1849
    public int diagnoseMismatch(Environment env, Identifier nm, Type argTypes[],
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1850
                                int start, Type margTypeResult[]) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1851
        int haveMatch[] = new int[argTypes.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1852
        Type margType[] = new Type[argTypes.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1853
        if (!diagnoseMismatch(env, nm, argTypes, start, haveMatch, margType))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1854
            return -2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1855
        for (int i = start; i < argTypes.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1856
            if (haveMatch[i] < 4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1857
                margTypeResult[0] = margType[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1858
                return (i<<2) | haveMatch[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1859
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1860
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1861
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1862
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1863
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1864
    private boolean diagnoseMismatch(Environment env, Identifier nm, Type argTypes[], int start,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1865
                                     int haveMatch[], Type margType[]) throws ClassNotFound {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1866
        // look in the current class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1867
        boolean haveOne = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1868
        MemberDefinition f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1869
        for (f = getFirstMatch(nm) ; f != null ; f = f.getNextMatch()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1870
            if (!f.isMethod()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1871
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1872
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1873
            Type fArgTypes[] = f.getType().getArgumentTypes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1874
            if (fArgTypes.length == argTypes.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1875
                haveOne = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1876
                for (int i = start; i < argTypes.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1877
                    Type at = argTypes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1878
                    Type ft = fArgTypes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1879
                    if (env.implicitCast(at, ft)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1880
                        haveMatch[i] = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1881
                        continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1882
                    } else if (haveMatch[i] <= 2 && env.explicitCast(at, ft)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1883
                        if (haveMatch[i] < 2)  margType[i] = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1884
                        haveMatch[i] = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1885
                    } else if (haveMatch[i] > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1886
                        continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1887
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1888
                    if (margType[i] == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1889
                        margType[i] = ft;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1890
                    else if (margType[i] != ft)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1891
                        haveMatch[i] |= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1892
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1893
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1894
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1895
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1896
        // constructors are not inherited
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1897
        if (nm.equals(idInit)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1898
            return haveOne;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1899
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1900
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1901
        // look in the super class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1902
        ClassDeclaration sup = getSuperClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1903
        if (sup != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1904
            if (sup.getClassDefinition(env).diagnoseMismatch(env, nm, argTypes, start,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1905
                                                             haveMatch, margType))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1906
                haveOne = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1907
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1908
        return haveOne;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1909
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1910
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1911
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1912
     * Add a field (no checks)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1913
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1914
    public void addMember(MemberDefinition field) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1915
        //System.out.println("ADD = " + field);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1916
        if (firstMember == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1917
            firstMember = lastMember = field;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1918
        } else if (field.isSynthetic() && field.isFinal()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1919
                                       && field.isVariable()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1920
            // insert this at the front, because of initialization order
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1921
            field.nextMember = firstMember;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1922
            firstMember = field;
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1923
            field.nextMatch = fieldHash.get(field.name);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1924
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1925
            lastMember.nextMember = field;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1926
            lastMember = field;
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  1927
            field.nextMatch = fieldHash.get(field.name);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1928
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1929
        fieldHash.put(field.name, field);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1930
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1931
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1932
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1933
     * Add a field (subclasses make checks)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1934
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1935
    public void addMember(Environment env, MemberDefinition field) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1936
        addMember(field);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1937
        if (resolved) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1938
            // a late addition
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1939
            field.resolveTypeStructure(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1940
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1941
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1942
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1943
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1944
     * Find or create an uplevel reference for the given target.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1945
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1946
    public UplevelReference getReference(LocalMember target) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1947
        for (UplevelReference r = references; r != null; r = r.getNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1948
            if (r.getTarget() == target) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1949
                return r;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1950
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1951
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1952
        return addReference(target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1953
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1954
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1955
    protected UplevelReference addReference(LocalMember target) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1956
        if (target.getClassDefinition() == this) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1957
            throw new CompilerError("addReference "+target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1958
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1959
        referencesMustNotBeFrozen();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1960
        UplevelReference r = new UplevelReference(this, target);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1961
        references = r.insertInto(references);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1962
        return r;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1963
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1964
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1965
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1966
     * Return the list of all uplevel references.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1967
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1968
    public UplevelReference getReferences() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1969
        return references;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1970
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1971
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1972
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1973
     * Return the same value as getReferences.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1974
     * Also, mark the set of references frozen.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1975
     * After that, it is an error to add new references.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1976
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1977
    public UplevelReference getReferencesFrozen() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1978
        referencesFrozen = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1979
        return references;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1980
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1981
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1982
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1983
     * assertion check
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1984
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1985
    public final void referencesMustNotBeFrozen() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1986
        if (referencesFrozen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1987
            throw new CompilerError("referencesMustNotBeFrozen "+this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1988
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1989
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1990
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1991
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1992
     * Get helper method for class literal lookup.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1993
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1994
    public MemberDefinition getClassLiteralLookup(long fwhere) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1995
        throw new CompilerError("binary class");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1996
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1997
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1998
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1999
     * Add a dependency
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2000
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2001
    public void addDependency(ClassDeclaration c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2002
        throw new CompilerError("addDependency");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2003
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2004
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2005
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2006
     * Maintain a hash table of local and anonymous classes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2007
     * whose internal names are prefixed by the current class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2008
     * The key is the simple internal name, less the prefix.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2009
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2010
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2011
    public ClassDefinition getLocalClass(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2012
        if (localClasses == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2013
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2014
        } else {
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  2015
            return localClasses.get(name);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2016
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2017
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2018
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2019
    public void addLocalClass(ClassDefinition c, String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2020
        if (localClasses == null) {
25799
1afc4675dc75 8044867: Fix raw and unchecked lint warnings in sun.tools.*
ntoda
parents: 5506
diff changeset
  2021
            localClasses = new Hashtable<>(LOCAL_CLASSES_SIZE);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2022
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2023
        localClasses.put(name, c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2024
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2025
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2026
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2027
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2028
     * Print for debugging
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2029
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2030
    public void print(PrintStream out) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2031
        if (isPublic()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2032
            out.print("public ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2033
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2034
        if (isInterface()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2035
            out.print("interface ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2036
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2037
            out.print("class ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2038
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2039
        out.print(getName() + " ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2040
        if (getSuperClass() != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2041
            out.print("extends " + getSuperClass().getName() + " ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2042
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2043
        if (interfaces.length > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2044
            out.print("implements ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2045
            for (int i = 0 ; i < interfaces.length ; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2046
                if (i > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2047
                    out.print(", ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2048
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2049
                out.print(interfaces[i].getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2050
                out.print(" ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2051
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2052
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2053
        out.println("{");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2054
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2055
        for (MemberDefinition f = getFirstMember() ; f != null ; f = f.getNextMember()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2056
            out.print("    ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2057
            f.print(out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2058
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2059
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2060
        out.println("}");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2061
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2062
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2063
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2064
     * Convert to String
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2065
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2066
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2067
        return getClassDeclaration().toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2068
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2069
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2070
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2071
     * After the class has been written to disk, try to free up
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2072
     * some storage.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2073
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2074
    public void cleanup(Environment env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2075
        if (env.dump()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2076
            env.output("[cleanup " + getName() + "]");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2077
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2078
        for (MemberDefinition f = getFirstMember() ; f != null ; f = f.getNextMember()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2079
            f.cleanup(env);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2080
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2081
        // keep "references" around, for the sake of local subclasses
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2082
        documentation = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2083
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  2084
}