Symbol.java revision 3981:8be741555fa6
1195534Sscottl/*
2195534Sscottl * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
3195534Sscottl * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4195534Sscottl *
5195534Sscottl * This code is free software; you can redistribute it and/or modify it
6195534Sscottl * under the terms of the GNU General Public License version 2 only, as
7195534Sscottl * published by the Free Software Foundation.  Oracle designates this
8195534Sscottl * particular file as subject to the "Classpath" exception as provided
9195534Sscottl * by Oracle in the LICENSE file that accompanied this code.
10195534Sscottl *
11195534Sscottl * This code is distributed in the hope that it will be useful, but WITHOUT
12195534Sscottl * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13195534Sscottl * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14195534Sscottl * version 2 for more details (a copy is included in the LICENSE file that
15195534Sscottl * accompanied this code).
16195534Sscottl *
17195534Sscottl * You should have received a copy of the GNU General Public License version
18195534Sscottl * 2 along with this work; if not, write to the Free Software Foundation,
19195534Sscottl * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20195534Sscottl *
21195534Sscottl * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22195534Sscottl * or visit www.oracle.com if you need additional information or have any
23195534Sscottl * questions.
24195534Sscottl */
25195534Sscottl
26195534Sscottlpackage com.sun.tools.javac.code;
27195534Sscottl
28195534Sscottlimport java.lang.annotation.Annotation;
29195534Sscottlimport java.lang.annotation.Inherited;
30195534Sscottlimport java.util.Collections;
31195534Sscottlimport java.util.EnumSet;
32195534Sscottlimport java.util.Map;
33195534Sscottlimport java.util.Set;
34195534Sscottlimport java.util.concurrent.Callable;
35195534Sscottl
36195534Sscottlimport javax.lang.model.element.Element;
37195534Sscottlimport javax.lang.model.element.ElementKind;
38195534Sscottlimport javax.lang.model.element.ElementVisitor;
39195534Sscottlimport javax.lang.model.element.ExecutableElement;
40195534Sscottlimport javax.lang.model.element.Modifier;
41195534Sscottlimport javax.lang.model.element.ModuleElement;
42195534Sscottlimport javax.lang.model.element.NestingKind;
43195534Sscottlimport javax.lang.model.element.PackageElement;
44195534Sscottlimport javax.lang.model.element.TypeElement;
45195534Sscottlimport javax.lang.model.element.TypeParameterElement;
46195534Sscottlimport javax.lang.model.element.VariableElement;
47195534Sscottlimport javax.tools.JavaFileManager;
48195534Sscottlimport javax.tools.JavaFileObject;
49195534Sscottl
50195534Sscottlimport com.sun.tools.javac.code.ClassFinder.BadEnclosingMethodAttr;
51195534Sscottlimport com.sun.tools.javac.code.Directive.RequiresFlag;
52195534Sscottlimport com.sun.tools.javac.code.Kinds.Kind;
53195534Sscottlimport com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
54195534Sscottlimport com.sun.tools.javac.code.Scope.WriteableScope;
55195534Sscottlimport com.sun.tools.javac.code.Type.*;
56195534Sscottlimport com.sun.tools.javac.comp.Attr;
57195534Sscottlimport com.sun.tools.javac.comp.AttrContext;
58195534Sscottlimport com.sun.tools.javac.comp.Env;
59195534Sscottlimport com.sun.tools.javac.jvm.*;
60195534Sscottlimport com.sun.tools.javac.tree.JCTree.JCFieldAccess;
61195534Sscottlimport com.sun.tools.javac.tree.JCTree.JCVariableDecl;
62195534Sscottlimport com.sun.tools.javac.tree.JCTree.Tag;
63195534Sscottlimport com.sun.tools.javac.util.*;
64195534Sscottlimport com.sun.tools.javac.util.DefinedBy.Api;
65195534Sscottlimport com.sun.tools.javac.util.Name;
66195534Sscottl
67195534Sscottlimport static com.sun.tools.javac.code.Flags.*;
68195534Sscottlimport static com.sun.tools.javac.code.Kinds.*;
69195534Sscottlimport static com.sun.tools.javac.code.Kinds.Kind.*;
70195534Sscottlimport static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
71195534Sscottlimport static com.sun.tools.javac.code.Symbol.OperatorSymbol.AccessCode.FIRSTASGOP;
72195534Sscottlimport static com.sun.tools.javac.code.TypeTag.CLASS;
73195534Sscottlimport static com.sun.tools.javac.code.TypeTag.FORALL;
74195534Sscottlimport static com.sun.tools.javac.code.TypeTag.TYPEVAR;
75195534Sscottlimport static com.sun.tools.javac.jvm.ByteCodes.iadd;
76195534Sscottlimport static com.sun.tools.javac.jvm.ByteCodes.ishll;
77195534Sscottlimport static com.sun.tools.javac.jvm.ByteCodes.lushrl;
78195534Sscottlimport static com.sun.tools.javac.jvm.ByteCodes.lxor;
79195534Sscottlimport static com.sun.tools.javac.jvm.ByteCodes.string_add;
80195534Sscottl
81195534Sscottl/** Root class for Java symbols. It contains subclasses
82195534Sscottl *  for specific sorts of symbols, such as variables, methods and operators,
83195534Sscottl *  types, packages. Each subclass is represented as a static inner class
84195534Sscottl *  inside Symbol.
85195534Sscottl *
86195534Sscottl *  <p><b>This is NOT part of any supported API.
87195534Sscottl *  If you write code that depends on this, you do so at your own risk.
88195534Sscottl *  This code and its internal interfaces are subject to change or
89195534Sscottl *  deletion without notice.</b>
90195534Sscottl */
91195534Sscottlpublic abstract class Symbol extends AnnoConstruct implements Element {
92195534Sscottl
93195534Sscottl    /** The kind of this symbol.
94195534Sscottl     *  @see Kinds
95195534Sscottl     */
96195534Sscottl    public Kind kind;
97195534Sscottl
98195534Sscottl    /** The flags of this symbol.
99195534Sscottl     */
100195534Sscottl    public long flags_field;
101195534Sscottl
102195534Sscottl    /** An accessor method for the flags of this symbol.
103258216Smav     *  Flags of class symbols should be accessed through the accessor
104195534Sscottl     *  method to make sure that the class symbol is loaded.
105195534Sscottl     */
106195534Sscottl    public long flags() { return flags_field; }
107195534Sscottl
108195534Sscottl    /** The name of this symbol in Utf8 representation.
109195534Sscottl     */
110195534Sscottl    public Name name;
111195534Sscottl
112195534Sscottl    /** The type of this symbol.
113195534Sscottl     */
114195534Sscottl    public Type type;
115195534Sscottl
116195534Sscottl    /** The owner of this symbol.
117195534Sscottl     */
118195534Sscottl    public Symbol owner;
119195534Sscottl
120195534Sscottl    /** The completer of this symbol.
121195534Sscottl     * This should never equal null (NULL_COMPLETER should be used instead).
122220657Smav     */
123195534Sscottl    public Completer completer;
124195534Sscottl
125195534Sscottl    /** A cache for the type erasure of this symbol.
126195534Sscottl     */
127195534Sscottl    public Type erasure_field;
128195534Sscottl
129195534Sscottl    // <editor-fold defaultstate="collapsed" desc="annotations">
130195534Sscottl
131195534Sscottl    /** The attributes of this symbol are contained in this
132195534Sscottl     * SymbolMetadata. The SymbolMetadata instance is NOT immutable.
133195534Sscottl     */
134195534Sscottl    protected SymbolMetadata metadata;
135195534Sscottl
136195534Sscottl
137195534Sscottl    /** An accessor method for the attributes of this symbol.
138195534Sscottl     *  Attributes of class symbols should be accessed through the accessor
139195534Sscottl     *  method to make sure that the class symbol is loaded.
140195534Sscottl     */
141195534Sscottl    public List<Attribute.Compound> getRawAttributes() {
142195534Sscottl        return (metadata == null)
143195534Sscottl                ? List.nil()
144195534Sscottl                : metadata.getDeclarationAttributes();
145195534Sscottl    }
146195534Sscottl
147195534Sscottl    /** An accessor method for the type attributes of this symbol.
148195534Sscottl     *  Attributes of class symbols should be accessed through the accessor
149195534Sscottl     *  method to make sure that the class symbol is loaded.
150195534Sscottl     */
151195534Sscottl    public List<Attribute.TypeCompound> getRawTypeAttributes() {
152195534Sscottl        return (metadata == null)
153195534Sscottl                ? List.nil()
154195534Sscottl                : metadata.getTypeAttributes();
155195534Sscottl    }
156195534Sscottl
157195534Sscottl    /** Fetch a particular annotation from a symbol. */
158195534Sscottl    public Attribute.Compound attribute(Symbol anno) {
159195534Sscottl        for (Attribute.Compound a : getRawAttributes()) {
160195534Sscottl            if (a.type.tsym == anno) return a;
161195534Sscottl        }
162195534Sscottl        return null;
163195534Sscottl    }
164195534Sscottl
165195534Sscottl    public boolean annotationsPendingCompletion() {
166195534Sscottl        return metadata == null ? false : metadata.pendingCompletion();
167195534Sscottl    }
168195534Sscottl
169195534Sscottl    public void appendAttributes(List<Attribute.Compound> l) {
170195534Sscottl        if (l.nonEmpty()) {
171195534Sscottl            initedMetadata().append(l);
172195534Sscottl        }
173195534Sscottl    }
174195534Sscottl
175195534Sscottl    public void appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
176195534Sscottl        if (l.nonEmpty()) {
177195534Sscottl            initedMetadata().appendClassInitTypeAttributes(l);
178195534Sscottl        }
179195534Sscottl    }
180195534Sscottl
181196656Smav    public void appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
182196656Smav        if (l.nonEmpty()) {
183196656Smav            initedMetadata().appendInitTypeAttributes(l);
184196656Smav        }
185196656Smav    }
186196656Smav
187196656Smav    public void appendUniqueTypeAttributes(List<Attribute.TypeCompound> l) {
188196656Smav        if (l.nonEmpty()) {
189196656Smav            initedMetadata().appendUniqueTypes(l);
190196656Smav        }
191203108Smav    }
192203108Smav
193203108Smav    public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
194203108Smav        return (metadata == null)
195203108Smav                ? List.nil()
196203108Smav                : metadata.getClassInitTypeAttributes();
197203108Smav    }
198203108Smav
199203108Smav    public List<Attribute.TypeCompound> getInitTypeAttributes() {
200203108Smav        return (metadata == null)
201203108Smav                ? List.nil()
202203108Smav                : metadata.getInitTypeAttributes();
203203108Smav    }
204203108Smav
205196656Smav    public void setInitTypeAttributes(List<Attribute.TypeCompound> l) {
206196656Smav        initedMetadata().setInitTypeAttributes(l);
207196656Smav    }
208196656Smav
209258216Smav    public void setClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
210258216Smav        initedMetadata().setClassInitTypeAttributes(l);
211258216Smav    }
212196656Smav
213195534Sscottl    public List<Attribute.Compound> getDeclarationAttributes() {
214195534Sscottl        return (metadata == null)
215195534Sscottl                ? List.nil()
216195534Sscottl                : metadata.getDeclarationAttributes();
217195534Sscottl    }
218195534Sscottl
219195534Sscottl    public boolean hasAnnotations() {
220195534Sscottl        return (metadata != null && !metadata.isEmpty());
221195534Sscottl    }
222195534Sscottl
223195534Sscottl    public boolean hasTypeAnnotations() {
224195534Sscottl        return (metadata != null && !metadata.isTypesEmpty());
225195534Sscottl    }
226195534Sscottl
227195534Sscottl    public boolean isCompleted() {
228195534Sscottl        return completer.isTerminal();
229220657Smav    }
230195534Sscottl
231195534Sscottl    public void prependAttributes(List<Attribute.Compound> l) {
232195534Sscottl        if (l.nonEmpty()) {
233195534Sscottl            initedMetadata().prepend(l);
234195534Sscottl        }
235195534Sscottl    }
236195534Sscottl
237195534Sscottl    public void resetAnnotations() {
238195534Sscottl        initedMetadata().reset();
239195534Sscottl    }
240195534Sscottl
241195534Sscottl    public void setAttributes(Symbol other) {
242195534Sscottl        if (metadata != null || other.metadata != null) {
243195534Sscottl            initedMetadata().setAttributes(other.metadata);
244195534Sscottl        }
245195534Sscottl    }
246195534Sscottl
247195534Sscottl    public void setDeclarationAttributes(List<Attribute.Compound> a) {
248195534Sscottl        if (metadata != null || a.nonEmpty()) {
249195534Sscottl            initedMetadata().setDeclarationAttributes(a);
250195534Sscottl        }
251195534Sscottl    }
252195534Sscottl
253195534Sscottl    public void setTypeAttributes(List<Attribute.TypeCompound> a) {
254195534Sscottl        if (metadata != null || a.nonEmpty()) {
255203123Smav            if (metadata == null)
256195534Sscottl                metadata = new SymbolMetadata(this);
257203123Smav            metadata.setTypeAttributes(a);
258203123Smav        }
259203123Smav    }
260195534Sscottl
261195534Sscottl    private SymbolMetadata initedMetadata() {
262195534Sscottl        if (metadata == null)
263195534Sscottl            metadata = new SymbolMetadata(this);
264195534Sscottl        return metadata;
265195534Sscottl    }
266195534Sscottl
267195534Sscottl    /** This method is intended for debugging only. */
268195534Sscottl    public SymbolMetadata getMetadata() {
269258216Smav        return metadata;
270195534Sscottl    }
271195534Sscottl
272195534Sscottl    // </editor-fold>
273195534Sscottl
274195534Sscottl    /** Construct a symbol with given kind, flags, name, type and owner.
275195534Sscottl     */
276195534Sscottl    public Symbol(Kind kind, long flags, Name name, Type type, Symbol owner) {
277195534Sscottl        this.kind = kind;
278195534Sscottl        this.flags_field = flags;
279195534Sscottl        this.type = type;
280203123Smav        this.owner = owner;
281203123Smav        this.completer = Completer.NULL_COMPLETER;
282203123Smav        this.erasure_field = null;
283203123Smav        this.name = name;
284203123Smav    }
285203123Smav
286203123Smav    /** Clone this symbol with new owner.
287203123Smav     *  Legal only for fields and methods.
288203123Smav     */
289195534Sscottl    public Symbol clone(Symbol newOwner) {
290195534Sscottl        throw new AssertionError();
291195534Sscottl    }
292195534Sscottl
293195534Sscottl    public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
294195534Sscottl        return v.visitSymbol(this, p);
295195534Sscottl    }
296195534Sscottl
297195534Sscottl    /** The Java source which this symbol represents.
298195534Sscottl     *  A description of this symbol; overrides Object.
299195534Sscottl     */
300195534Sscottl    public String toString() {
301195534Sscottl        return name.toString();
302195534Sscottl    }
303195534Sscottl
304195534Sscottl    /** A Java source description of the location of this symbol; used for
305195534Sscottl     *  error reporting.
306195534Sscottl     *
307195534Sscottl     * @return null if the symbol is a package or a toplevel class defined in
308195534Sscottl     * the default package; otherwise, the owner symbol is returned
309195534Sscottl     */
310195534Sscottl    public Symbol location() {
311195534Sscottl        if (owner.name == null || (owner.name.isEmpty() &&
312195534Sscottl                                   (owner.flags() & BLOCK) == 0 &&
313195534Sscottl                                   owner.kind != PCK &&
314195534Sscottl                                   owner.kind != TYP)) {
315195534Sscottl            return null;
316195534Sscottl        }
317195534Sscottl        return owner;
318195534Sscottl    }
319195534Sscottl
320195534Sscottl    public Symbol location(Type site, Types types) {
321195534Sscottl        if (owner.name == null || owner.name.isEmpty()) {
322195534Sscottl            return location();
323195534Sscottl        }
324195534Sscottl        if (owner.type.hasTag(CLASS)) {
325195534Sscottl            Type ownertype = types.asOuterSuper(site, owner);
326195534Sscottl            if (ownertype != null) return ownertype.tsym;
327195534Sscottl        }
328195534Sscottl        return owner;
329195534Sscottl    }
330195534Sscottl
331195534Sscottl    public Symbol baseSymbol() {
332195534Sscottl        return this;
333195534Sscottl    }
334195534Sscottl
335195534Sscottl    /** The symbol's erased type.
336195534Sscottl     */
337195534Sscottl    public Type erasure(Types types) {
338195534Sscottl        if (erasure_field == null)
339195534Sscottl            erasure_field = types.erasure(type);
340195534Sscottl        return erasure_field;
341195534Sscottl    }
342195534Sscottl
343195534Sscottl    /** The external type of a symbol. This is the symbol's erased type
344195534Sscottl     *  except for constructors of inner classes which get the enclosing
345195534Sscottl     *  instance class added as first argument.
346195534Sscottl     */
347195534Sscottl    public Type externalType(Types types) {
348195534Sscottl        Type t = erasure(types);
349195534Sscottl        if (name == name.table.names.init && owner.hasOuterInstance()) {
350195534Sscottl            Type outerThisType = types.erasure(owner.type.getEnclosingType());
351195534Sscottl            return new MethodType(t.getParameterTypes().prepend(outerThisType),
352195534Sscottl                                  t.getReturnType(),
353195534Sscottl                                  t.getThrownTypes(),
354195534Sscottl                                  t.tsym);
355195534Sscottl        } else {
356195534Sscottl            return t;
357195534Sscottl        }
358195534Sscottl    }
359195534Sscottl
360195534Sscottl    public boolean isDeprecated() {
361195534Sscottl        return (flags_field & DEPRECATED) != 0;
362198319Smav    }
363195534Sscottl
364195534Sscottl    public boolean hasDeprecatedAnnotation() {
365195534Sscottl        return (flags_field & DEPRECATED_ANNOTATION) != 0;
366195534Sscottl    }
367195534Sscottl
368195534Sscottl    public boolean isDeprecatedForRemoval() {
369195534Sscottl        return (flags_field & DEPRECATED_REMOVAL) != 0;
370195534Sscottl    }
371195534Sscottl
372195534Sscottl    public boolean isDeprecatableViaAnnotation() {
373195534Sscottl        switch (getKind()) {
374199747Smav            case LOCAL_VARIABLE:
375199821Smav            case PACKAGE:
376199747Smav            case PARAMETER:
377199747Smav            case RESOURCE_VARIABLE:
378203376Smav            case EXCEPTION_PARAMETER:
379199747Smav                return false;
380207499Smav            default:
381199747Smav                return true;
382199747Smav        }
383222039Smav    }
384222039Smav
385222039Smav    public boolean isStatic() {
386222039Smav        return
387222039Smav            (flags() & STATIC) != 0 ||
388222039Smav            (owner.flags() & INTERFACE) != 0 && kind != MTH &&
389222039Smav             name != name.table.names._this;
390222039Smav    }
391222039Smav
392195534Sscottl    public boolean isInterface() {
393195534Sscottl        return (flags() & INTERFACE) != 0;
394195534Sscottl    }
395195534Sscottl
396195534Sscottl    public boolean isPrivate() {
397195534Sscottl        return (flags_field & Flags.AccessFlags) == PRIVATE;
398195534Sscottl    }
399195534Sscottl
400195534Sscottl    public boolean isEnum() {
401195534Sscottl        return (flags() & ENUM) != 0;
402222039Smav    }
403195534Sscottl
404196656Smav    /** Is this symbol declared (directly or indirectly) local
405203123Smav     *  to a method or variable initializer?
406199322Smav     *  Also includes fields of inner classes which are in
407195534Sscottl     *  turn local to a method or variable initializer.
408195534Sscottl     */
409195534Sscottl    public boolean isLocal() {
410195534Sscottl        return
411195534Sscottl            (owner.kind.matches(KindSelector.VAL_MTH) ||
412195534Sscottl             (owner.kind == TYP && owner.isLocal()));
413195534Sscottl    }
414195534Sscottl
415203123Smav    /** Has this symbol an empty name? This includes anonymous
416199747Smav     *  inner classes.
417195534Sscottl     */
418195534Sscottl    public boolean isAnonymous() {
419203123Smav        return name.isEmpty();
420203873Smav    }
421195534Sscottl
422203123Smav    /** Is this symbol a constructor?
423195534Sscottl     */
424203123Smav    public boolean isConstructor() {
425220830Smav        return name == name.table.names.init;
426220565Smav    }
427198851Smav
428195534Sscottl    /** The fully qualified name of this symbol.
429195534Sscottl     *  This is the same as the symbol's name except for class symbols,
430220576Smav     *  which are handled separately.
431220789Smav     */
432220657Smav    public Name getQualifiedName() {
433224498Smav        return name;
434195534Sscottl    }
435196656Smav
436220576Smav    /** The fully qualified name of this symbol after converting to flat
437199747Smav     *  representation. This is the same as the symbol's name except for
438199747Smav     *  class symbols, which are handled separately.
439199747Smav     */
440195534Sscottl    public Name flatName() {
441195534Sscottl        return getQualifiedName();
442195534Sscottl    }
443195534Sscottl
444195534Sscottl    /** If this is a class or package, its members, otherwise null.
445249853Smav     */
446195534Sscottl    public WriteableScope members() {
447195534Sscottl        return null;
448195534Sscottl    }
449195534Sscottl
450195534Sscottl    /** A class is an inner class if it it has an enclosing instance class.
451195534Sscottl     */
452195534Sscottl    public boolean isInner() {
453195534Sscottl        return kind == TYP && type.getEnclosingType().hasTag(CLASS);
454195534Sscottl    }
455195534Sscottl
456195534Sscottl    /** An inner class has an outer instance if it is not an interface
457195534Sscottl     *  it has an enclosing instance class which might be referenced from the class.
458195534Sscottl     *  Nested classes can see instance members of their enclosing class.
459196656Smav     *  Their constructors carry an additional this$n parameter, inserted
460196656Smav     *  implicitly by the compiler.
461203108Smav     *
462222039Smav     *  @see #isInner
463199322Smav     */
464195534Sscottl    public boolean hasOuterInstance() {
465195534Sscottl        return
466195534Sscottl            type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
467196656Smav    }
468196656Smav
469195534Sscottl    /** The closest enclosing class of this symbol's declaration.
470195534Sscottl     *  Warning: this (misnamed) method returns the receiver itself
471195534Sscottl     *  when the receiver is a class (as opposed to its enclosing
472195534Sscottl     *  class as one may be misled to believe.)
473222039Smav     */
474195534Sscottl    public ClassSymbol enclClass() {
475195534Sscottl        Symbol c = this;
476195534Sscottl        while (c != null &&
477195534Sscottl               (!c.kind.matches(KindSelector.TYP) || !c.type.hasTag(CLASS))) {
478195534Sscottl            c = c.owner;
479195534Sscottl        }
480195534Sscottl        return (ClassSymbol)c;
481195534Sscottl    }
482195534Sscottl
483195534Sscottl    /** The outermost class which indirectly owns this symbol.
484195534Sscottl     */
485195534Sscottl    public ClassSymbol outermostClass() {
486195534Sscottl        Symbol sym = this;
487195534Sscottl        Symbol prev = null;
488195534Sscottl        while (sym.kind != PCK) {
489195534Sscottl            prev = sym;
490195534Sscottl            sym = sym.owner;
491195534Sscottl        }
492195534Sscottl        return (ClassSymbol) prev;
493195534Sscottl    }
494195534Sscottl
495195534Sscottl    /** The package which indirectly owns this symbol.
496195534Sscottl     */
497195534Sscottl    public PackageSymbol packge() {
498195534Sscottl        Symbol sym = this;
499195534Sscottl        while (sym.kind != PCK) {
500195534Sscottl            sym = sym.owner;
501195534Sscottl        }
502195534Sscottl        return (PackageSymbol) sym;
503195534Sscottl    }
504195534Sscottl
505195534Sscottl    /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
506195534Sscottl     */
507195534Sscottl    public boolean isSubClass(Symbol base, Types types) {
508195534Sscottl        throw new AssertionError("isSubClass " + this);
509195534Sscottl    }
510195534Sscottl
511195534Sscottl    /** Fully check membership: hierarchy, protection, and hiding.
512195534Sscottl     *  Does not exclude methods not inherited due to overriding.
513195534Sscottl     */
514195534Sscottl    public boolean isMemberOf(TypeSymbol clazz, Types types) {
515195534Sscottl        return
516            owner == clazz ||
517            clazz.isSubClass(owner, types) &&
518            isInheritedIn(clazz, types) &&
519            !hiddenIn((ClassSymbol)clazz, types);
520    }
521
522    /** Is this symbol the same as or enclosed by the given class? */
523    public boolean isEnclosedBy(ClassSymbol clazz) {
524        for (Symbol sym = this; sym.kind != PCK; sym = sym.owner)
525            if (sym == clazz) return true;
526        return false;
527    }
528
529    private boolean hiddenIn(ClassSymbol clazz, Types types) {
530        Symbol sym = hiddenInInternal(clazz, types);
531        Assert.check(sym != null, "the result of hiddenInInternal() can't be null");
532        /* If we find the current symbol then there is no symbol hiding it
533         */
534        return sym != this;
535    }
536
537    /** This method looks in the supertypes graph that has the current class as the
538     * initial node, till it finds the current symbol or another symbol that hides it.
539     * If the current class has more than one supertype (extends one class and
540     * implements one or more interfaces) then null can be returned, meaning that
541     * a wrong path in the supertypes graph was selected. Null can only be returned
542     * as a temporary value, as a result of the recursive call.
543     */
544    private Symbol hiddenInInternal(ClassSymbol currentClass, Types types) {
545        if (currentClass == owner) {
546            return this;
547        }
548        for (Symbol sym : currentClass.members().getSymbolsByName(name)) {
549            if (sym.kind == kind &&
550                    (kind != MTH ||
551                    (sym.flags() & STATIC) != 0 &&
552                    types.isSubSignature(sym.type, type))) {
553                return sym;
554            }
555        }
556        Symbol hiddenSym = null;
557        for (Type st : types.interfaces(currentClass.type)
558                .prepend(types.supertype(currentClass.type))) {
559            if (st != null && (st.hasTag(CLASS))) {
560                Symbol sym = hiddenInInternal((ClassSymbol)st.tsym, types);
561                if (sym == this) {
562                    return this;
563                } else if (sym != null) {
564                    hiddenSym = sym;
565                }
566            }
567        }
568        return hiddenSym;
569    }
570
571    /** Is this symbol inherited into a given class?
572     *  PRE: If symbol's owner is a interface,
573     *       it is already assumed that the interface is a superinterface
574     *       of given class.
575     *  @param clazz  The class for which we want to establish membership.
576     *                This must be a subclass of the member's owner.
577     */
578    public boolean isInheritedIn(Symbol clazz, Types types) {
579        switch ((int)(flags_field & Flags.AccessFlags)) {
580        default: // error recovery
581        case PUBLIC:
582            return true;
583        case PRIVATE:
584            return this.owner == clazz;
585        case PROTECTED:
586            // we model interfaces as extending Object
587            return (clazz.flags() & INTERFACE) == 0;
588        case 0:
589            PackageSymbol thisPackage = this.packge();
590            for (Symbol sup = clazz;
591                 sup != null && sup != this.owner;
592                 sup = types.supertype(sup.type).tsym) {
593                while (sup.type.hasTag(TYPEVAR))
594                    sup = sup.type.getUpperBound().tsym;
595                if (sup.type.isErroneous())
596                    return true; // error recovery
597                if ((sup.flags() & COMPOUND) != 0)
598                    continue;
599                if (sup.packge() != thisPackage)
600                    return false;
601            }
602            return (clazz.flags() & INTERFACE) == 0;
603        }
604    }
605
606    /** The (variable or method) symbol seen as a member of given
607     *  class type`site' (this might change the symbol's type).
608     *  This is used exclusively for producing diagnostics.
609     */
610    public Symbol asMemberOf(Type site, Types types) {
611        throw new AssertionError();
612    }
613
614    /** Does this method symbol override `other' symbol, when both are seen as
615     *  members of class `origin'?  It is assumed that _other is a member
616     *  of origin.
617     *
618     *  It is assumed that both symbols have the same name.  The static
619     *  modifier is ignored for this test.
620     *
621     *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
622     */
623    public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
624        return false;
625    }
626
627    /** Complete the elaboration of this symbol's definition.
628     */
629    public void complete() throws CompletionFailure {
630        if (completer != Completer.NULL_COMPLETER) {
631            Completer c = completer;
632            completer = Completer.NULL_COMPLETER;
633            c.complete(this);
634        }
635    }
636
637    /** True if the symbol represents an entity that exists.
638     */
639    public boolean exists() {
640        return true;
641    }
642
643    @DefinedBy(Api.LANGUAGE_MODEL)
644    public Type asType() {
645        return type;
646    }
647
648    @DefinedBy(Api.LANGUAGE_MODEL)
649    public Symbol getEnclosingElement() {
650        return owner;
651    }
652
653    @DefinedBy(Api.LANGUAGE_MODEL)
654    public ElementKind getKind() {
655        return ElementKind.OTHER;       // most unkind
656    }
657
658    @DefinedBy(Api.LANGUAGE_MODEL)
659    public Set<Modifier> getModifiers() {
660        return Flags.asModifierSet(flags());
661    }
662
663    @DefinedBy(Api.LANGUAGE_MODEL)
664    public Name getSimpleName() {
665        return name;
666    }
667
668    /**
669     * This is the implementation for {@code
670     * javax.lang.model.element.Element.getAnnotationMirrors()}.
671     */
672    @Override @DefinedBy(Api.LANGUAGE_MODEL)
673    public List<Attribute.Compound> getAnnotationMirrors() {
674        return getRawAttributes();
675    }
676
677
678    // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
679    @DefinedBy(Api.LANGUAGE_MODEL)
680    public java.util.List<Symbol> getEnclosedElements() {
681        return List.nil();
682    }
683
684    public List<TypeVariableSymbol> getTypeParameters() {
685        ListBuffer<TypeVariableSymbol> l = new ListBuffer<>();
686        for (Type t : type.getTypeArguments()) {
687            Assert.check(t.tsym.getKind() == ElementKind.TYPE_PARAMETER);
688            l.append((TypeVariableSymbol)t.tsym);
689        }
690        return l.toList();
691    }
692
693    public static class DelegatedSymbol<T extends Symbol> extends Symbol {
694        protected T other;
695        public DelegatedSymbol(T other) {
696            super(other.kind, other.flags_field, other.name, other.type, other.owner);
697            this.other = other;
698        }
699        public String toString() { return other.toString(); }
700        public Symbol location() { return other.location(); }
701        public Symbol location(Type site, Types types) { return other.location(site, types); }
702        public Symbol baseSymbol() { return other; }
703        public Type erasure(Types types) { return other.erasure(types); }
704        public Type externalType(Types types) { return other.externalType(types); }
705        public boolean isLocal() { return other.isLocal(); }
706        public boolean isConstructor() { return other.isConstructor(); }
707        public Name getQualifiedName() { return other.getQualifiedName(); }
708        public Name flatName() { return other.flatName(); }
709        public WriteableScope members() { return other.members(); }
710        public boolean isInner() { return other.isInner(); }
711        public boolean hasOuterInstance() { return other.hasOuterInstance(); }
712        public ClassSymbol enclClass() { return other.enclClass(); }
713        public ClassSymbol outermostClass() { return other.outermostClass(); }
714        public PackageSymbol packge() { return other.packge(); }
715        public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
716        public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
717        public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
718        public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
719        public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
720        public void complete() throws CompletionFailure { other.complete(); }
721
722        @DefinedBy(Api.LANGUAGE_MODEL)
723        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
724            return other.accept(v, p);
725        }
726
727        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
728            return v.visitSymbol(other, p);
729        }
730
731        public T getUnderlyingSymbol() {
732            return other;
733        }
734    }
735
736    /** A base class for Symbols representing types.
737     */
738    public static abstract class TypeSymbol extends Symbol {
739        public TypeSymbol(Kind kind, long flags, Name name, Type type, Symbol owner) {
740            super(kind, flags, name, type, owner);
741        }
742        /** form a fully qualified name from a name and an owner
743         */
744        static public Name formFullName(Name name, Symbol owner) {
745            if (owner == null) return name;
746            if ((owner.kind != ERR) &&
747                (owner.kind.matches(KindSelector.VAL_MTH) ||
748                 (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
749                 )) return name;
750            Name prefix = owner.getQualifiedName();
751            if (prefix == null || prefix == prefix.table.names.empty)
752                return name;
753            else return prefix.append('.', name);
754        }
755
756        /** form a fully qualified name from a name and an owner, after
757         *  converting to flat representation
758         */
759        static public Name formFlatName(Name name, Symbol owner) {
760            if (owner == null || owner.kind.matches(KindSelector.VAL_MTH) ||
761                (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
762                ) return name;
763            char sep = owner.kind == TYP ? '$' : '.';
764            Name prefix = owner.flatName();
765            if (prefix == null || prefix == prefix.table.names.empty)
766                return name;
767            else return prefix.append(sep, name);
768        }
769
770        /**
771         * A partial ordering between type symbols that refines the
772         * class inheritance graph.
773         *
774         * Type variables always precede other kinds of symbols.
775         */
776        public final boolean precedes(TypeSymbol that, Types types) {
777            if (this == that)
778                return false;
779            if (type.hasTag(that.type.getTag())) {
780                if (type.hasTag(CLASS)) {
781                    return
782                        types.rank(that.type) < types.rank(this.type) ||
783                        types.rank(that.type) == types.rank(this.type) &&
784                        that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
785                } else if (type.hasTag(TYPEVAR)) {
786                    return types.isSubtype(this.type, that.type);
787                }
788            }
789            return type.hasTag(TYPEVAR);
790        }
791
792        @Override @DefinedBy(Api.LANGUAGE_MODEL)
793        public java.util.List<Symbol> getEnclosedElements() {
794            List<Symbol> list = List.nil();
795            if (kind == TYP && type.hasTag(TYPEVAR)) {
796                return list;
797            }
798            for (Symbol sym : members().getSymbols(NON_RECURSIVE)) {
799                try {
800                    if (sym != null && (sym.flags() & SYNTHETIC) == 0 && sym.owner == this) {
801                        list = list.prepend(sym);
802                    }
803                } catch (BadEnclosingMethodAttr badEnclosingMethod) {
804                    // ignore the exception
805                }
806            }
807            return list;
808        }
809
810        public AnnotationTypeMetadata getAnnotationTypeMetadata() {
811            Assert.error("Only on ClassSymbol");
812            return null; //unreachable
813        }
814
815        public boolean isAnnotationType() { return false; }
816
817        @Override
818        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
819            return v.visitTypeSymbol(this, p);
820        }
821    }
822
823    /**
824     * Type variables are represented by instances of this class.
825     */
826    public static class TypeVariableSymbol
827            extends TypeSymbol implements TypeParameterElement {
828
829        public TypeVariableSymbol(long flags, Name name, Type type, Symbol owner) {
830            super(TYP, flags, name, type, owner);
831        }
832
833        @DefinedBy(Api.LANGUAGE_MODEL)
834        public ElementKind getKind() {
835            return ElementKind.TYPE_PARAMETER;
836        }
837
838        @Override @DefinedBy(Api.LANGUAGE_MODEL)
839        public Symbol getGenericElement() {
840            return owner;
841        }
842
843        @DefinedBy(Api.LANGUAGE_MODEL)
844        public List<Type> getBounds() {
845            TypeVar t = (TypeVar)type;
846            Type bound = t.getUpperBound();
847            if (!bound.isCompound())
848                return List.of(bound);
849            ClassType ct = (ClassType)bound;
850            if (!ct.tsym.erasure_field.isInterface()) {
851                return ct.interfaces_field.prepend(ct.supertype_field);
852            } else {
853                // No superclass was given in bounds.
854                // In this case, supertype is Object, erasure is first interface.
855                return ct.interfaces_field;
856            }
857        }
858
859        @Override @DefinedBy(Api.LANGUAGE_MODEL)
860        public List<Attribute.Compound> getAnnotationMirrors() {
861            // Declaration annotations on type variables are stored in type attributes
862            // on the owner of the TypeVariableSymbol
863            List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes();
864            int index = owner.getTypeParameters().indexOf(this);
865            List<Attribute.Compound> res = List.nil();
866            for (Attribute.TypeCompound a : candidates) {
867                if (isCurrentSymbolsAnnotation(a, index))
868                    res = res.prepend(a);
869            }
870
871            return res.reverse();
872        }
873
874        // Helper to getAnnotation[s]
875        @Override
876        public <A extends Annotation> Attribute.Compound getAttribute(Class<A> annoType) {
877            String name = annoType.getName();
878
879            // Declaration annotations on type variables are stored in type attributes
880            // on the owner of the TypeVariableSymbol
881            List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes();
882            int index = owner.getTypeParameters().indexOf(this);
883            for (Attribute.TypeCompound anno : candidates)
884                if (isCurrentSymbolsAnnotation(anno, index) &&
885                    name.contentEquals(anno.type.tsym.flatName()))
886                    return anno;
887
888            return null;
889        }
890            //where:
891            boolean isCurrentSymbolsAnnotation(Attribute.TypeCompound anno, int index) {
892                return (anno.position.type == TargetType.CLASS_TYPE_PARAMETER ||
893                        anno.position.type == TargetType.METHOD_TYPE_PARAMETER) &&
894                        anno.position.parameter_index == index;
895            }
896
897
898        @Override @DefinedBy(Api.LANGUAGE_MODEL)
899        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
900            return v.visitTypeParameter(this, p);
901        }
902    }
903    /** A class for module symbols.
904     */
905    public static class ModuleSymbol extends TypeSymbol
906            implements ModuleElement {
907
908        public Name version;
909        public JavaFileManager.Location sourceLocation;
910        public JavaFileManager.Location classLocation;
911        public JavaFileManager.Location patchLocation;
912        public JavaFileManager.Location patchOutputLocation;
913
914        /** All directives, in natural order. */
915        public List<com.sun.tools.javac.code.Directive> directives;
916        public List<com.sun.tools.javac.code.Directive.RequiresDirective> requires;
917        public List<com.sun.tools.javac.code.Directive.ExportsDirective> exports;
918        public List<com.sun.tools.javac.code.Directive.OpensDirective> opens;
919        public List<com.sun.tools.javac.code.Directive.ProvidesDirective> provides;
920        public List<com.sun.tools.javac.code.Directive.UsesDirective> uses;
921
922        public ClassSymbol module_info;
923
924        public PackageSymbol unnamedPackage;
925        public Map<Name, PackageSymbol> visiblePackages;
926        public Set<ModuleSymbol> readModules;
927        public List<Symbol> enclosedPackages = List.nil();
928
929        public Completer usesProvidesCompleter = Completer.NULL_COMPLETER;
930        public final Set<ModuleFlags> flags = EnumSet.noneOf(ModuleFlags.class);
931        public final Set<ModuleResolutionFlags> resolutionFlags = EnumSet.noneOf(ModuleResolutionFlags.class);
932
933        /**
934         * Create a ModuleSymbol with an associated module-info ClassSymbol.
935         */
936        public static ModuleSymbol create(Name name, Name module_info) {
937            ModuleSymbol msym = new ModuleSymbol(name, null);
938            ClassSymbol info = new ClassSymbol(Flags.MODULE, module_info, msym);
939            info.fullname = formFullName(module_info, msym);
940            info.flatname = info.fullname;
941            info.members_field = WriteableScope.create(info);
942            msym.module_info = info;
943            return msym;
944        }
945
946        public ModuleSymbol(Name name, Symbol owner) {
947            super(MDL, 0, name, null, owner);
948            Assert.checkNonNull(name);
949            this.type = new ModuleType(this);
950        }
951
952        @Override @DefinedBy(Api.LANGUAGE_MODEL)
953        public boolean isOpen() {
954            return flags.contains(ModuleFlags.OPEN);
955        }
956
957        @Override @DefinedBy(Api.LANGUAGE_MODEL)
958        public boolean isUnnamed() {
959            return name.isEmpty() && owner == null;
960        }
961
962        @Override
963        public boolean isDeprecated() {
964            return hasDeprecatedAnnotation();
965        }
966
967        public boolean isNoModule() {
968            return false;
969        }
970
971        @Override @DefinedBy(Api.LANGUAGE_MODEL)
972        public ElementKind getKind() {
973            return ElementKind.MODULE;
974        }
975
976        @Override @DefinedBy(Api.LANGUAGE_MODEL)
977        public java.util.List<Directive> getDirectives() {
978            complete();
979            completeUsesProvides();
980            return Collections.unmodifiableList(directives);
981        }
982
983        public void completeUsesProvides() {
984            if (usesProvidesCompleter != Completer.NULL_COMPLETER) {
985                Completer c = usesProvidesCompleter;
986                usesProvidesCompleter = Completer.NULL_COMPLETER;
987                c.complete(this);
988            }
989        }
990
991        @Override
992        public ClassSymbol outermostClass() {
993            return null;
994        }
995
996        @Override
997        public String toString() {
998            // TODO: the following strings should be localized
999            // Do this with custom anon subtypes in Symtab
1000            String n = (name == null) ? "<unknown>"
1001                    : (name.isEmpty()) ? "<unnamed>"
1002                    : String.valueOf(name);
1003            return n;
1004        }
1005
1006        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1007        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1008            return v.visitModule(this, p);
1009        }
1010
1011        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1012        public List<Symbol> getEnclosedElements() {
1013            List<Symbol> list = List.nil();
1014            for (Symbol sym : enclosedPackages) {
1015                if (sym.members().anyMatch(m -> m.kind == TYP))
1016                    list = list.prepend(sym);
1017            }
1018            return list;
1019        }
1020
1021        public void reset() {
1022            this.directives = null;
1023            this.requires = null;
1024            this.exports = null;
1025            this.provides = null;
1026            this.uses = null;
1027            this.visiblePackages = null;
1028        }
1029
1030    }
1031
1032    public enum ModuleFlags {
1033        OPEN(0x0020),
1034        SYNTHETIC(0x1000),
1035        MANDATED(0x8000);
1036
1037        public static int value(Set<ModuleFlags> s) {
1038            int v = 0;
1039            for (ModuleFlags f: s)
1040                v |= f.value;
1041            return v;
1042        }
1043
1044        private ModuleFlags(int value) {
1045            this.value = value;
1046        }
1047
1048        public final int value;
1049    }
1050
1051    public enum ModuleResolutionFlags {
1052        DO_NOT_RESOLVE_BY_DEFAULT(0x0001),
1053        WARN_DEPRECATED(0x0002),
1054        WARN_DEPRECATED_REMOVAL(0x0004),
1055        WARN_INCUBATING(0x0008);
1056
1057        public static int value(Set<ModuleResolutionFlags> s) {
1058            int v = 0;
1059            for (ModuleResolutionFlags f: s)
1060                v |= f.value;
1061            return v;
1062        }
1063
1064        private ModuleResolutionFlags(int value) {
1065            this.value = value;
1066        }
1067
1068        public final int value;
1069    }
1070
1071    /** A class for package symbols
1072     */
1073    public static class PackageSymbol extends TypeSymbol
1074        implements PackageElement {
1075
1076        public WriteableScope members_field;
1077        public Name fullname;
1078        public ClassSymbol package_info; // see bug 6443073
1079        public ModuleSymbol modle;
1080        // the file containing the documentation comments for the package
1081        public JavaFileObject sourcefile;
1082
1083        public PackageSymbol(Name name, Type type, Symbol owner) {
1084            super(PCK, 0, name, type, owner);
1085            this.members_field = null;
1086            this.fullname = formFullName(name, owner);
1087        }
1088
1089        public PackageSymbol(Name name, Symbol owner) {
1090            this(name, null, owner);
1091            this.type = new PackageType(this);
1092        }
1093
1094        public String toString() {
1095            return fullname.toString();
1096        }
1097
1098        @DefinedBy(Api.LANGUAGE_MODEL)
1099        public Name getQualifiedName() {
1100            return fullname;
1101        }
1102
1103        @DefinedBy(Api.LANGUAGE_MODEL)
1104        public boolean isUnnamed() {
1105            return name.isEmpty() && owner != null;
1106        }
1107
1108        public WriteableScope members() {
1109            complete();
1110            return members_field;
1111        }
1112
1113        public long flags() {
1114            complete();
1115            return flags_field;
1116        }
1117
1118        @Override
1119        public List<Attribute.Compound> getRawAttributes() {
1120            complete();
1121            if (package_info != null) {
1122                package_info.complete();
1123                mergeAttributes();
1124            }
1125            return super.getRawAttributes();
1126        }
1127
1128        private void mergeAttributes() {
1129            if (metadata == null &&
1130                package_info.metadata != null) {
1131                metadata = new SymbolMetadata(this);
1132                metadata.setAttributes(package_info.metadata);
1133            }
1134        }
1135
1136        /** A package "exists" if a type or package that exists has
1137         *  been seen within it.
1138         */
1139        public boolean exists() {
1140            return (flags_field & EXISTS) != 0;
1141        }
1142
1143        @DefinedBy(Api.LANGUAGE_MODEL)
1144        public ElementKind getKind() {
1145            return ElementKind.PACKAGE;
1146        }
1147
1148        @DefinedBy(Api.LANGUAGE_MODEL)
1149        public Symbol getEnclosingElement() {
1150            return modle != null && !modle.isNoModule() ? modle : null;
1151        }
1152
1153        @DefinedBy(Api.LANGUAGE_MODEL)
1154        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1155            return v.visitPackage(this, p);
1156        }
1157
1158        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1159            return v.visitPackageSymbol(this, p);
1160        }
1161
1162        /**Resets the Symbol into the state good for next round of annotation processing.*/
1163        public void reset() {
1164            metadata = null;
1165        }
1166
1167    }
1168
1169    /** A class for class symbols
1170     */
1171    public static class ClassSymbol extends TypeSymbol implements TypeElement {
1172
1173        /** a scope for all class members; variables, methods and inner classes
1174         *  type parameters are not part of this scope
1175         */
1176        public WriteableScope members_field;
1177
1178        /** the fully qualified name of the class, i.e. pck.outer.inner.
1179         *  null for anonymous classes
1180         */
1181        public Name fullname;
1182
1183        /** the fully qualified name of the class after converting to flat
1184         *  representation, i.e. pck.outer$inner,
1185         *  set externally for local and anonymous classes
1186         */
1187        public Name flatname;
1188
1189        /** the sourcefile where the class came from
1190         */
1191        public JavaFileObject sourcefile;
1192
1193        /** the classfile from where to load this class
1194         *  this will have extension .class or .java
1195         */
1196        public JavaFileObject classfile;
1197
1198        /** the list of translated local classes (used for generating
1199         * InnerClasses attribute)
1200         */
1201        public List<ClassSymbol> trans_local;
1202
1203        /** the constant pool of the class
1204         */
1205        public Pool pool;
1206
1207        /** the annotation metadata attached to this class */
1208        private AnnotationTypeMetadata annotationTypeMetadata;
1209
1210        public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
1211            super(TYP, flags, name, type, owner);
1212            this.members_field = null;
1213            this.fullname = formFullName(name, owner);
1214            this.flatname = formFlatName(name, owner);
1215            this.sourcefile = null;
1216            this.classfile = null;
1217            this.pool = null;
1218            this.annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1219        }
1220
1221        public ClassSymbol(long flags, Name name, Symbol owner) {
1222            this(
1223                flags,
1224                name,
1225                new ClassType(Type.noType, null, null),
1226                owner);
1227            this.type.tsym = this;
1228        }
1229
1230        /** The Java source which this symbol represents.
1231         */
1232        public String toString() {
1233            return className();
1234        }
1235
1236        public long flags() {
1237            complete();
1238            return flags_field;
1239        }
1240
1241        public WriteableScope members() {
1242            complete();
1243            return members_field;
1244        }
1245
1246        @Override
1247        public List<Attribute.Compound> getRawAttributes() {
1248            complete();
1249            return super.getRawAttributes();
1250        }
1251
1252        @Override
1253        public List<Attribute.TypeCompound> getRawTypeAttributes() {
1254            complete();
1255            return super.getRawTypeAttributes();
1256        }
1257
1258        public Type erasure(Types types) {
1259            if (erasure_field == null)
1260                erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
1261                                              List.nil(), this,
1262                                              type.getMetadata());
1263            return erasure_field;
1264        }
1265
1266        public String className() {
1267            if (name.isEmpty())
1268                return
1269                    Log.getLocalizedString("anonymous.class", flatname);
1270            else
1271                return fullname.toString();
1272        }
1273
1274        @DefinedBy(Api.LANGUAGE_MODEL)
1275        public Name getQualifiedName() {
1276            return fullname;
1277        }
1278
1279        public Name flatName() {
1280            return flatname;
1281        }
1282
1283        public boolean isSubClass(Symbol base, Types types) {
1284            if (this == base) {
1285                return true;
1286            } else if ((base.flags() & INTERFACE) != 0) {
1287                for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1288                    for (List<Type> is = types.interfaces(t);
1289                         is.nonEmpty();
1290                         is = is.tail)
1291                        if (is.head.tsym.isSubClass(base, types)) return true;
1292            } else {
1293                for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1294                    if (t.tsym == base) return true;
1295            }
1296            return false;
1297        }
1298
1299        /** Complete the elaboration of this symbol's definition.
1300         */
1301        public void complete() throws CompletionFailure {
1302            try {
1303                super.complete();
1304            } catch (CompletionFailure ex) {
1305                // quiet error recovery
1306                flags_field |= (PUBLIC|STATIC);
1307                this.type = new ErrorType(this, Type.noType);
1308                throw ex;
1309            }
1310        }
1311
1312        @DefinedBy(Api.LANGUAGE_MODEL)
1313        public List<Type> getInterfaces() {
1314            complete();
1315            if (type instanceof ClassType) {
1316                ClassType t = (ClassType)type;
1317                if (t.interfaces_field == null) // FIXME: shouldn't be null
1318                    t.interfaces_field = List.nil();
1319                if (t.all_interfaces_field != null)
1320                    return Type.getModelTypes(t.all_interfaces_field);
1321                return t.interfaces_field;
1322            } else {
1323                return List.nil();
1324            }
1325        }
1326
1327        @DefinedBy(Api.LANGUAGE_MODEL)
1328        public Type getSuperclass() {
1329            complete();
1330            if (type instanceof ClassType) {
1331                ClassType t = (ClassType)type;
1332                if (t.supertype_field == null) // FIXME: shouldn't be null
1333                    t.supertype_field = Type.noType;
1334                // An interface has no superclass; its supertype is Object.
1335                return t.isInterface()
1336                    ? Type.noType
1337                    : t.supertype_field.getModelType();
1338            } else {
1339                return Type.noType;
1340            }
1341        }
1342
1343        /**
1344         * Returns the next class to search for inherited annotations or {@code null}
1345         * if the next class can't be found.
1346         */
1347        private ClassSymbol getSuperClassToSearchForAnnotations() {
1348
1349            Type sup = getSuperclass();
1350
1351            if (!sup.hasTag(CLASS) || sup.isErroneous())
1352                return null;
1353
1354            return (ClassSymbol) sup.tsym;
1355        }
1356
1357
1358        @Override
1359        protected <A extends Annotation> A[] getInheritedAnnotations(Class<A> annoType) {
1360
1361            ClassSymbol sup = getSuperClassToSearchForAnnotations();
1362
1363            return sup == null ? super.getInheritedAnnotations(annoType)
1364                               : sup.getAnnotationsByType(annoType);
1365        }
1366
1367
1368        @DefinedBy(Api.LANGUAGE_MODEL)
1369        public ElementKind getKind() {
1370            long flags = flags();
1371            if ((flags & ANNOTATION) != 0)
1372                return ElementKind.ANNOTATION_TYPE;
1373            else if ((flags & INTERFACE) != 0)
1374                return ElementKind.INTERFACE;
1375            else if ((flags & ENUM) != 0)
1376                return ElementKind.ENUM;
1377            else
1378                return ElementKind.CLASS;
1379        }
1380
1381        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1382        public Set<Modifier> getModifiers() {
1383            long flags = flags();
1384            return Flags.asModifierSet(flags & ~DEFAULT);
1385        }
1386
1387        @DefinedBy(Api.LANGUAGE_MODEL)
1388        public NestingKind getNestingKind() {
1389            complete();
1390            if (owner.kind == PCK)
1391                return NestingKind.TOP_LEVEL;
1392            else if (name.isEmpty())
1393                return NestingKind.ANONYMOUS;
1394            else if (owner.kind == MTH)
1395                return NestingKind.LOCAL;
1396            else
1397                return NestingKind.MEMBER;
1398        }
1399
1400
1401        @Override
1402        protected <A extends Annotation> Attribute.Compound getAttribute(final Class<A> annoType) {
1403
1404            Attribute.Compound attrib = super.getAttribute(annoType);
1405
1406            boolean inherited = annoType.isAnnotationPresent(Inherited.class);
1407            if (attrib != null || !inherited)
1408                return attrib;
1409
1410            // Search supertypes
1411            ClassSymbol superType = getSuperClassToSearchForAnnotations();
1412            return superType == null ? null
1413                                     : superType.getAttribute(annoType);
1414        }
1415
1416
1417
1418
1419        @DefinedBy(Api.LANGUAGE_MODEL)
1420        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1421            return v.visitType(this, p);
1422        }
1423
1424        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1425            return v.visitClassSymbol(this, p);
1426        }
1427
1428        public void markAbstractIfNeeded(Types types) {
1429            if (types.enter.getEnv(this) != null &&
1430                (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym &&
1431                (flags() & (FINAL | ABSTRACT)) == 0) {
1432                if (types.firstUnimplementedAbstract(this) != null)
1433                    // add the ABSTRACT flag to an enum
1434                    flags_field |= ABSTRACT;
1435            }
1436        }
1437
1438        /**Resets the Symbol into the state good for next round of annotation processing.*/
1439        public void reset() {
1440            kind = TYP;
1441            erasure_field = null;
1442            members_field = null;
1443            flags_field = 0;
1444            if (type instanceof ClassType) {
1445                ClassType t = (ClassType)type;
1446                t.setEnclosingType(Type.noType);
1447                t.rank_field = -1;
1448                t.typarams_field = null;
1449                t.allparams_field = null;
1450                t.supertype_field = null;
1451                t.interfaces_field = null;
1452                t.all_interfaces_field = null;
1453            }
1454            clearAnnotationMetadata();
1455        }
1456
1457        public void clearAnnotationMetadata() {
1458            metadata = null;
1459            annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1460        }
1461
1462        @Override
1463        public AnnotationTypeMetadata getAnnotationTypeMetadata() {
1464            return annotationTypeMetadata;
1465        }
1466
1467        @Override
1468        public boolean isAnnotationType() {
1469            return (flags_field & Flags.ANNOTATION) != 0;
1470        }
1471
1472        public void setAnnotationTypeMetadata(AnnotationTypeMetadata a) {
1473            Assert.checkNonNull(a);
1474            Assert.check(!annotationTypeMetadata.isMetadataForAnnotationType());
1475            this.annotationTypeMetadata = a;
1476        }
1477    }
1478
1479
1480    /** A class for variable symbols
1481     */
1482    public static class VarSymbol extends Symbol implements VariableElement {
1483
1484        /** The variable's declaration position.
1485         */
1486        public int pos = Position.NOPOS;
1487
1488        /** The variable's address. Used for different purposes during
1489         *  flow analysis, translation and code generation.
1490         *  Flow analysis:
1491         *    If this is a blank final or local variable, its sequence number.
1492         *  Translation:
1493         *    If this is a private field, its access number.
1494         *  Code generation:
1495         *    If this is a local variable, its logical slot number.
1496         */
1497        public int adr = -1;
1498
1499        /** Construct a variable symbol, given its flags, name, type and owner.
1500         */
1501        public VarSymbol(long flags, Name name, Type type, Symbol owner) {
1502            super(VAR, flags, name, type, owner);
1503        }
1504
1505        /** Clone this symbol with new owner.
1506         */
1507        public VarSymbol clone(Symbol newOwner) {
1508            VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) {
1509                @Override
1510                public Symbol baseSymbol() {
1511                    return VarSymbol.this;
1512                }
1513            };
1514            v.pos = pos;
1515            v.adr = adr;
1516            v.data = data;
1517//          System.out.println("clone " + v + " in " + newOwner);//DEBUG
1518            return v;
1519        }
1520
1521        public String toString() {
1522            return name.toString();
1523        }
1524
1525        public Symbol asMemberOf(Type site, Types types) {
1526            return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
1527        }
1528
1529        @DefinedBy(Api.LANGUAGE_MODEL)
1530        public ElementKind getKind() {
1531            long flags = flags();
1532            if ((flags & PARAMETER) != 0) {
1533                if (isExceptionParameter())
1534                    return ElementKind.EXCEPTION_PARAMETER;
1535                else
1536                    return ElementKind.PARAMETER;
1537            } else if ((flags & ENUM) != 0) {
1538                return ElementKind.ENUM_CONSTANT;
1539            } else if (owner.kind == TYP || owner.kind == ERR) {
1540                return ElementKind.FIELD;
1541            } else if (isResourceVariable()) {
1542                return ElementKind.RESOURCE_VARIABLE;
1543            } else {
1544                return ElementKind.LOCAL_VARIABLE;
1545            }
1546        }
1547
1548        @DefinedBy(Api.LANGUAGE_MODEL)
1549        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1550            return v.visitVariable(this, p);
1551        }
1552
1553        @DefinedBy(Api.LANGUAGE_MODEL)
1554        public Object getConstantValue() { // Mirror API
1555            return Constants.decode(getConstValue(), type);
1556        }
1557
1558        public void setLazyConstValue(final Env<AttrContext> env,
1559                                      final Attr attr,
1560                                      final JCVariableDecl variable)
1561        {
1562            setData((Callable<Object>)() -> attr.attribLazyConstantValue(env, variable, type));
1563        }
1564
1565        /**
1566         * The variable's constant value, if this is a constant.
1567         * Before the constant value is evaluated, it points to an
1568         * initializer environment.  If this is not a constant, it can
1569         * be used for other stuff.
1570         */
1571        private Object data;
1572
1573        public boolean isExceptionParameter() {
1574            return data == ElementKind.EXCEPTION_PARAMETER;
1575        }
1576
1577        public boolean isResourceVariable() {
1578            return data == ElementKind.RESOURCE_VARIABLE;
1579        }
1580
1581        public Object getConstValue() {
1582            // TODO: Consider if getConstValue and getConstantValue can be collapsed
1583            if (data == ElementKind.EXCEPTION_PARAMETER ||
1584                data == ElementKind.RESOURCE_VARIABLE) {
1585                return null;
1586            } else if (data instanceof Callable<?>) {
1587                // In this case, this is a final variable, with an as
1588                // yet unevaluated initializer.
1589                Callable<?> eval = (Callable<?>)data;
1590                data = null; // to make sure we don't evaluate this twice.
1591                try {
1592                    data = eval.call();
1593                } catch (Exception ex) {
1594                    throw new AssertionError(ex);
1595                }
1596            }
1597            return data;
1598        }
1599
1600        public void setData(Object data) {
1601            Assert.check(!(data instanceof Env<?>), this);
1602            this.data = data;
1603        }
1604
1605        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1606            return v.visitVarSymbol(this, p);
1607        }
1608    }
1609
1610    /** A class for method symbols.
1611     */
1612    public static class MethodSymbol extends Symbol implements ExecutableElement {
1613
1614        /** The code of the method. */
1615        public Code code = null;
1616
1617        /** The extra (synthetic/mandated) parameters of the method. */
1618        public List<VarSymbol> extraParams = List.nil();
1619
1620        /** The captured local variables in an anonymous class */
1621        public List<VarSymbol> capturedLocals = List.nil();
1622
1623        /** The parameters of the method. */
1624        public List<VarSymbol> params = null;
1625
1626        /** The names of the parameters */
1627        public List<Name> savedParameterNames;
1628
1629        /** For an annotation type element, its default value if any.
1630         *  The value is null if none appeared in the method
1631         *  declaration.
1632         */
1633        public Attribute defaultValue = null;
1634
1635        /** Construct a method symbol, given its flags, name, type and owner.
1636         */
1637        public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1638            super(MTH, flags, name, type, owner);
1639            if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name);
1640        }
1641
1642        /** Clone this symbol with new owner.
1643         */
1644        public MethodSymbol clone(Symbol newOwner) {
1645            MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) {
1646                @Override
1647                public Symbol baseSymbol() {
1648                    return MethodSymbol.this;
1649                }
1650            };
1651            m.code = code;
1652            return m;
1653        }
1654
1655        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1656        public Set<Modifier> getModifiers() {
1657            long flags = flags();
1658            return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags);
1659        }
1660
1661        /** The Java source which this symbol represents.
1662         */
1663        public String toString() {
1664            if ((flags() & BLOCK) != 0) {
1665                return owner.name.toString();
1666            } else {
1667                String s = (name == name.table.names.init)
1668                    ? owner.name.toString()
1669                    : name.toString();
1670                if (type != null) {
1671                    if (type.hasTag(FORALL))
1672                        s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1673                    s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1674                }
1675                return s;
1676            }
1677        }
1678
1679        public boolean isDynamic() {
1680            return false;
1681        }
1682
1683        /** find a symbol that this (proxy method) symbol implements.
1684         *  @param    c       The class whose members are searched for
1685         *                    implementations
1686         */
1687        public Symbol implemented(TypeSymbol c, Types types) {
1688            Symbol impl = null;
1689            for (List<Type> is = types.interfaces(c.type);
1690                 impl == null && is.nonEmpty();
1691                 is = is.tail) {
1692                TypeSymbol i = is.head.tsym;
1693                impl = implementedIn(i, types);
1694                if (impl == null)
1695                    impl = implemented(i, types);
1696            }
1697            return impl;
1698        }
1699
1700        public Symbol implementedIn(TypeSymbol c, Types types) {
1701            Symbol impl = null;
1702            for (Symbol sym : c.members().getSymbolsByName(name)) {
1703                if (this.overrides(sym, (TypeSymbol)owner, types, true) &&
1704                    // FIXME: I suspect the following requires a
1705                    // subst() for a parametric return type.
1706                    types.isSameType(type.getReturnType(),
1707                                     types.memberType(owner.type, sym).getReturnType())) {
1708                    impl = sym;
1709                }
1710            }
1711            return impl;
1712        }
1713
1714        /** Will the erasure of this method be considered by the VM to
1715         *  override the erasure of the other when seen from class `origin'?
1716         */
1717        public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1718            if (isConstructor() || _other.kind != MTH) return false;
1719
1720            if (this == _other) return true;
1721            MethodSymbol other = (MethodSymbol)_other;
1722
1723            // check for a direct implementation
1724            if (other.isOverridableIn((TypeSymbol)owner) &&
1725                types.asSuper(owner.type, other.owner) != null &&
1726                types.isSameType(erasure(types), other.erasure(types)))
1727                return true;
1728
1729            // check for an inherited implementation
1730            return
1731                (flags() & ABSTRACT) == 0 &&
1732                other.isOverridableIn(origin) &&
1733                this.isMemberOf(origin, types) &&
1734                types.isSameType(erasure(types), other.erasure(types));
1735        }
1736
1737        /** The implementation of this (abstract) symbol in class origin,
1738         *  from the VM's point of view, null if method does not have an
1739         *  implementation in class.
1740         *  @param origin   The class of which the implementation is a member.
1741         */
1742        public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1743            for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1744                for (Symbol sym : c.members().getSymbolsByName(name)) {
1745                    if (sym.kind == MTH &&
1746                        ((MethodSymbol)sym).binaryOverrides(this, origin, types))
1747                        return (MethodSymbol)sym;
1748                }
1749            }
1750            return null;
1751        }
1752
1753        /** Does this symbol override `other' symbol, when both are seen as
1754         *  members of class `origin'?  It is assumed that _other is a member
1755         *  of origin.
1756         *
1757         *  It is assumed that both symbols have the same name.  The static
1758         *  modifier is ignored for this test.
1759         *
1760         *  A quirk in the works is that if the receiver is a method symbol for
1761         *  an inherited abstract method we answer false summarily all else being
1762         *  immaterial. Abstract "own" methods (i.e `this' is a direct member of
1763         *  origin) don't get rejected as summarily and are put to test against the
1764         *  suitable criteria.
1765         *
1766         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1767         */
1768        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1769            return overrides(_other, origin, types, checkResult, true);
1770        }
1771
1772        /** Does this symbol override `other' symbol, when both are seen as
1773         *  members of class `origin'?  It is assumed that _other is a member
1774         *  of origin.
1775         *
1776         *  Caveat: If `this' is an abstract inherited member of origin, it is
1777         *  deemed to override `other' only when `requireConcreteIfInherited'
1778         *  is false.
1779         *
1780         *  It is assumed that both symbols have the same name.  The static
1781         *  modifier is ignored for this test.
1782         *
1783         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1784         */
1785        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult,
1786                                            boolean requireConcreteIfInherited) {
1787            if (isConstructor() || _other.kind != MTH) return false;
1788
1789            if (this == _other) return true;
1790            MethodSymbol other = (MethodSymbol)_other;
1791
1792            // check for a direct implementation
1793            if (other.isOverridableIn((TypeSymbol)owner) &&
1794                types.asSuper(owner.type, other.owner) != null) {
1795                Type mt = types.memberType(owner.type, this);
1796                Type ot = types.memberType(owner.type, other);
1797                if (types.isSubSignature(mt, ot)) {
1798                    if (!checkResult)
1799                        return true;
1800                    if (types.returnTypeSubstitutable(mt, ot))
1801                        return true;
1802                }
1803            }
1804
1805            // check for an inherited implementation
1806            if (((flags() & ABSTRACT) != 0 && requireConcreteIfInherited) ||
1807                    ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
1808                    !other.isOverridableIn(origin) ||
1809                    !this.isMemberOf(origin, types))
1810                return false;
1811
1812            // assert types.asSuper(origin.type, other.owner) != null;
1813            Type mt = types.memberType(origin.type, this);
1814            Type ot = types.memberType(origin.type, other);
1815            return
1816                types.isSubSignature(mt, ot) &&
1817                (!checkResult || types.resultSubtype(mt, ot, types.noWarnings));
1818        }
1819
1820        private boolean isOverridableIn(TypeSymbol origin) {
1821            // JLS 8.4.6.1
1822            switch ((int)(flags_field & Flags.AccessFlags)) {
1823            case Flags.PRIVATE:
1824                return false;
1825            case Flags.PUBLIC:
1826                return !this.owner.isInterface() ||
1827                        (flags_field & STATIC) == 0;
1828            case Flags.PROTECTED:
1829                return (origin.flags() & INTERFACE) == 0;
1830            case 0:
1831                // for package private: can only override in the same
1832                // package
1833                return
1834                    this.packge() == origin.packge() &&
1835                    (origin.flags() & INTERFACE) == 0;
1836            default:
1837                return false;
1838            }
1839        }
1840
1841        @Override
1842        public boolean isInheritedIn(Symbol clazz, Types types) {
1843            switch ((int)(flags_field & Flags.AccessFlags)) {
1844                case PUBLIC:
1845                    return !this.owner.isInterface() ||
1846                            clazz == owner ||
1847                            (flags_field & STATIC) == 0;
1848                default:
1849                    return super.isInheritedIn(clazz, types);
1850            }
1851        }
1852
1853        public boolean isLambdaMethod() {
1854            return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD;
1855        }
1856
1857        /** The implementation of this (abstract) symbol in class origin;
1858         *  null if none exists. Synthetic methods are not considered
1859         *  as possible implementations.
1860         */
1861        public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1862            return implementation(origin, types, checkResult, implementation_filter);
1863        }
1864        // where
1865            public static final Filter<Symbol> implementation_filter = s ->
1866                    s.kind == MTH && (s.flags() & SYNTHETIC) == 0;
1867
1868        public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
1869            MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
1870            if (res != null)
1871                return res;
1872            // if origin is derived from a raw type, we might have missed
1873            // an implementation because we do not know enough about instantiations.
1874            // in this case continue with the supertype as origin.
1875            if (types.isDerivedRaw(origin.type) && !origin.isInterface())
1876                return implementation(types.supertype(origin.type).tsym, types, checkResult);
1877            else
1878                return null;
1879        }
1880
1881        public List<VarSymbol> params() {
1882            owner.complete();
1883            if (params == null) {
1884                // If ClassReader.saveParameterNames has been set true, then
1885                // savedParameterNames will be set to a list of names that
1886                // matches the types in type.getParameterTypes().  If any names
1887                // were not found in the class file, those names in the list will
1888                // be set to the empty name.
1889                // If ClassReader.saveParameterNames has been set false, then
1890                // savedParameterNames will be null.
1891                List<Name> paramNames = savedParameterNames;
1892                savedParameterNames = null;
1893                // discard the provided names if the list of names is the wrong size.
1894                if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) {
1895                    paramNames = List.nil();
1896                }
1897                ListBuffer<VarSymbol> buf = new ListBuffer<>();
1898                List<Name> remaining = paramNames;
1899                // assert: remaining and paramNames are both empty or both
1900                // have same cardinality as type.getParameterTypes()
1901                int i = 0;
1902                for (Type t : type.getParameterTypes()) {
1903                    Name paramName;
1904                    if (remaining.isEmpty()) {
1905                        // no names for any parameters available
1906                        paramName = createArgName(i, paramNames);
1907                    } else {
1908                        paramName = remaining.head;
1909                        remaining = remaining.tail;
1910                        if (paramName.isEmpty()) {
1911                            // no name for this specific parameter
1912                            paramName = createArgName(i, paramNames);
1913                        }
1914                    }
1915                    buf.append(new VarSymbol(PARAMETER, paramName, t, this));
1916                    i++;
1917                }
1918                params = buf.toList();
1919            }
1920            return params;
1921        }
1922
1923        // Create a name for the argument at position 'index' that is not in
1924        // the exclude list. In normal use, either no names will have been
1925        // provided, in which case the exclude list is empty, or all the names
1926        // will have been provided, in which case this method will not be called.
1927        private Name createArgName(int index, List<Name> exclude) {
1928            String prefix = "arg";
1929            while (true) {
1930                Name argName = name.table.fromString(prefix + index);
1931                if (!exclude.contains(argName))
1932                    return argName;
1933                prefix += "$";
1934            }
1935        }
1936
1937        public Symbol asMemberOf(Type site, Types types) {
1938            return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1939        }
1940
1941        @DefinedBy(Api.LANGUAGE_MODEL)
1942        public ElementKind getKind() {
1943            if (name == name.table.names.init)
1944                return ElementKind.CONSTRUCTOR;
1945            else if (name == name.table.names.clinit)
1946                return ElementKind.STATIC_INIT;
1947            else if ((flags() & BLOCK) != 0)
1948                return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT;
1949            else
1950                return ElementKind.METHOD;
1951        }
1952
1953        public boolean isStaticOrInstanceInit() {
1954            return getKind() == ElementKind.STATIC_INIT ||
1955                    getKind() == ElementKind.INSTANCE_INIT;
1956        }
1957
1958        @DefinedBy(Api.LANGUAGE_MODEL)
1959        public Attribute getDefaultValue() {
1960            return defaultValue;
1961        }
1962
1963        @DefinedBy(Api.LANGUAGE_MODEL)
1964        public List<VarSymbol> getParameters() {
1965            return params();
1966        }
1967
1968        @DefinedBy(Api.LANGUAGE_MODEL)
1969        public boolean isVarArgs() {
1970            return (flags() & VARARGS) != 0;
1971        }
1972
1973        @DefinedBy(Api.LANGUAGE_MODEL)
1974        public boolean isDefault() {
1975            return (flags() & DEFAULT) != 0;
1976        }
1977
1978        @DefinedBy(Api.LANGUAGE_MODEL)
1979        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1980            return v.visitExecutable(this, p);
1981        }
1982
1983        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1984            return v.visitMethodSymbol(this, p);
1985        }
1986
1987        @DefinedBy(Api.LANGUAGE_MODEL)
1988        public Type getReceiverType() {
1989            return asType().getReceiverType();
1990        }
1991
1992        @DefinedBy(Api.LANGUAGE_MODEL)
1993        public Type getReturnType() {
1994            return asType().getReturnType();
1995        }
1996
1997        @DefinedBy(Api.LANGUAGE_MODEL)
1998        public List<Type> getThrownTypes() {
1999            return asType().getThrownTypes();
2000        }
2001    }
2002
2003    /** A class for invokedynamic method calls.
2004     */
2005    public static class DynamicMethodSymbol extends MethodSymbol {
2006
2007        public Object[] staticArgs;
2008        public Symbol bsm;
2009        public int bsmKind;
2010
2011        public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
2012            super(0, name, type, owner);
2013            this.bsm = bsm;
2014            this.bsmKind = bsmKind;
2015            this.staticArgs = staticArgs;
2016        }
2017
2018        @Override
2019        public boolean isDynamic() {
2020            return true;
2021        }
2022    }
2023
2024    /** A class for predefined operators.
2025     */
2026    public static class OperatorSymbol extends MethodSymbol {
2027
2028        public int opcode;
2029        private int accessCode = Integer.MIN_VALUE;
2030
2031        public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
2032            super(PUBLIC | STATIC, name, type, owner);
2033            this.opcode = opcode;
2034        }
2035
2036        @Override
2037        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
2038            return v.visitOperatorSymbol(this, p);
2039        }
2040
2041        public int getAccessCode(Tag tag) {
2042            if (accessCode != Integer.MIN_VALUE && !tag.isIncOrDecUnaryOp()) {
2043                return accessCode;
2044            }
2045            accessCode = AccessCode.from(tag, opcode);
2046            return accessCode;
2047        }
2048
2049        /** Access codes for dereferencing, assignment,
2050         *  and pre/post increment/decrement.
2051
2052         *  All access codes for accesses to the current class are even.
2053         *  If a member of the superclass should be accessed instead (because
2054         *  access was via a qualified super), add one to the corresponding code
2055         *  for the current class, making the number odd.
2056         *  This numbering scheme is used by the backend to decide whether
2057         *  to issue an invokevirtual or invokespecial call.
2058         *
2059         *  @see Gen#visitSelect(JCFieldAccess tree)
2060         */
2061        public enum AccessCode {
2062            UNKNOWN(-1, Tag.NO_TAG),
2063            DEREF(0, Tag.NO_TAG),
2064            ASSIGN(2, Tag.ASSIGN),
2065            PREINC(4, Tag.PREINC),
2066            PREDEC(6, Tag.PREDEC),
2067            POSTINC(8, Tag.POSTINC),
2068            POSTDEC(10, Tag.POSTDEC),
2069            FIRSTASGOP(12, Tag.NO_TAG);
2070
2071            public final int code;
2072            public final Tag tag;
2073            public static final int numberOfAccessCodes = (lushrl - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code + 2;
2074
2075            AccessCode(int code, Tag tag) {
2076                this.code = code;
2077                this.tag = tag;
2078            }
2079
2080            static public AccessCode getFromCode(int code) {
2081                for (AccessCode aCodes : AccessCode.values()) {
2082                    if (aCodes.code == code) {
2083                        return aCodes;
2084                    }
2085                }
2086                return UNKNOWN;
2087            }
2088
2089            static int from(Tag tag, int opcode) {
2090                /** Map bytecode of binary operation to access code of corresponding
2091                *  assignment operation. This is always an even number.
2092                */
2093                switch (tag) {
2094                    case PREINC:
2095                        return AccessCode.PREINC.code;
2096                    case PREDEC:
2097                        return AccessCode.PREDEC.code;
2098                    case POSTINC:
2099                        return AccessCode.POSTINC.code;
2100                    case POSTDEC:
2101                        return AccessCode.POSTDEC.code;
2102                }
2103                if (iadd <= opcode && opcode <= lxor) {
2104                    return (opcode - iadd) * 2 + FIRSTASGOP.code;
2105                } else if (opcode == string_add) {
2106                    return (lxor + 1 - iadd) * 2 + FIRSTASGOP.code;
2107                } else if (ishll <= opcode && opcode <= lushrl) {
2108                    return (opcode - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code;
2109                }
2110                return -1;
2111            }
2112        }
2113    }
2114
2115    /** Symbol completer interface.
2116     */
2117    public static interface Completer {
2118
2119        /** Dummy completer to be used when the symbol has been completed or
2120         * does not need completion.
2121         */
2122        public final static Completer NULL_COMPLETER = new Completer() {
2123            public void complete(Symbol sym) { }
2124            public boolean isTerminal() { return true; }
2125        };
2126
2127        void complete(Symbol sym) throws CompletionFailure;
2128
2129        /** Returns true if this completer is <em>terminal</em>. A terminal
2130         * completer is used as a place holder when the symbol is completed.
2131         * Calling complete on a terminal completer will not affect the symbol.
2132         *
2133         * The dummy NULL_COMPLETER and the GraphDependencies completer are
2134         * examples of terminal completers.
2135         *
2136         * @return true iff this completer is terminal
2137         */
2138        default boolean isTerminal() {
2139            return false;
2140        }
2141    }
2142
2143    public static class CompletionFailure extends RuntimeException {
2144        private static final long serialVersionUID = 0;
2145        public Symbol sym;
2146
2147        /** A diagnostic object describing the failure
2148         */
2149        public JCDiagnostic diag;
2150
2151        /** A localized string describing the failure.
2152         * @deprecated Use {@code getDetail()} or {@code getMessage()}
2153         */
2154        @Deprecated
2155        public String errmsg;
2156
2157        public CompletionFailure(Symbol sym, String errmsg) {
2158            this.sym = sym;
2159            this.errmsg = errmsg;
2160//          this.printStackTrace();//DEBUG
2161        }
2162
2163        public CompletionFailure(Symbol sym, JCDiagnostic diag) {
2164            this.sym = sym;
2165            this.diag = diag;
2166//          this.printStackTrace();//DEBUG
2167        }
2168
2169        public JCDiagnostic getDiagnostic() {
2170            return diag;
2171        }
2172
2173        @Override
2174        public String getMessage() {
2175            if (diag != null)
2176                return diag.getMessage(null);
2177            else
2178                return errmsg;
2179        }
2180
2181        public Object getDetailValue() {
2182            return (diag != null ? diag : errmsg);
2183        }
2184
2185        @Override
2186        public CompletionFailure initCause(Throwable cause) {
2187            super.initCause(cause);
2188            return this;
2189        }
2190
2191    }
2192
2193    /**
2194     * A visitor for symbols.  A visitor is used to implement operations
2195     * (or relations) on symbols.  Most common operations on types are
2196     * binary relations and this interface is designed for binary
2197     * relations, that is, operations on the form
2198     * Symbol&nbsp;&times;&nbsp;P&nbsp;&rarr;&nbsp;R.
2199     * <!-- In plain text: Type x P -> R -->
2200     *
2201     * @param <R> the return type of the operation implemented by this
2202     * visitor; use Void if no return type is needed.
2203     * @param <P> the type of the second argument (the first being the
2204     * symbol itself) of the operation implemented by this visitor; use
2205     * Void if a second argument is not needed.
2206     */
2207    public interface Visitor<R,P> {
2208        R visitClassSymbol(ClassSymbol s, P arg);
2209        R visitMethodSymbol(MethodSymbol s, P arg);
2210        R visitPackageSymbol(PackageSymbol s, P arg);
2211        R visitOperatorSymbol(OperatorSymbol s, P arg);
2212        R visitVarSymbol(VarSymbol s, P arg);
2213        R visitTypeSymbol(TypeSymbol s, P arg);
2214        R visitSymbol(Symbol s, P arg);
2215    }
2216}
2217