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