Symbol.java revision 3513:ea4eea2997b9
1130803Smarcel/*
2130803Smarcel * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3130803Smarcel * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4130803Smarcel *
5130803Smarcel * This code is free software; you can redistribute it and/or modify it
6130803Smarcel * under the terms of the GNU General Public License version 2 only, as
7130803Smarcel * published by the Free Software Foundation.  Oracle designates this
8130803Smarcel * particular file as subject to the "Classpath" exception as provided
9130803Smarcel * by Oracle in the LICENSE file that accompanied this code.
10130803Smarcel *
11130803Smarcel * This code is distributed in the hope that it will be useful, but WITHOUT
12130803Smarcel * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13130803Smarcel * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14130803Smarcel * version 2 for more details (a copy is included in the LICENSE file that
15130803Smarcel * accompanied this code).
16130803Smarcel *
17130803Smarcel * You should have received a copy of the GNU General Public License version
18130803Smarcel * 2 along with this work; if not, write to the Free Software Foundation,
19130803Smarcel * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20130803Smarcel *
21130803Smarcel * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22130803Smarcel * or visit www.oracle.com if you need additional information or have any
23130803Smarcel * questions.
24130803Smarcel */
25130803Smarcel
26130803Smarcelpackage com.sun.tools.javac.code;
27130803Smarcel
28130803Smarcelimport java.lang.annotation.Annotation;
29130803Smarcelimport java.lang.annotation.Inherited;
30130803Smarcelimport java.util.Collections;
31130803Smarcelimport java.util.Map;
32130803Smarcelimport java.util.Set;
33130803Smarcelimport java.util.concurrent.Callable;
34130803Smarcel
35130803Smarcelimport javax.lang.model.element.Element;
36130803Smarcelimport javax.lang.model.element.ElementKind;
37130803Smarcelimport javax.lang.model.element.ElementVisitor;
38130803Smarcelimport javax.lang.model.element.ExecutableElement;
39130803Smarcelimport javax.lang.model.element.Modifier;
40130803Smarcelimport javax.lang.model.element.ModuleElement;
41130803Smarcelimport javax.lang.model.element.NestingKind;
42130803Smarcelimport javax.lang.model.element.PackageElement;
43130803Smarcelimport javax.lang.model.element.TypeElement;
44130803Smarcelimport javax.lang.model.element.TypeParameterElement;
45130803Smarcelimport javax.lang.model.element.VariableElement;
46130803Smarcelimport javax.tools.JavaFileManager;
47130803Smarcelimport javax.tools.JavaFileObject;
48130803Smarcel
49130803Smarcelimport com.sun.tools.javac.code.ClassFinder.BadEnclosingMethodAttr;
50130803Smarcelimport com.sun.tools.javac.code.Kinds.Kind;
51130803Smarcelimport com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
52130803Smarcelimport com.sun.tools.javac.code.Scope.WriteableScope;
53130803Smarcelimport com.sun.tools.javac.code.Type.*;
54130803Smarcelimport com.sun.tools.javac.comp.Attr;
55130803Smarcelimport com.sun.tools.javac.comp.AttrContext;
56130803Smarcelimport com.sun.tools.javac.comp.Env;
57130803Smarcelimport com.sun.tools.javac.jvm.*;
58130803Smarcelimport com.sun.tools.javac.tree.JCTree.JCVariableDecl;
59130803Smarcelimport com.sun.tools.javac.util.*;
60130803Smarcelimport com.sun.tools.javac.util.DefinedBy.Api;
61130803Smarcelimport com.sun.tools.javac.util.Name;
62130803Smarcel
63130803Smarcelimport static com.sun.tools.javac.code.Flags.*;
64130803Smarcelimport static com.sun.tools.javac.code.Kinds.*;
65import static com.sun.tools.javac.code.Kinds.Kind.*;
66import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
67import static com.sun.tools.javac.code.TypeTag.CLASS;
68import static com.sun.tools.javac.code.TypeTag.FORALL;
69import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
70
71/** Root class for Java symbols. It contains subclasses
72 *  for specific sorts of symbols, such as variables, methods and operators,
73 *  types, packages. Each subclass is represented as a static inner class
74 *  inside Symbol.
75 *
76 *  <p><b>This is NOT part of any supported API.
77 *  If you write code that depends on this, you do so at your own risk.
78 *  This code and its internal interfaces are subject to change or
79 *  deletion without notice.</b>
80 */
81public abstract class Symbol extends AnnoConstruct implements Element {
82
83    /** The kind of this symbol.
84     *  @see Kinds
85     */
86    public Kind kind;
87
88    /** The flags of this symbol.
89     */
90    public long flags_field;
91
92    /** An accessor method for the flags of this symbol.
93     *  Flags of class symbols should be accessed through the accessor
94     *  method to make sure that the class symbol is loaded.
95     */
96    public long flags() { return flags_field; }
97
98    /** The name of this symbol in Utf8 representation.
99     */
100    public Name name;
101
102    /** The type of this symbol.
103     */
104    public Type type;
105
106    /** The owner of this symbol.
107     */
108    public Symbol owner;
109
110    /** The completer of this symbol.
111     * This should never equal null (NULL_COMPLETER should be used instead).
112     */
113    public Completer completer;
114
115    /** A cache for the type erasure of this symbol.
116     */
117    public Type erasure_field;
118
119    // <editor-fold defaultstate="collapsed" desc="annotations">
120
121    /** The attributes of this symbol are contained in this
122     * SymbolMetadata. The SymbolMetadata instance is NOT immutable.
123     */
124    protected SymbolMetadata metadata;
125
126
127    /** An accessor method for the attributes of this symbol.
128     *  Attributes of class symbols should be accessed through the accessor
129     *  method to make sure that the class symbol is loaded.
130     */
131    public List<Attribute.Compound> getRawAttributes() {
132        return (metadata == null)
133                ? List.<Attribute.Compound>nil()
134                : metadata.getDeclarationAttributes();
135    }
136
137    /** An accessor method for the type attributes of this symbol.
138     *  Attributes of class symbols should be accessed through the accessor
139     *  method to make sure that the class symbol is loaded.
140     */
141    public List<Attribute.TypeCompound> getRawTypeAttributes() {
142        return (metadata == null)
143                ? List.<Attribute.TypeCompound>nil()
144                : metadata.getTypeAttributes();
145    }
146
147    /** Fetch a particular annotation from a symbol. */
148    public Attribute.Compound attribute(Symbol anno) {
149        for (Attribute.Compound a : getRawAttributes()) {
150            if (a.type.tsym == anno) return a;
151        }
152        return null;
153    }
154
155    public boolean annotationsPendingCompletion() {
156        return metadata == null ? false : metadata.pendingCompletion();
157    }
158
159    public void appendAttributes(List<Attribute.Compound> l) {
160        if (l.nonEmpty()) {
161            initedMetadata().append(l);
162        }
163    }
164
165    public void appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
166        if (l.nonEmpty()) {
167            initedMetadata().appendClassInitTypeAttributes(l);
168        }
169    }
170
171    public void appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
172        if (l.nonEmpty()) {
173            initedMetadata().appendInitTypeAttributes(l);
174        }
175    }
176
177    public void appendUniqueTypeAttributes(List<Attribute.TypeCompound> l) {
178        if (l.nonEmpty()) {
179            initedMetadata().appendUniqueTypes(l);
180        }
181    }
182
183    public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
184        return (metadata == null)
185                ? List.<Attribute.TypeCompound>nil()
186                : metadata.getClassInitTypeAttributes();
187    }
188
189    public List<Attribute.TypeCompound> getInitTypeAttributes() {
190        return (metadata == null)
191                ? List.<Attribute.TypeCompound>nil()
192                : metadata.getInitTypeAttributes();
193    }
194
195    public void setInitTypeAttributes(List<Attribute.TypeCompound> l) {
196        initedMetadata().setInitTypeAttributes(l);
197    }
198
199    public void setClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
200        initedMetadata().setClassInitTypeAttributes(l);
201    }
202
203    public List<Attribute.Compound> getDeclarationAttributes() {
204        return (metadata == null)
205                ? List.<Attribute.Compound>nil()
206                : metadata.getDeclarationAttributes();
207    }
208
209    public boolean hasAnnotations() {
210        return (metadata != null && !metadata.isEmpty());
211    }
212
213    public boolean hasTypeAnnotations() {
214        return (metadata != null && !metadata.isTypesEmpty());
215    }
216
217    public boolean isCompleted() {
218        return completer.isTerminal();
219    }
220
221    public void prependAttributes(List<Attribute.Compound> l) {
222        if (l.nonEmpty()) {
223            initedMetadata().prepend(l);
224        }
225    }
226
227    public void resetAnnotations() {
228        initedMetadata().reset();
229    }
230
231    public void setAttributes(Symbol other) {
232        if (metadata != null || other.metadata != null) {
233            initedMetadata().setAttributes(other.metadata);
234        }
235    }
236
237    public void setDeclarationAttributes(List<Attribute.Compound> a) {
238        if (metadata != null || a.nonEmpty()) {
239            initedMetadata().setDeclarationAttributes(a);
240        }
241    }
242
243    public void setTypeAttributes(List<Attribute.TypeCompound> a) {
244        if (metadata != null || a.nonEmpty()) {
245            if (metadata == null)
246                metadata = new SymbolMetadata(this);
247            metadata.setTypeAttributes(a);
248        }
249    }
250
251    private SymbolMetadata initedMetadata() {
252        if (metadata == null)
253            metadata = new SymbolMetadata(this);
254        return metadata;
255    }
256
257    /** This method is intended for debugging only. */
258    public SymbolMetadata getMetadata() {
259        return metadata;
260    }
261
262    // </editor-fold>
263
264    /** Construct a symbol with given kind, flags, name, type and owner.
265     */
266    public Symbol(Kind kind, long flags, Name name, Type type, Symbol owner) {
267        this.kind = kind;
268        this.flags_field = flags;
269        this.type = type;
270        this.owner = owner;
271        this.completer = Completer.NULL_COMPLETER;
272        this.erasure_field = null;
273        this.name = name;
274    }
275
276    /** Clone this symbol with new owner.
277     *  Legal only for fields and methods.
278     */
279    public Symbol clone(Symbol newOwner) {
280        throw new AssertionError();
281    }
282
283    public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
284        return v.visitSymbol(this, p);
285    }
286
287    /** The Java source which this symbol represents.
288     *  A description of this symbol; overrides Object.
289     */
290    public String toString() {
291        return name.toString();
292    }
293
294    /** A Java source description of the location of this symbol; used for
295     *  error reporting.
296     *
297     * @return null if the symbol is a package or a toplevel class defined in
298     * the default package; otherwise, the owner symbol is returned
299     */
300    public Symbol location() {
301        if (owner.name == null || (owner.name.isEmpty() &&
302                                   (owner.flags() & BLOCK) == 0 &&
303                                   owner.kind != PCK &&
304                                   owner.kind != TYP)) {
305            return null;
306        }
307        return owner;
308    }
309
310    public Symbol location(Type site, Types types) {
311        if (owner.name == null || owner.name.isEmpty()) {
312            return location();
313        }
314        if (owner.type.hasTag(CLASS)) {
315            Type ownertype = types.asOuterSuper(site, owner);
316            if (ownertype != null) return ownertype.tsym;
317        }
318        return owner;
319    }
320
321    public Symbol baseSymbol() {
322        return this;
323    }
324
325    /** The symbol's erased type.
326     */
327    public Type erasure(Types types) {
328        if (erasure_field == null)
329            erasure_field = types.erasure(type);
330        return erasure_field;
331    }
332
333    /** The external type of a symbol. This is the symbol's erased type
334     *  except for constructors of inner classes which get the enclosing
335     *  instance class added as first argument.
336     */
337    public Type externalType(Types types) {
338        Type t = erasure(types);
339        if (name == name.table.names.init && owner.hasOuterInstance()) {
340            Type outerThisType = types.erasure(owner.type.getEnclosingType());
341            return new MethodType(t.getParameterTypes().prepend(outerThisType),
342                                  t.getReturnType(),
343                                  t.getThrownTypes(),
344                                  t.tsym);
345        } else {
346            return t;
347        }
348    }
349
350    public boolean isDeprecated() {
351        return (flags_field & DEPRECATED) != 0;
352    }
353
354    public boolean isStatic() {
355        return
356            (flags() & STATIC) != 0 ||
357            (owner.flags() & INTERFACE) != 0 && kind != MTH &&
358             name != name.table.names._this;
359    }
360
361    public boolean isInterface() {
362        return (flags() & INTERFACE) != 0;
363    }
364
365    public boolean isPrivate() {
366        return (flags_field & Flags.AccessFlags) == PRIVATE;
367    }
368
369    public boolean isEnum() {
370        return (flags() & ENUM) != 0;
371    }
372
373    /** Is this symbol declared (directly or indirectly) local
374     *  to a method or variable initializer?
375     *  Also includes fields of inner classes which are in
376     *  turn local to a method or variable initializer.
377     */
378    public boolean isLocal() {
379        return
380            (owner.kind.matches(KindSelector.VAL_MTH) ||
381             (owner.kind == TYP && owner.isLocal()));
382    }
383
384    /** Has this symbol an empty name? This includes anonymous
385     *  inner classes.
386     */
387    public boolean isAnonymous() {
388        return name.isEmpty();
389    }
390
391    /** Is this symbol a constructor?
392     */
393    public boolean isConstructor() {
394        return name == name.table.names.init;
395    }
396
397    /** The fully qualified name of this symbol.
398     *  This is the same as the symbol's name except for class symbols,
399     *  which are handled separately.
400     */
401    public Name getQualifiedName() {
402        return name;
403    }
404
405    /** The fully qualified name of this symbol after converting to flat
406     *  representation. This is the same as the symbol's name except for
407     *  class symbols, which are handled separately.
408     */
409    public Name flatName() {
410        return getQualifiedName();
411    }
412
413    /** If this is a class or package, its members, otherwise null.
414     */
415    public WriteableScope members() {
416        return null;
417    }
418
419    /** A class is an inner class if it it has an enclosing instance class.
420     */
421    public boolean isInner() {
422        return kind == TYP && type.getEnclosingType().hasTag(CLASS);
423    }
424
425    /** An inner class has an outer instance if it is not an interface
426     *  it has an enclosing instance class which might be referenced from the class.
427     *  Nested classes can see instance members of their enclosing class.
428     *  Their constructors carry an additional this$n parameter, inserted
429     *  implicitly by the compiler.
430     *
431     *  @see #isInner
432     */
433    public boolean hasOuterInstance() {
434        return
435            type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
436    }
437
438    /** The closest enclosing class of this symbol's declaration.
439     *  Warning: this (misnamed) method returns the receiver itself
440     *  when the receiver is a class (as opposed to its enclosing
441     *  class as one may be misled to believe.)
442     */
443    public ClassSymbol enclClass() {
444        Symbol c = this;
445        while (c != null &&
446               (!c.kind.matches(KindSelector.TYP) || !c.type.hasTag(CLASS))) {
447            c = c.owner;
448        }
449        return (ClassSymbol)c;
450    }
451
452    /** The outermost class which indirectly owns this symbol.
453     */
454    public ClassSymbol outermostClass() {
455        Symbol sym = this;
456        Symbol prev = null;
457        while (sym.kind != PCK) {
458            prev = sym;
459            sym = sym.owner;
460        }
461        return (ClassSymbol) prev;
462    }
463
464    /** The package which indirectly owns this symbol.
465     */
466    public PackageSymbol packge() {
467        Symbol sym = this;
468        while (sym.kind != PCK) {
469            sym = sym.owner;
470        }
471        return (PackageSymbol) sym;
472    }
473
474    /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
475     */
476    public boolean isSubClass(Symbol base, Types types) {
477        throw new AssertionError("isSubClass " + this);
478    }
479
480    /** Fully check membership: hierarchy, protection, and hiding.
481     *  Does not exclude methods not inherited due to overriding.
482     */
483    public boolean isMemberOf(TypeSymbol clazz, Types types) {
484        return
485            owner == clazz ||
486            clazz.isSubClass(owner, types) &&
487            isInheritedIn(clazz, types) &&
488            !hiddenIn((ClassSymbol)clazz, types);
489    }
490
491    /** Is this symbol the same as or enclosed by the given class? */
492    public boolean isEnclosedBy(ClassSymbol clazz) {
493        for (Symbol sym = this; sym.kind != PCK; sym = sym.owner)
494            if (sym == clazz) return true;
495        return false;
496    }
497
498    private boolean hiddenIn(ClassSymbol clazz, Types types) {
499        Symbol sym = hiddenInInternal(clazz, types);
500        Assert.check(sym != null, "the result of hiddenInInternal() can't be null");
501        /* If we find the current symbol then there is no symbol hiding it
502         */
503        return sym != this;
504    }
505
506    /** This method looks in the supertypes graph that has the current class as the
507     * initial node, till it finds the current symbol or another symbol that hides it.
508     * If the current class has more than one supertype (extends one class and
509     * implements one or more interfaces) then null can be returned, meaning that
510     * a wrong path in the supertypes graph was selected. Null can only be returned
511     * as a temporary value, as a result of the recursive call.
512     */
513    private Symbol hiddenInInternal(ClassSymbol currentClass, Types types) {
514        if (currentClass == owner) {
515            return this;
516        }
517        for (Symbol sym : currentClass.members().getSymbolsByName(name)) {
518            if (sym.kind == kind &&
519                    (kind != MTH ||
520                    (sym.flags() & STATIC) != 0 &&
521                    types.isSubSignature(sym.type, type))) {
522                return sym;
523            }
524        }
525        Symbol hiddenSym = null;
526        for (Type st : types.interfaces(currentClass.type)
527                .prepend(types.supertype(currentClass.type))) {
528            if (st != null && (st.hasTag(CLASS))) {
529                Symbol sym = hiddenInInternal((ClassSymbol)st.tsym, types);
530                if (sym == this) {
531                    return this;
532                } else if (sym != null) {
533                    hiddenSym = sym;
534                }
535            }
536        }
537        return hiddenSym;
538    }
539
540    /** Is this symbol inherited into a given class?
541     *  PRE: If symbol's owner is a interface,
542     *       it is already assumed that the interface is a superinterface
543     *       of given class.
544     *  @param clazz  The class for which we want to establish membership.
545     *                This must be a subclass of the member's owner.
546     */
547    public boolean isInheritedIn(Symbol clazz, Types types) {
548        switch ((int)(flags_field & Flags.AccessFlags)) {
549        default: // error recovery
550        case PUBLIC:
551            return true;
552        case PRIVATE:
553            return this.owner == clazz;
554        case PROTECTED:
555            // we model interfaces as extending Object
556            return (clazz.flags() & INTERFACE) == 0;
557        case 0:
558            PackageSymbol thisPackage = this.packge();
559            for (Symbol sup = clazz;
560                 sup != null && sup != this.owner;
561                 sup = types.supertype(sup.type).tsym) {
562                while (sup.type.hasTag(TYPEVAR))
563                    sup = sup.type.getUpperBound().tsym;
564                if (sup.type.isErroneous())
565                    return true; // error recovery
566                if ((sup.flags() & COMPOUND) != 0)
567                    continue;
568                if (sup.packge() != thisPackage)
569                    return false;
570            }
571            return (clazz.flags() & INTERFACE) == 0;
572        }
573    }
574
575    /** The (variable or method) symbol seen as a member of given
576     *  class type`site' (this might change the symbol's type).
577     *  This is used exclusively for producing diagnostics.
578     */
579    public Symbol asMemberOf(Type site, Types types) {
580        throw new AssertionError();
581    }
582
583    /** Does this method symbol override `other' symbol, when both are seen as
584     *  members of class `origin'?  It is assumed that _other is a member
585     *  of origin.
586     *
587     *  It is assumed that both symbols have the same name.  The static
588     *  modifier is ignored for this test.
589     *
590     *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
591     */
592    public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
593        return false;
594    }
595
596    /** Complete the elaboration of this symbol's definition.
597     */
598    public void complete() throws CompletionFailure {
599        if (completer != Completer.NULL_COMPLETER) {
600            Completer c = completer;
601            completer = Completer.NULL_COMPLETER;
602            c.complete(this);
603        }
604    }
605
606    /** True if the symbol represents an entity that exists.
607     */
608    public boolean exists() {
609        return true;
610    }
611
612    @DefinedBy(Api.LANGUAGE_MODEL)
613    public Type asType() {
614        return type;
615    }
616
617    @DefinedBy(Api.LANGUAGE_MODEL)
618    public Symbol getEnclosingElement() {
619        return owner;
620    }
621
622    @DefinedBy(Api.LANGUAGE_MODEL)
623    public ElementKind getKind() {
624        return ElementKind.OTHER;       // most unkind
625    }
626
627    @DefinedBy(Api.LANGUAGE_MODEL)
628    public Set<Modifier> getModifiers() {
629        return Flags.asModifierSet(flags());
630    }
631
632    @DefinedBy(Api.LANGUAGE_MODEL)
633    public Name getSimpleName() {
634        return name;
635    }
636
637    /**
638     * This is the implementation for {@code
639     * javax.lang.model.element.Element.getAnnotationMirrors()}.
640     */
641    @Override @DefinedBy(Api.LANGUAGE_MODEL)
642    public List<Attribute.Compound> getAnnotationMirrors() {
643        return getRawAttributes();
644    }
645
646
647    // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
648    @DefinedBy(Api.LANGUAGE_MODEL)
649    public java.util.List<Symbol> getEnclosedElements() {
650        return List.nil();
651    }
652
653    public List<TypeVariableSymbol> getTypeParameters() {
654        ListBuffer<TypeVariableSymbol> l = new ListBuffer<>();
655        for (Type t : type.getTypeArguments()) {
656            Assert.check(t.tsym.getKind() == ElementKind.TYPE_PARAMETER);
657            l.append((TypeVariableSymbol)t.tsym);
658        }
659        return l.toList();
660    }
661
662    public static class DelegatedSymbol<T extends Symbol> extends Symbol {
663        protected T other;
664        public DelegatedSymbol(T other) {
665            super(other.kind, other.flags_field, other.name, other.type, other.owner);
666            this.other = other;
667        }
668        public String toString() { return other.toString(); }
669        public Symbol location() { return other.location(); }
670        public Symbol location(Type site, Types types) { return other.location(site, types); }
671        public Symbol baseSymbol() { return other; }
672        public Type erasure(Types types) { return other.erasure(types); }
673        public Type externalType(Types types) { return other.externalType(types); }
674        public boolean isLocal() { return other.isLocal(); }
675        public boolean isConstructor() { return other.isConstructor(); }
676        public Name getQualifiedName() { return other.getQualifiedName(); }
677        public Name flatName() { return other.flatName(); }
678        public WriteableScope members() { return other.members(); }
679        public boolean isInner() { return other.isInner(); }
680        public boolean hasOuterInstance() { return other.hasOuterInstance(); }
681        public ClassSymbol enclClass() { return other.enclClass(); }
682        public ClassSymbol outermostClass() { return other.outermostClass(); }
683        public PackageSymbol packge() { return other.packge(); }
684        public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
685        public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
686        public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
687        public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
688        public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
689        public void complete() throws CompletionFailure { other.complete(); }
690
691        @DefinedBy(Api.LANGUAGE_MODEL)
692        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
693            return other.accept(v, p);
694        }
695
696        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
697            return v.visitSymbol(other, p);
698        }
699
700        public T getUnderlyingSymbol() {
701            return other;
702        }
703    }
704
705    /** A base class for Symbols representing types.
706     */
707    public static abstract class TypeSymbol extends Symbol {
708        public TypeSymbol(Kind kind, long flags, Name name, Type type, Symbol owner) {
709            super(kind, flags, name, type, owner);
710        }
711        /** form a fully qualified name from a name and an owner
712         */
713        static public Name formFullName(Name name, Symbol owner) {
714            if (owner == null) return name;
715            if ((owner.kind != ERR) &&
716                (owner.kind.matches(KindSelector.VAL_MTH) ||
717                 (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
718                 )) return name;
719            Name prefix = owner.getQualifiedName();
720            if (prefix == null || prefix == prefix.table.names.empty)
721                return name;
722            else return prefix.append('.', name);
723        }
724
725        /** form a fully qualified name from a name and an owner, after
726         *  converting to flat representation
727         */
728        static public Name formFlatName(Name name, Symbol owner) {
729            if (owner == null || owner.kind.matches(KindSelector.VAL_MTH) ||
730                (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
731                ) return name;
732            char sep = owner.kind == TYP ? '$' : '.';
733            Name prefix = owner.flatName();
734            if (prefix == null || prefix == prefix.table.names.empty)
735                return name;
736            else return prefix.append(sep, name);
737        }
738
739        /**
740         * A partial ordering between type symbols that refines the
741         * class inheritance graph.
742         *
743         * Type variables always precede other kinds of symbols.
744         */
745        public final boolean precedes(TypeSymbol that, Types types) {
746            if (this == that)
747                return false;
748            if (type.hasTag(that.type.getTag())) {
749                if (type.hasTag(CLASS)) {
750                    return
751                        types.rank(that.type) < types.rank(this.type) ||
752                        types.rank(that.type) == types.rank(this.type) &&
753                        that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
754                } else if (type.hasTag(TYPEVAR)) {
755                    return types.isSubtype(this.type, that.type);
756                }
757            }
758            return type.hasTag(TYPEVAR);
759        }
760
761        @Override @DefinedBy(Api.LANGUAGE_MODEL)
762        public java.util.List<Symbol> getEnclosedElements() {
763            List<Symbol> list = List.nil();
764            if (kind == TYP && type.hasTag(TYPEVAR)) {
765                return list;
766            }
767            for (Symbol sym : members().getSymbols(NON_RECURSIVE)) {
768                try {
769                    if (sym != null && (sym.flags() & SYNTHETIC) == 0 && sym.owner == this) {
770                        list = list.prepend(sym);
771                    }
772                } catch (BadEnclosingMethodAttr badEnclosingMethod) {
773                    // ignore the exception
774                }
775            }
776            return list;
777        }
778
779        public AnnotationTypeMetadata getAnnotationTypeMetadata() {
780            Assert.error("Only on ClassSymbol");
781            return null; //unreachable
782        }
783
784        public boolean isAnnotationType() { return false; }
785
786        @Override
787        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
788            return v.visitTypeSymbol(this, p);
789        }
790    }
791
792    /**
793     * Type variables are represented by instances of this class.
794     */
795    public static class TypeVariableSymbol
796            extends TypeSymbol implements TypeParameterElement {
797
798        public TypeVariableSymbol(long flags, Name name, Type type, Symbol owner) {
799            super(TYP, flags, name, type, owner);
800        }
801
802        @DefinedBy(Api.LANGUAGE_MODEL)
803        public ElementKind getKind() {
804            return ElementKind.TYPE_PARAMETER;
805        }
806
807        @Override @DefinedBy(Api.LANGUAGE_MODEL)
808        public Symbol getGenericElement() {
809            return owner;
810        }
811
812        @DefinedBy(Api.LANGUAGE_MODEL)
813        public List<Type> getBounds() {
814            TypeVar t = (TypeVar)type;
815            Type bound = t.getUpperBound();
816            if (!bound.isCompound())
817                return List.of(bound);
818            ClassType ct = (ClassType)bound;
819            if (!ct.tsym.erasure_field.isInterface()) {
820                return ct.interfaces_field.prepend(ct.supertype_field);
821            } else {
822                // No superclass was given in bounds.
823                // In this case, supertype is Object, erasure is first interface.
824                return ct.interfaces_field;
825            }
826        }
827
828        @Override @DefinedBy(Api.LANGUAGE_MODEL)
829        public List<Attribute.Compound> getAnnotationMirrors() {
830            // Declaration annotations on type variables are stored in type attributes
831            // on the owner of the TypeVariableSymbol
832            List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes();
833            int index = owner.getTypeParameters().indexOf(this);
834            List<Attribute.Compound> res = List.nil();
835            for (Attribute.TypeCompound a : candidates) {
836                if (isCurrentSymbolsAnnotation(a, index))
837                    res = res.prepend(a);
838            }
839
840            return res.reverse();
841        }
842
843        // Helper to getAnnotation[s]
844        @Override
845        public <A extends Annotation> Attribute.Compound getAttribute(Class<A> annoType) {
846            String name = annoType.getName();
847
848            // Declaration annotations on type variables are stored in type attributes
849            // on the owner of the TypeVariableSymbol
850            List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes();
851            int index = owner.getTypeParameters().indexOf(this);
852            for (Attribute.TypeCompound anno : candidates)
853                if (isCurrentSymbolsAnnotation(anno, index) &&
854                    name.contentEquals(anno.type.tsym.flatName()))
855                    return anno;
856
857            return null;
858        }
859            //where:
860            boolean isCurrentSymbolsAnnotation(Attribute.TypeCompound anno, int index) {
861                return (anno.position.type == TargetType.CLASS_TYPE_PARAMETER ||
862                        anno.position.type == TargetType.METHOD_TYPE_PARAMETER) &&
863                        anno.position.parameter_index == index;
864            }
865
866
867        @Override @DefinedBy(Api.LANGUAGE_MODEL)
868        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
869            return v.visitTypeParameter(this, p);
870        }
871    }
872    /** A class for module symbols.
873     */
874    public static class ModuleSymbol extends TypeSymbol
875            implements ModuleElement {
876
877        public Name version;
878        public JavaFileManager.Location sourceLocation;
879        public JavaFileManager.Location classLocation;
880
881        /** All directives, in natural order. */
882        public List<com.sun.tools.javac.code.Directive> directives;
883        public List<com.sun.tools.javac.code.Directive.RequiresDirective> requires;
884        public List<com.sun.tools.javac.code.Directive.ExportsDirective> exports;
885        public List<com.sun.tools.javac.code.Directive.ProvidesDirective> provides;
886        public List<com.sun.tools.javac.code.Directive.UsesDirective> uses;
887
888        public ClassSymbol module_info;
889
890        public PackageSymbol unnamedPackage;
891        public Map<Name, PackageSymbol> visiblePackages;
892        public List<Symbol> enclosedPackages = List.nil();
893
894        public Completer usesProvidesCompleter = Completer.NULL_COMPLETER;
895
896        /**
897         * Create a ModuleSymbol with an associated module-info ClassSymbol.
898         * The name of the module may be null, if it is not known yet.
899         */
900        public static ModuleSymbol create(Name name, Name module_info) {
901            ModuleSymbol msym = new ModuleSymbol(name, null);
902            ClassSymbol info = new ClassSymbol(Flags.MODULE, module_info, msym);
903            info.fullname = formFullName(module_info, msym);
904            info.flatname = info.fullname;
905            info.members_field = WriteableScope.create(info);
906            msym.module_info = info;
907            return msym;
908        }
909
910        public ModuleSymbol() {
911            super(MDL, 0, null, null, null);
912            this.type = new ModuleType(this);
913        }
914
915        public ModuleSymbol(Name name, Symbol owner) {
916            super(MDL, 0, name, null, owner);
917            this.type = new ModuleType(this);
918        }
919
920        @Override @DefinedBy(Api.LANGUAGE_MODEL)
921        public boolean isUnnamed() {
922            return name.isEmpty() && owner == null;
923        }
924
925        public boolean isNoModule() {
926            return false;
927        }
928
929        @Override @DefinedBy(Api.LANGUAGE_MODEL)
930        public ElementKind getKind() {
931            return ElementKind.MODULE;
932        }
933
934        @Override @DefinedBy(Api.LANGUAGE_MODEL)
935        public java.util.List<Directive> getDirectives() {
936            completeUsesProvides();
937            return Collections.unmodifiableList(directives);
938        }
939
940        public void completeUsesProvides() {
941            if (usesProvidesCompleter != Completer.NULL_COMPLETER) {
942                Completer c = usesProvidesCompleter;
943                usesProvidesCompleter = Completer.NULL_COMPLETER;
944                c.complete(this);
945            }
946        }
947
948        @Override
949        public ClassSymbol outermostClass() {
950            return null;
951        }
952
953        @Override
954        public String toString() {
955            // TODO: the following strings should be localized
956            // Do this with custom anon subtypes in Symtab
957            String n = (name == null) ? "<unknown>"
958                    : (name.isEmpty()) ? "<unnamed>"
959                    : String.valueOf(name);
960            return n;
961        }
962
963        @Override @DefinedBy(Api.LANGUAGE_MODEL)
964        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
965            return v.visitModule(this, p);
966        }
967
968        @Override @DefinedBy(Api.LANGUAGE_MODEL)
969        public List<Symbol> getEnclosedElements() {
970            List<Symbol> list = List.nil();
971            for (Symbol sym : enclosedPackages) {
972                if (sym.members().anyMatch(m -> m.kind == TYP))
973                    list = list.prepend(sym);
974            }
975            return list;
976        }
977
978        public void reset() {
979            this.directives = null;
980            this.requires = null;
981            this.exports = null;
982            this.provides = null;
983            this.uses = null;
984            this.visiblePackages = null;
985        }
986
987    }
988
989    /** A class for package symbols
990     */
991    public static class PackageSymbol extends TypeSymbol
992        implements PackageElement {
993
994        public WriteableScope members_field;
995        public Name fullname;
996        public ClassSymbol package_info; // see bug 6443073
997        public ModuleSymbol modle;
998
999        public PackageSymbol(Name name, Type type, Symbol owner) {
1000            super(PCK, 0, name, type, owner);
1001            this.members_field = null;
1002            this.fullname = formFullName(name, owner);
1003        }
1004
1005        public PackageSymbol(Name name, Symbol owner) {
1006            this(name, null, owner);
1007            this.type = new PackageType(this);
1008        }
1009
1010        public String toString() {
1011            return fullname.toString();
1012        }
1013
1014        @DefinedBy(Api.LANGUAGE_MODEL)
1015        public Name getQualifiedName() {
1016            return fullname;
1017        }
1018
1019        @DefinedBy(Api.LANGUAGE_MODEL)
1020        public boolean isUnnamed() {
1021            return name.isEmpty() && owner != null;
1022        }
1023
1024        public WriteableScope members() {
1025            complete();
1026            return members_field;
1027        }
1028
1029        public long flags() {
1030            complete();
1031            return flags_field;
1032        }
1033
1034        @Override
1035        public List<Attribute.Compound> getRawAttributes() {
1036            complete();
1037            if (package_info != null) {
1038                package_info.complete();
1039                mergeAttributes();
1040            }
1041            return super.getRawAttributes();
1042        }
1043
1044        private void mergeAttributes() {
1045            if (metadata == null &&
1046                package_info.metadata != null) {
1047                metadata = new SymbolMetadata(this);
1048                metadata.setAttributes(package_info.metadata);
1049            }
1050        }
1051
1052        /** A package "exists" if a type or package that exists has
1053         *  been seen within it.
1054         */
1055        public boolean exists() {
1056            return (flags_field & EXISTS) != 0;
1057        }
1058
1059        @DefinedBy(Api.LANGUAGE_MODEL)
1060        public ElementKind getKind() {
1061            return ElementKind.PACKAGE;
1062        }
1063
1064        @DefinedBy(Api.LANGUAGE_MODEL)
1065        public Symbol getEnclosingElement() {
1066            return modle != null && !modle.isNoModule() ? modle : null;
1067        }
1068
1069        @DefinedBy(Api.LANGUAGE_MODEL)
1070        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1071            return v.visitPackage(this, p);
1072        }
1073
1074        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1075            return v.visitPackageSymbol(this, p);
1076        }
1077
1078        /**Resets the Symbol into the state good for next round of annotation processing.*/
1079        public void reset() {
1080            metadata = null;
1081        }
1082
1083    }
1084
1085    /** A class for class symbols
1086     */
1087    public static class ClassSymbol extends TypeSymbol implements TypeElement {
1088
1089        /** a scope for all class members; variables, methods and inner classes
1090         *  type parameters are not part of this scope
1091         */
1092        public WriteableScope members_field;
1093
1094        /** the fully qualified name of the class, i.e. pck.outer.inner.
1095         *  null for anonymous classes
1096         */
1097        public Name fullname;
1098
1099        /** the fully qualified name of the class after converting to flat
1100         *  representation, i.e. pck.outer$inner,
1101         *  set externally for local and anonymous classes
1102         */
1103        public Name flatname;
1104
1105        /** the sourcefile where the class came from
1106         */
1107        public JavaFileObject sourcefile;
1108
1109        /** the classfile from where to load this class
1110         *  this will have extension .class or .java
1111         */
1112        public JavaFileObject classfile;
1113
1114        /** the list of translated local classes (used for generating
1115         * InnerClasses attribute)
1116         */
1117        public List<ClassSymbol> trans_local;
1118
1119        /** the constant pool of the class
1120         */
1121        public Pool pool;
1122
1123        /** the annotation metadata attached to this class */
1124        private AnnotationTypeMetadata annotationTypeMetadata;
1125
1126        public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
1127            super(TYP, flags, name, type, owner);
1128            this.members_field = null;
1129            this.fullname = formFullName(name, owner);
1130            this.flatname = formFlatName(name, owner);
1131            this.sourcefile = null;
1132            this.classfile = null;
1133            this.pool = null;
1134            this.annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1135        }
1136
1137        public ClassSymbol(long flags, Name name, Symbol owner) {
1138            this(
1139                flags,
1140                name,
1141                new ClassType(Type.noType, null, null),
1142                owner);
1143            this.type.tsym = this;
1144        }
1145
1146        /** The Java source which this symbol represents.
1147         */
1148        public String toString() {
1149            return className();
1150        }
1151
1152        public long flags() {
1153            complete();
1154            return flags_field;
1155        }
1156
1157        public WriteableScope members() {
1158            complete();
1159            return members_field;
1160        }
1161
1162        @Override
1163        public List<Attribute.Compound> getRawAttributes() {
1164            complete();
1165            return super.getRawAttributes();
1166        }
1167
1168        @Override
1169        public List<Attribute.TypeCompound> getRawTypeAttributes() {
1170            complete();
1171            return super.getRawTypeAttributes();
1172        }
1173
1174        public Type erasure(Types types) {
1175            if (erasure_field == null)
1176                erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
1177                                              List.<Type>nil(), this,
1178                                              type.getMetadata());
1179            return erasure_field;
1180        }
1181
1182        public String className() {
1183            if (name.isEmpty())
1184                return
1185                    Log.getLocalizedString("anonymous.class", flatname);
1186            else
1187                return fullname.toString();
1188        }
1189
1190        @DefinedBy(Api.LANGUAGE_MODEL)
1191        public Name getQualifiedName() {
1192            return fullname;
1193        }
1194
1195        public Name flatName() {
1196            return flatname;
1197        }
1198
1199        public boolean isSubClass(Symbol base, Types types) {
1200            if (this == base) {
1201                return true;
1202            } else if ((base.flags() & INTERFACE) != 0) {
1203                for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1204                    for (List<Type> is = types.interfaces(t);
1205                         is.nonEmpty();
1206                         is = is.tail)
1207                        if (is.head.tsym.isSubClass(base, types)) return true;
1208            } else {
1209                for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1210                    if (t.tsym == base) return true;
1211            }
1212            return false;
1213        }
1214
1215        /** Complete the elaboration of this symbol's definition.
1216         */
1217        public void complete() throws CompletionFailure {
1218            try {
1219                super.complete();
1220            } catch (CompletionFailure ex) {
1221                // quiet error recovery
1222                flags_field |= (PUBLIC|STATIC);
1223                this.type = new ErrorType(this, Type.noType);
1224                throw ex;
1225            }
1226        }
1227
1228        @DefinedBy(Api.LANGUAGE_MODEL)
1229        public List<Type> getInterfaces() {
1230            complete();
1231            if (type instanceof ClassType) {
1232                ClassType t = (ClassType)type;
1233                if (t.interfaces_field == null) // FIXME: shouldn't be null
1234                    t.interfaces_field = List.nil();
1235                if (t.all_interfaces_field != null)
1236                    return Type.getModelTypes(t.all_interfaces_field);
1237                return t.interfaces_field;
1238            } else {
1239                return List.nil();
1240            }
1241        }
1242
1243        @DefinedBy(Api.LANGUAGE_MODEL)
1244        public Type getSuperclass() {
1245            complete();
1246            if (type instanceof ClassType) {
1247                ClassType t = (ClassType)type;
1248                if (t.supertype_field == null) // FIXME: shouldn't be null
1249                    t.supertype_field = Type.noType;
1250                // An interface has no superclass; its supertype is Object.
1251                return t.isInterface()
1252                    ? Type.noType
1253                    : t.supertype_field.getModelType();
1254            } else {
1255                return Type.noType;
1256            }
1257        }
1258
1259        /**
1260         * Returns the next class to search for inherited annotations or {@code null}
1261         * if the next class can't be found.
1262         */
1263        private ClassSymbol getSuperClassToSearchForAnnotations() {
1264
1265            Type sup = getSuperclass();
1266
1267            if (!sup.hasTag(CLASS) || sup.isErroneous())
1268                return null;
1269
1270            return (ClassSymbol) sup.tsym;
1271        }
1272
1273
1274        @Override
1275        protected <A extends Annotation> A[] getInheritedAnnotations(Class<A> annoType) {
1276
1277            ClassSymbol sup = getSuperClassToSearchForAnnotations();
1278
1279            return sup == null ? super.getInheritedAnnotations(annoType)
1280                               : sup.getAnnotationsByType(annoType);
1281        }
1282
1283
1284        @DefinedBy(Api.LANGUAGE_MODEL)
1285        public ElementKind getKind() {
1286            long flags = flags();
1287            if ((flags & ANNOTATION) != 0)
1288                return ElementKind.ANNOTATION_TYPE;
1289            else if ((flags & INTERFACE) != 0)
1290                return ElementKind.INTERFACE;
1291            else if ((flags & ENUM) != 0)
1292                return ElementKind.ENUM;
1293            else
1294                return ElementKind.CLASS;
1295        }
1296
1297        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1298        public Set<Modifier> getModifiers() {
1299            long flags = flags();
1300            return Flags.asModifierSet(flags & ~DEFAULT);
1301        }
1302
1303        @DefinedBy(Api.LANGUAGE_MODEL)
1304        public NestingKind getNestingKind() {
1305            complete();
1306            if (owner.kind == PCK)
1307                return NestingKind.TOP_LEVEL;
1308            else if (name.isEmpty())
1309                return NestingKind.ANONYMOUS;
1310            else if (owner.kind == MTH)
1311                return NestingKind.LOCAL;
1312            else
1313                return NestingKind.MEMBER;
1314        }
1315
1316
1317        @Override
1318        protected <A extends Annotation> Attribute.Compound getAttribute(final Class<A> annoType) {
1319
1320            Attribute.Compound attrib = super.getAttribute(annoType);
1321
1322            boolean inherited = annoType.isAnnotationPresent(Inherited.class);
1323            if (attrib != null || !inherited)
1324                return attrib;
1325
1326            // Search supertypes
1327            ClassSymbol superType = getSuperClassToSearchForAnnotations();
1328            return superType == null ? null
1329                                     : superType.getAttribute(annoType);
1330        }
1331
1332
1333
1334
1335        @DefinedBy(Api.LANGUAGE_MODEL)
1336        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1337            return v.visitType(this, p);
1338        }
1339
1340        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1341            return v.visitClassSymbol(this, p);
1342        }
1343
1344        public void markAbstractIfNeeded(Types types) {
1345            if (types.enter.getEnv(this) != null &&
1346                (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym &&
1347                (flags() & (FINAL | ABSTRACT)) == 0) {
1348                if (types.firstUnimplementedAbstract(this) != null)
1349                    // add the ABSTRACT flag to an enum
1350                    flags_field |= ABSTRACT;
1351            }
1352        }
1353
1354        /**Resets the Symbol into the state good for next round of annotation processing.*/
1355        public void reset() {
1356            kind = TYP;
1357            erasure_field = null;
1358            members_field = null;
1359            flags_field = 0;
1360            if (type instanceof ClassType) {
1361                ClassType t = (ClassType)type;
1362                t.setEnclosingType(Type.noType);
1363                t.rank_field = -1;
1364                t.typarams_field = null;
1365                t.allparams_field = null;
1366                t.supertype_field = null;
1367                t.interfaces_field = null;
1368                t.all_interfaces_field = null;
1369            }
1370            clearAnnotationMetadata();
1371        }
1372
1373        public void clearAnnotationMetadata() {
1374            metadata = null;
1375            annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1376        }
1377
1378        @Override
1379        public AnnotationTypeMetadata getAnnotationTypeMetadata() {
1380            return annotationTypeMetadata;
1381        }
1382
1383        @Override
1384        public boolean isAnnotationType() {
1385            return (flags_field & Flags.ANNOTATION) != 0;
1386        }
1387
1388        public void setAnnotationTypeMetadata(AnnotationTypeMetadata a) {
1389            Assert.checkNonNull(a);
1390            Assert.check(!annotationTypeMetadata.isMetadataForAnnotationType());
1391            this.annotationTypeMetadata = a;
1392        }
1393    }
1394
1395
1396    /** A class for variable symbols
1397     */
1398    public static class VarSymbol extends Symbol implements VariableElement {
1399
1400        /** The variable's declaration position.
1401         */
1402        public int pos = Position.NOPOS;
1403
1404        /** The variable's address. Used for different purposes during
1405         *  flow analysis, translation and code generation.
1406         *  Flow analysis:
1407         *    If this is a blank final or local variable, its sequence number.
1408         *  Translation:
1409         *    If this is a private field, its access number.
1410         *  Code generation:
1411         *    If this is a local variable, its logical slot number.
1412         */
1413        public int adr = -1;
1414
1415        /** Construct a variable symbol, given its flags, name, type and owner.
1416         */
1417        public VarSymbol(long flags, Name name, Type type, Symbol owner) {
1418            super(VAR, flags, name, type, owner);
1419        }
1420
1421        /** Clone this symbol with new owner.
1422         */
1423        public VarSymbol clone(Symbol newOwner) {
1424            VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) {
1425                @Override
1426                public Symbol baseSymbol() {
1427                    return VarSymbol.this;
1428                }
1429            };
1430            v.pos = pos;
1431            v.adr = adr;
1432            v.data = data;
1433//          System.out.println("clone " + v + " in " + newOwner);//DEBUG
1434            return v;
1435        }
1436
1437        public String toString() {
1438            return name.toString();
1439        }
1440
1441        public Symbol asMemberOf(Type site, Types types) {
1442            return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
1443        }
1444
1445        @DefinedBy(Api.LANGUAGE_MODEL)
1446        public ElementKind getKind() {
1447            long flags = flags();
1448            if ((flags & PARAMETER) != 0) {
1449                if (isExceptionParameter())
1450                    return ElementKind.EXCEPTION_PARAMETER;
1451                else
1452                    return ElementKind.PARAMETER;
1453            } else if ((flags & ENUM) != 0) {
1454                return ElementKind.ENUM_CONSTANT;
1455            } else if (owner.kind == TYP || owner.kind == ERR) {
1456                return ElementKind.FIELD;
1457            } else if (isResourceVariable()) {
1458                return ElementKind.RESOURCE_VARIABLE;
1459            } else {
1460                return ElementKind.LOCAL_VARIABLE;
1461            }
1462        }
1463
1464        @DefinedBy(Api.LANGUAGE_MODEL)
1465        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1466            return v.visitVariable(this, p);
1467        }
1468
1469        @DefinedBy(Api.LANGUAGE_MODEL)
1470        public Object getConstantValue() { // Mirror API
1471            return Constants.decode(getConstValue(), type);
1472        }
1473
1474        public void setLazyConstValue(final Env<AttrContext> env,
1475                                      final Attr attr,
1476                                      final JCVariableDecl variable)
1477        {
1478            setData(new Callable<Object>() {
1479                public Object call() {
1480                    return attr.attribLazyConstantValue(env, variable, type);
1481                }
1482            });
1483        }
1484
1485        /**
1486         * The variable's constant value, if this is a constant.
1487         * Before the constant value is evaluated, it points to an
1488         * initializer environment.  If this is not a constant, it can
1489         * be used for other stuff.
1490         */
1491        private Object data;
1492
1493        public boolean isExceptionParameter() {
1494            return data == ElementKind.EXCEPTION_PARAMETER;
1495        }
1496
1497        public boolean isResourceVariable() {
1498            return data == ElementKind.RESOURCE_VARIABLE;
1499        }
1500
1501        public Object getConstValue() {
1502            // TODO: Consider if getConstValue and getConstantValue can be collapsed
1503            if (data == ElementKind.EXCEPTION_PARAMETER ||
1504                data == ElementKind.RESOURCE_VARIABLE) {
1505                return null;
1506            } else if (data instanceof Callable<?>) {
1507                // In this case, this is a final variable, with an as
1508                // yet unevaluated initializer.
1509                Callable<?> eval = (Callable<?>)data;
1510                data = null; // to make sure we don't evaluate this twice.
1511                try {
1512                    data = eval.call();
1513                } catch (Exception ex) {
1514                    throw new AssertionError(ex);
1515                }
1516            }
1517            return data;
1518        }
1519
1520        public void setData(Object data) {
1521            Assert.check(!(data instanceof Env<?>), this);
1522            this.data = data;
1523        }
1524
1525        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1526            return v.visitVarSymbol(this, p);
1527        }
1528    }
1529
1530    /** A class for method symbols.
1531     */
1532    public static class MethodSymbol extends Symbol implements ExecutableElement {
1533
1534        /** The code of the method. */
1535        public Code code = null;
1536
1537        /** The extra (synthetic/mandated) parameters of the method. */
1538        public List<VarSymbol> extraParams = List.nil();
1539
1540        /** The captured local variables in an anonymous class */
1541        public List<VarSymbol> capturedLocals = List.nil();
1542
1543        /** The parameters of the method. */
1544        public List<VarSymbol> params = null;
1545
1546        /** The names of the parameters */
1547        public List<Name> savedParameterNames;
1548
1549        /** For an annotation type element, its default value if any.
1550         *  The value is null if none appeared in the method
1551         *  declaration.
1552         */
1553        public Attribute defaultValue = null;
1554
1555        /** Construct a method symbol, given its flags, name, type and owner.
1556         */
1557        public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1558            super(MTH, flags, name, type, owner);
1559            if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name);
1560        }
1561
1562        /** Clone this symbol with new owner.
1563         */
1564        public MethodSymbol clone(Symbol newOwner) {
1565            MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) {
1566                @Override
1567                public Symbol baseSymbol() {
1568                    return MethodSymbol.this;
1569                }
1570            };
1571            m.code = code;
1572            return m;
1573        }
1574
1575        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1576        public Set<Modifier> getModifiers() {
1577            long flags = flags();
1578            return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags);
1579        }
1580
1581        /** The Java source which this symbol represents.
1582         */
1583        public String toString() {
1584            if ((flags() & BLOCK) != 0) {
1585                return owner.name.toString();
1586            } else {
1587                String s = (name == name.table.names.init)
1588                    ? owner.name.toString()
1589                    : name.toString();
1590                if (type != null) {
1591                    if (type.hasTag(FORALL))
1592                        s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1593                    s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1594                }
1595                return s;
1596            }
1597        }
1598
1599        public boolean isDynamic() {
1600            return false;
1601        }
1602
1603        /** find a symbol that this (proxy method) symbol implements.
1604         *  @param    c       The class whose members are searched for
1605         *                    implementations
1606         */
1607        public Symbol implemented(TypeSymbol c, Types types) {
1608            Symbol impl = null;
1609            for (List<Type> is = types.interfaces(c.type);
1610                 impl == null && is.nonEmpty();
1611                 is = is.tail) {
1612                TypeSymbol i = is.head.tsym;
1613                impl = implementedIn(i, types);
1614                if (impl == null)
1615                    impl = implemented(i, types);
1616            }
1617            return impl;
1618        }
1619
1620        public Symbol implementedIn(TypeSymbol c, Types types) {
1621            Symbol impl = null;
1622            for (Symbol sym : c.members().getSymbolsByName(name)) {
1623                if (this.overrides(sym, (TypeSymbol)owner, types, true) &&
1624                    // FIXME: I suspect the following requires a
1625                    // subst() for a parametric return type.
1626                    types.isSameType(type.getReturnType(),
1627                                     types.memberType(owner.type, sym).getReturnType())) {
1628                    impl = sym;
1629                }
1630            }
1631            return impl;
1632        }
1633
1634        /** Will the erasure of this method be considered by the VM to
1635         *  override the erasure of the other when seen from class `origin'?
1636         */
1637        public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1638            if (isConstructor() || _other.kind != MTH) return false;
1639
1640            if (this == _other) return true;
1641            MethodSymbol other = (MethodSymbol)_other;
1642
1643            // check for a direct implementation
1644            if (other.isOverridableIn((TypeSymbol)owner) &&
1645                types.asSuper(owner.type, other.owner) != null &&
1646                types.isSameType(erasure(types), other.erasure(types)))
1647                return true;
1648
1649            // check for an inherited implementation
1650            return
1651                (flags() & ABSTRACT) == 0 &&
1652                other.isOverridableIn(origin) &&
1653                this.isMemberOf(origin, types) &&
1654                types.isSameType(erasure(types), other.erasure(types));
1655        }
1656
1657        /** The implementation of this (abstract) symbol in class origin,
1658         *  from the VM's point of view, null if method does not have an
1659         *  implementation in class.
1660         *  @param origin   The class of which the implementation is a member.
1661         */
1662        public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1663            for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1664                for (Symbol sym : c.members().getSymbolsByName(name)) {
1665                    if (sym.kind == MTH &&
1666                        ((MethodSymbol)sym).binaryOverrides(this, origin, types))
1667                        return (MethodSymbol)sym;
1668                }
1669            }
1670            return null;
1671        }
1672
1673        /** Does this symbol override `other' symbol, when both are seen as
1674         *  members of class `origin'?  It is assumed that _other is a member
1675         *  of origin.
1676         *
1677         *  It is assumed that both symbols have the same name.  The static
1678         *  modifier is ignored for this test.
1679         *
1680         *  A quirk in the works is that if the receiver is a method symbol for
1681         *  an inherited abstract method we answer false summarily all else being
1682         *  immaterial. Abstract "own" methods (i.e `this' is a direct member of
1683         *  origin) don't get rejected as summarily and are put to test against the
1684         *  suitable criteria.
1685         *
1686         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1687         */
1688        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1689            return overrides(_other, origin, types, checkResult, true);
1690        }
1691
1692        /** Does this symbol override `other' symbol, when both are seen as
1693         *  members of class `origin'?  It is assumed that _other is a member
1694         *  of origin.
1695         *
1696         *  Caveat: If `this' is an abstract inherited member of origin, it is
1697         *  deemed to override `other' only when `requireConcreteIfInherited'
1698         *  is false.
1699         *
1700         *  It is assumed that both symbols have the same name.  The static
1701         *  modifier is ignored for this test.
1702         *
1703         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1704         */
1705        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult,
1706                                            boolean requireConcreteIfInherited) {
1707            if (isConstructor() || _other.kind != MTH) return false;
1708
1709            if (this == _other) return true;
1710            MethodSymbol other = (MethodSymbol)_other;
1711
1712            // check for a direct implementation
1713            if (other.isOverridableIn((TypeSymbol)owner) &&
1714                types.asSuper(owner.type, other.owner) != null) {
1715                Type mt = types.memberType(owner.type, this);
1716                Type ot = types.memberType(owner.type, other);
1717                if (types.isSubSignature(mt, ot)) {
1718                    if (!checkResult)
1719                        return true;
1720                    if (types.returnTypeSubstitutable(mt, ot))
1721                        return true;
1722                }
1723            }
1724
1725            // check for an inherited implementation
1726            if (((flags() & ABSTRACT) != 0 && requireConcreteIfInherited) ||
1727                    ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
1728                    !other.isOverridableIn(origin) ||
1729                    !this.isMemberOf(origin, types))
1730                return false;
1731
1732            // assert types.asSuper(origin.type, other.owner) != null;
1733            Type mt = types.memberType(origin.type, this);
1734            Type ot = types.memberType(origin.type, other);
1735            return
1736                types.isSubSignature(mt, ot) &&
1737                (!checkResult || types.resultSubtype(mt, ot, types.noWarnings));
1738        }
1739
1740        private boolean isOverridableIn(TypeSymbol origin) {
1741            // JLS 8.4.6.1
1742            switch ((int)(flags_field & Flags.AccessFlags)) {
1743            case Flags.PRIVATE:
1744                return false;
1745            case Flags.PUBLIC:
1746                return !this.owner.isInterface() ||
1747                        (flags_field & STATIC) == 0;
1748            case Flags.PROTECTED:
1749                return (origin.flags() & INTERFACE) == 0;
1750            case 0:
1751                // for package private: can only override in the same
1752                // package
1753                return
1754                    this.packge() == origin.packge() &&
1755                    (origin.flags() & INTERFACE) == 0;
1756            default:
1757                return false;
1758            }
1759        }
1760
1761        @Override
1762        public boolean isInheritedIn(Symbol clazz, Types types) {
1763            switch ((int)(flags_field & Flags.AccessFlags)) {
1764                case PUBLIC:
1765                    return !this.owner.isInterface() ||
1766                            clazz == owner ||
1767                            (flags_field & STATIC) == 0;
1768                default:
1769                    return super.isInheritedIn(clazz, types);
1770            }
1771        }
1772
1773        public boolean isLambdaMethod() {
1774            return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD;
1775        }
1776
1777        /** The implementation of this (abstract) symbol in class origin;
1778         *  null if none exists. Synthetic methods are not considered
1779         *  as possible implementations.
1780         */
1781        public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1782            return implementation(origin, types, checkResult, implementation_filter);
1783        }
1784        // where
1785            public static final Filter<Symbol> implementation_filter = new Filter<Symbol>() {
1786                public boolean accepts(Symbol s) {
1787                    return s.kind == MTH &&
1788                            (s.flags() & SYNTHETIC) == 0;
1789                }
1790            };
1791
1792        public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
1793            MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
1794            if (res != null)
1795                return res;
1796            // if origin is derived from a raw type, we might have missed
1797            // an implementation because we do not know enough about instantiations.
1798            // in this case continue with the supertype as origin.
1799            if (types.isDerivedRaw(origin.type) && !origin.isInterface())
1800                return implementation(types.supertype(origin.type).tsym, types, checkResult);
1801            else
1802                return null;
1803        }
1804
1805        public List<VarSymbol> params() {
1806            owner.complete();
1807            if (params == null) {
1808                // If ClassReader.saveParameterNames has been set true, then
1809                // savedParameterNames will be set to a list of names that
1810                // matches the types in type.getParameterTypes().  If any names
1811                // were not found in the class file, those names in the list will
1812                // be set to the empty name.
1813                // If ClassReader.saveParameterNames has been set false, then
1814                // savedParameterNames will be null.
1815                List<Name> paramNames = savedParameterNames;
1816                savedParameterNames = null;
1817                // discard the provided names if the list of names is the wrong size.
1818                if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) {
1819                    paramNames = List.nil();
1820                }
1821                ListBuffer<VarSymbol> buf = new ListBuffer<>();
1822                List<Name> remaining = paramNames;
1823                // assert: remaining and paramNames are both empty or both
1824                // have same cardinality as type.getParameterTypes()
1825                int i = 0;
1826                for (Type t : type.getParameterTypes()) {
1827                    Name paramName;
1828                    if (remaining.isEmpty()) {
1829                        // no names for any parameters available
1830                        paramName = createArgName(i, paramNames);
1831                    } else {
1832                        paramName = remaining.head;
1833                        remaining = remaining.tail;
1834                        if (paramName.isEmpty()) {
1835                            // no name for this specific parameter
1836                            paramName = createArgName(i, paramNames);
1837                        }
1838                    }
1839                    buf.append(new VarSymbol(PARAMETER, paramName, t, this));
1840                    i++;
1841                }
1842                params = buf.toList();
1843            }
1844            return params;
1845        }
1846
1847        // Create a name for the argument at position 'index' that is not in
1848        // the exclude list. In normal use, either no names will have been
1849        // provided, in which case the exclude list is empty, or all the names
1850        // will have been provided, in which case this method will not be called.
1851        private Name createArgName(int index, List<Name> exclude) {
1852            String prefix = "arg";
1853            while (true) {
1854                Name argName = name.table.fromString(prefix + index);
1855                if (!exclude.contains(argName))
1856                    return argName;
1857                prefix += "$";
1858            }
1859        }
1860
1861        public Symbol asMemberOf(Type site, Types types) {
1862            return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1863        }
1864
1865        @DefinedBy(Api.LANGUAGE_MODEL)
1866        public ElementKind getKind() {
1867            if (name == name.table.names.init)
1868                return ElementKind.CONSTRUCTOR;
1869            else if (name == name.table.names.clinit)
1870                return ElementKind.STATIC_INIT;
1871            else if ((flags() & BLOCK) != 0)
1872                return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT;
1873            else
1874                return ElementKind.METHOD;
1875        }
1876
1877        public boolean isStaticOrInstanceInit() {
1878            return getKind() == ElementKind.STATIC_INIT ||
1879                    getKind() == ElementKind.INSTANCE_INIT;
1880        }
1881
1882        @DefinedBy(Api.LANGUAGE_MODEL)
1883        public Attribute getDefaultValue() {
1884            return defaultValue;
1885        }
1886
1887        @DefinedBy(Api.LANGUAGE_MODEL)
1888        public List<VarSymbol> getParameters() {
1889            return params();
1890        }
1891
1892        @DefinedBy(Api.LANGUAGE_MODEL)
1893        public boolean isVarArgs() {
1894            return (flags() & VARARGS) != 0;
1895        }
1896
1897        @DefinedBy(Api.LANGUAGE_MODEL)
1898        public boolean isDefault() {
1899            return (flags() & DEFAULT) != 0;
1900        }
1901
1902        @DefinedBy(Api.LANGUAGE_MODEL)
1903        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1904            return v.visitExecutable(this, p);
1905        }
1906
1907        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1908            return v.visitMethodSymbol(this, p);
1909        }
1910
1911        @DefinedBy(Api.LANGUAGE_MODEL)
1912        public Type getReceiverType() {
1913            return asType().getReceiverType();
1914        }
1915
1916        @DefinedBy(Api.LANGUAGE_MODEL)
1917        public Type getReturnType() {
1918            return asType().getReturnType();
1919        }
1920
1921        @DefinedBy(Api.LANGUAGE_MODEL)
1922        public List<Type> getThrownTypes() {
1923            return asType().getThrownTypes();
1924        }
1925    }
1926
1927    /** A class for invokedynamic method calls.
1928     */
1929    public static class DynamicMethodSymbol extends MethodSymbol {
1930
1931        public Object[] staticArgs;
1932        public Symbol bsm;
1933        public int bsmKind;
1934
1935        public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
1936            super(0, name, type, owner);
1937            this.bsm = bsm;
1938            this.bsmKind = bsmKind;
1939            this.staticArgs = staticArgs;
1940        }
1941
1942        @Override
1943        public boolean isDynamic() {
1944            return true;
1945        }
1946    }
1947
1948    /** A class for predefined operators.
1949     */
1950    public static class OperatorSymbol extends MethodSymbol {
1951
1952        public int opcode;
1953
1954        public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1955            super(PUBLIC | STATIC, name, type, owner);
1956            this.opcode = opcode;
1957        }
1958
1959        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1960            return v.visitOperatorSymbol(this, p);
1961        }
1962    }
1963
1964    /** Symbol completer interface.
1965     */
1966    public static interface Completer {
1967
1968        /** Dummy completer to be used when the symbol has been completed or
1969         * does not need completion.
1970         */
1971        public final static Completer NULL_COMPLETER = new Completer() {
1972            public void complete(Symbol sym) { }
1973            public boolean isTerminal() { return true; }
1974        };
1975
1976        void complete(Symbol sym) throws CompletionFailure;
1977
1978        /** Returns true if this completer is <em>terminal</em>. A terminal
1979         * completer is used as a place holder when the symbol is completed.
1980         * Calling complete on a terminal completer will not affect the symbol.
1981         *
1982         * The dummy NULL_COMPLETER and the GraphDependencies completer are
1983         * examples of terminal completers.
1984         *
1985         * @return true iff this completer is terminal
1986         */
1987        default boolean isTerminal() {
1988            return false;
1989        }
1990    }
1991
1992    public static class CompletionFailure extends RuntimeException {
1993        private static final long serialVersionUID = 0;
1994        public Symbol sym;
1995
1996        /** A diagnostic object describing the failure
1997         */
1998        public JCDiagnostic diag;
1999
2000        /** A localized string describing the failure.
2001         * @deprecated Use {@code getDetail()} or {@code getMessage()}
2002         */
2003        @Deprecated
2004        public String errmsg;
2005
2006        public CompletionFailure(Symbol sym, String errmsg) {
2007            this.sym = sym;
2008            this.errmsg = errmsg;
2009//          this.printStackTrace();//DEBUG
2010        }
2011
2012        public CompletionFailure(Symbol sym, JCDiagnostic diag) {
2013            this.sym = sym;
2014            this.diag = diag;
2015//          this.printStackTrace();//DEBUG
2016        }
2017
2018        public JCDiagnostic getDiagnostic() {
2019            return diag;
2020        }
2021
2022        @Override
2023        public String getMessage() {
2024            if (diag != null)
2025                return diag.getMessage(null);
2026            else
2027                return errmsg;
2028        }
2029
2030        public Object getDetailValue() {
2031            return (diag != null ? diag : errmsg);
2032        }
2033
2034        @Override
2035        public CompletionFailure initCause(Throwable cause) {
2036            super.initCause(cause);
2037            return this;
2038        }
2039
2040    }
2041
2042    /**
2043     * A visitor for symbols.  A visitor is used to implement operations
2044     * (or relations) on symbols.  Most common operations on types are
2045     * binary relations and this interface is designed for binary
2046     * relations, that is, operations on the form
2047     * Symbol&nbsp;&times;&nbsp;P&nbsp;&rarr;&nbsp;R.
2048     * <!-- In plain text: Type x P -> R -->
2049     *
2050     * @param <R> the return type of the operation implemented by this
2051     * visitor; use Void if no return type is needed.
2052     * @param <P> the type of the second argument (the first being the
2053     * symbol itself) of the operation implemented by this visitor; use
2054     * Void if a second argument is not needed.
2055     */
2056    public interface Visitor<R,P> {
2057        R visitClassSymbol(ClassSymbol s, P arg);
2058        R visitMethodSymbol(MethodSymbol s, P arg);
2059        R visitPackageSymbol(PackageSymbol s, P arg);
2060        R visitOperatorSymbol(OperatorSymbol s, P arg);
2061        R visitVarSymbol(VarSymbol s, P arg);
2062        R visitTypeSymbol(TypeSymbol s, P arg);
2063        R visitSymbol(Symbol s, P arg);
2064    }
2065}
2066