Symbol.java revision 3376:4c740bddc648
1/*
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.javac.code;
27
28import java.lang.annotation.Annotation;
29import java.lang.annotation.Inherited;
30import java.util.Collections;
31import java.util.Map;
32import java.util.Set;
33import java.util.concurrent.Callable;
34
35import javax.lang.model.element.Element;
36import javax.lang.model.element.ElementKind;
37import javax.lang.model.element.ElementVisitor;
38import javax.lang.model.element.ExecutableElement;
39import javax.lang.model.element.Modifier;
40import javax.lang.model.element.ModuleElement;
41import javax.lang.model.element.NestingKind;
42import javax.lang.model.element.PackageElement;
43import javax.lang.model.element.TypeElement;
44import javax.lang.model.element.TypeParameterElement;
45import javax.lang.model.element.VariableElement;
46import javax.tools.JavaFileManager;
47import javax.tools.JavaFileObject;
48
49import com.sun.tools.javac.code.ClassFinder.BadEnclosingMethodAttr;
50import com.sun.tools.javac.code.Kinds.Kind;
51import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
52import com.sun.tools.javac.code.Scope.WriteableScope;
53import com.sun.tools.javac.code.Type.*;
54import com.sun.tools.javac.comp.Attr;
55import com.sun.tools.javac.comp.AttrContext;
56import com.sun.tools.javac.comp.Env;
57import com.sun.tools.javac.jvm.*;
58import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
59import com.sun.tools.javac.util.*;
60import com.sun.tools.javac.util.DefinedBy.Api;
61import com.sun.tools.javac.util.Name;
62
63import static com.sun.tools.javac.code.Flags.*;
64import 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            metadata = null;
1371            annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1372        }
1373
1374        @Override
1375        public AnnotationTypeMetadata getAnnotationTypeMetadata() {
1376            return annotationTypeMetadata;
1377        }
1378
1379        @Override
1380        public boolean isAnnotationType() {
1381            return (flags_field & Flags.ANNOTATION) != 0;
1382        }
1383
1384        public void setAnnotationTypeMetadata(AnnotationTypeMetadata a) {
1385            Assert.checkNonNull(a);
1386            Assert.check(!annotationTypeMetadata.isMetadataForAnnotationType());
1387            this.annotationTypeMetadata = a;
1388        }
1389    }
1390
1391
1392    /** A class for variable symbols
1393     */
1394    public static class VarSymbol extends Symbol implements VariableElement {
1395
1396        /** The variable's declaration position.
1397         */
1398        public int pos = Position.NOPOS;
1399
1400        /** The variable's address. Used for different purposes during
1401         *  flow analysis, translation and code generation.
1402         *  Flow analysis:
1403         *    If this is a blank final or local variable, its sequence number.
1404         *  Translation:
1405         *    If this is a private field, its access number.
1406         *  Code generation:
1407         *    If this is a local variable, its logical slot number.
1408         */
1409        public int adr = -1;
1410
1411        /** Construct a variable symbol, given its flags, name, type and owner.
1412         */
1413        public VarSymbol(long flags, Name name, Type type, Symbol owner) {
1414            super(VAR, flags, name, type, owner);
1415        }
1416
1417        /** Clone this symbol with new owner.
1418         */
1419        public VarSymbol clone(Symbol newOwner) {
1420            VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) {
1421                @Override
1422                public Symbol baseSymbol() {
1423                    return VarSymbol.this;
1424                }
1425            };
1426            v.pos = pos;
1427            v.adr = adr;
1428            v.data = data;
1429//          System.out.println("clone " + v + " in " + newOwner);//DEBUG
1430            return v;
1431        }
1432
1433        public String toString() {
1434            return name.toString();
1435        }
1436
1437        public Symbol asMemberOf(Type site, Types types) {
1438            return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
1439        }
1440
1441        @DefinedBy(Api.LANGUAGE_MODEL)
1442        public ElementKind getKind() {
1443            long flags = flags();
1444            if ((flags & PARAMETER) != 0) {
1445                if (isExceptionParameter())
1446                    return ElementKind.EXCEPTION_PARAMETER;
1447                else
1448                    return ElementKind.PARAMETER;
1449            } else if ((flags & ENUM) != 0) {
1450                return ElementKind.ENUM_CONSTANT;
1451            } else if (owner.kind == TYP || owner.kind == ERR) {
1452                return ElementKind.FIELD;
1453            } else if (isResourceVariable()) {
1454                return ElementKind.RESOURCE_VARIABLE;
1455            } else {
1456                return ElementKind.LOCAL_VARIABLE;
1457            }
1458        }
1459
1460        @DefinedBy(Api.LANGUAGE_MODEL)
1461        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1462            return v.visitVariable(this, p);
1463        }
1464
1465        @DefinedBy(Api.LANGUAGE_MODEL)
1466        public Object getConstantValue() { // Mirror API
1467            return Constants.decode(getConstValue(), type);
1468        }
1469
1470        public void setLazyConstValue(final Env<AttrContext> env,
1471                                      final Attr attr,
1472                                      final JCVariableDecl variable)
1473        {
1474            setData(new Callable<Object>() {
1475                public Object call() {
1476                    return attr.attribLazyConstantValue(env, variable, type);
1477                }
1478            });
1479        }
1480
1481        /**
1482         * The variable's constant value, if this is a constant.
1483         * Before the constant value is evaluated, it points to an
1484         * initializer environment.  If this is not a constant, it can
1485         * be used for other stuff.
1486         */
1487        private Object data;
1488
1489        public boolean isExceptionParameter() {
1490            return data == ElementKind.EXCEPTION_PARAMETER;
1491        }
1492
1493        public boolean isResourceVariable() {
1494            return data == ElementKind.RESOURCE_VARIABLE;
1495        }
1496
1497        public Object getConstValue() {
1498            // TODO: Consider if getConstValue and getConstantValue can be collapsed
1499            if (data == ElementKind.EXCEPTION_PARAMETER ||
1500                data == ElementKind.RESOURCE_VARIABLE) {
1501                return null;
1502            } else if (data instanceof Callable<?>) {
1503                // In this case, this is a final variable, with an as
1504                // yet unevaluated initializer.
1505                Callable<?> eval = (Callable<?>)data;
1506                data = null; // to make sure we don't evaluate this twice.
1507                try {
1508                    data = eval.call();
1509                } catch (Exception ex) {
1510                    throw new AssertionError(ex);
1511                }
1512            }
1513            return data;
1514        }
1515
1516        public void setData(Object data) {
1517            Assert.check(!(data instanceof Env<?>), this);
1518            this.data = data;
1519        }
1520
1521        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1522            return v.visitVarSymbol(this, p);
1523        }
1524    }
1525
1526    /** A class for method symbols.
1527     */
1528    public static class MethodSymbol extends Symbol implements ExecutableElement {
1529
1530        /** The code of the method. */
1531        public Code code = null;
1532
1533        /** The extra (synthetic/mandated) parameters of the method. */
1534        public List<VarSymbol> extraParams = List.nil();
1535
1536        /** The captured local variables in an anonymous class */
1537        public List<VarSymbol> capturedLocals = List.nil();
1538
1539        /** The parameters of the method. */
1540        public List<VarSymbol> params = null;
1541
1542        /** The names of the parameters */
1543        public List<Name> savedParameterNames;
1544
1545        /** For an annotation type element, its default value if any.
1546         *  The value is null if none appeared in the method
1547         *  declaration.
1548         */
1549        public Attribute defaultValue = null;
1550
1551        /** Construct a method symbol, given its flags, name, type and owner.
1552         */
1553        public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1554            super(MTH, flags, name, type, owner);
1555            if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name);
1556        }
1557
1558        /** Clone this symbol with new owner.
1559         */
1560        public MethodSymbol clone(Symbol newOwner) {
1561            MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) {
1562                @Override
1563                public Symbol baseSymbol() {
1564                    return MethodSymbol.this;
1565                }
1566            };
1567            m.code = code;
1568            return m;
1569        }
1570
1571        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1572        public Set<Modifier> getModifiers() {
1573            long flags = flags();
1574            return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags);
1575        }
1576
1577        /** The Java source which this symbol represents.
1578         */
1579        public String toString() {
1580            if ((flags() & BLOCK) != 0) {
1581                return owner.name.toString();
1582            } else {
1583                String s = (name == name.table.names.init)
1584                    ? owner.name.toString()
1585                    : name.toString();
1586                if (type != null) {
1587                    if (type.hasTag(FORALL))
1588                        s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1589                    s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1590                }
1591                return s;
1592            }
1593        }
1594
1595        public boolean isDynamic() {
1596            return false;
1597        }
1598
1599        /** find a symbol that this (proxy method) symbol implements.
1600         *  @param    c       The class whose members are searched for
1601         *                    implementations
1602         */
1603        public Symbol implemented(TypeSymbol c, Types types) {
1604            Symbol impl = null;
1605            for (List<Type> is = types.interfaces(c.type);
1606                 impl == null && is.nonEmpty();
1607                 is = is.tail) {
1608                TypeSymbol i = is.head.tsym;
1609                impl = implementedIn(i, types);
1610                if (impl == null)
1611                    impl = implemented(i, types);
1612            }
1613            return impl;
1614        }
1615
1616        public Symbol implementedIn(TypeSymbol c, Types types) {
1617            Symbol impl = null;
1618            for (Symbol sym : c.members().getSymbolsByName(name)) {
1619                if (this.overrides(sym, (TypeSymbol)owner, types, true) &&
1620                    // FIXME: I suspect the following requires a
1621                    // subst() for a parametric return type.
1622                    types.isSameType(type.getReturnType(),
1623                                     types.memberType(owner.type, sym).getReturnType())) {
1624                    impl = sym;
1625                }
1626            }
1627            return impl;
1628        }
1629
1630        /** Will the erasure of this method be considered by the VM to
1631         *  override the erasure of the other when seen from class `origin'?
1632         */
1633        public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1634            if (isConstructor() || _other.kind != MTH) return false;
1635
1636            if (this == _other) return true;
1637            MethodSymbol other = (MethodSymbol)_other;
1638
1639            // check for a direct implementation
1640            if (other.isOverridableIn((TypeSymbol)owner) &&
1641                types.asSuper(owner.type, other.owner) != null &&
1642                types.isSameType(erasure(types), other.erasure(types)))
1643                return true;
1644
1645            // check for an inherited implementation
1646            return
1647                (flags() & ABSTRACT) == 0 &&
1648                other.isOverridableIn(origin) &&
1649                this.isMemberOf(origin, types) &&
1650                types.isSameType(erasure(types), other.erasure(types));
1651        }
1652
1653        /** The implementation of this (abstract) symbol in class origin,
1654         *  from the VM's point of view, null if method does not have an
1655         *  implementation in class.
1656         *  @param origin   The class of which the implementation is a member.
1657         */
1658        public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1659            for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1660                for (Symbol sym : c.members().getSymbolsByName(name)) {
1661                    if (sym.kind == MTH &&
1662                        ((MethodSymbol)sym).binaryOverrides(this, origin, types))
1663                        return (MethodSymbol)sym;
1664                }
1665            }
1666            return null;
1667        }
1668
1669        /** Does this symbol override `other' symbol, when both are seen as
1670         *  members of class `origin'?  It is assumed that _other is a member
1671         *  of origin.
1672         *
1673         *  It is assumed that both symbols have the same name.  The static
1674         *  modifier is ignored for this test.
1675         *
1676         *  A quirk in the works is that if the receiver is a method symbol for
1677         *  an inherited abstract method we answer false summarily all else being
1678         *  immaterial. Abstract "own" methods (i.e `this' is a direct member of
1679         *  origin) don't get rejected as summarily and are put to test against the
1680         *  suitable criteria.
1681         *
1682         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1683         */
1684        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1685            return overrides(_other, origin, types, checkResult, true);
1686        }
1687
1688        /** Does this symbol override `other' symbol, when both are seen as
1689         *  members of class `origin'?  It is assumed that _other is a member
1690         *  of origin.
1691         *
1692         *  Caveat: If `this' is an abstract inherited member of origin, it is
1693         *  deemed to override `other' only when `requireConcreteIfInherited'
1694         *  is false.
1695         *
1696         *  It is assumed that both symbols have the same name.  The static
1697         *  modifier is ignored for this test.
1698         *
1699         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1700         */
1701        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult,
1702                                            boolean requireConcreteIfInherited) {
1703            if (isConstructor() || _other.kind != MTH) return false;
1704
1705            if (this == _other) return true;
1706            MethodSymbol other = (MethodSymbol)_other;
1707
1708            // check for a direct implementation
1709            if (other.isOverridableIn((TypeSymbol)owner) &&
1710                types.asSuper(owner.type, other.owner) != null) {
1711                Type mt = types.memberType(owner.type, this);
1712                Type ot = types.memberType(owner.type, other);
1713                if (types.isSubSignature(mt, ot)) {
1714                    if (!checkResult)
1715                        return true;
1716                    if (types.returnTypeSubstitutable(mt, ot))
1717                        return true;
1718                }
1719            }
1720
1721            // check for an inherited implementation
1722            if (((flags() & ABSTRACT) != 0 && requireConcreteIfInherited) ||
1723                    ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
1724                    !other.isOverridableIn(origin) ||
1725                    !this.isMemberOf(origin, types))
1726                return false;
1727
1728            // assert types.asSuper(origin.type, other.owner) != null;
1729            Type mt = types.memberType(origin.type, this);
1730            Type ot = types.memberType(origin.type, other);
1731            return
1732                types.isSubSignature(mt, ot) &&
1733                (!checkResult || types.resultSubtype(mt, ot, types.noWarnings));
1734        }
1735
1736        private boolean isOverridableIn(TypeSymbol origin) {
1737            // JLS 8.4.6.1
1738            switch ((int)(flags_field & Flags.AccessFlags)) {
1739            case Flags.PRIVATE:
1740                return false;
1741            case Flags.PUBLIC:
1742                return !this.owner.isInterface() ||
1743                        (flags_field & STATIC) == 0;
1744            case Flags.PROTECTED:
1745                return (origin.flags() & INTERFACE) == 0;
1746            case 0:
1747                // for package private: can only override in the same
1748                // package
1749                return
1750                    this.packge() == origin.packge() &&
1751                    (origin.flags() & INTERFACE) == 0;
1752            default:
1753                return false;
1754            }
1755        }
1756
1757        @Override
1758        public boolean isInheritedIn(Symbol clazz, Types types) {
1759            switch ((int)(flags_field & Flags.AccessFlags)) {
1760                case PUBLIC:
1761                    return !this.owner.isInterface() ||
1762                            clazz == owner ||
1763                            (flags_field & STATIC) == 0;
1764                default:
1765                    return super.isInheritedIn(clazz, types);
1766            }
1767        }
1768
1769        public boolean isLambdaMethod() {
1770            return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD;
1771        }
1772
1773        /** The implementation of this (abstract) symbol in class origin;
1774         *  null if none exists. Synthetic methods are not considered
1775         *  as possible implementations.
1776         */
1777        public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1778            return implementation(origin, types, checkResult, implementation_filter);
1779        }
1780        // where
1781            public static final Filter<Symbol> implementation_filter = new Filter<Symbol>() {
1782                public boolean accepts(Symbol s) {
1783                    return s.kind == MTH &&
1784                            (s.flags() & SYNTHETIC) == 0;
1785                }
1786            };
1787
1788        public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
1789            MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
1790            if (res != null)
1791                return res;
1792            // if origin is derived from a raw type, we might have missed
1793            // an implementation because we do not know enough about instantiations.
1794            // in this case continue with the supertype as origin.
1795            if (types.isDerivedRaw(origin.type) && !origin.isInterface())
1796                return implementation(types.supertype(origin.type).tsym, types, checkResult);
1797            else
1798                return null;
1799        }
1800
1801        public List<VarSymbol> params() {
1802            owner.complete();
1803            if (params == null) {
1804                // If ClassReader.saveParameterNames has been set true, then
1805                // savedParameterNames will be set to a list of names that
1806                // matches the types in type.getParameterTypes().  If any names
1807                // were not found in the class file, those names in the list will
1808                // be set to the empty name.
1809                // If ClassReader.saveParameterNames has been set false, then
1810                // savedParameterNames will be null.
1811                List<Name> paramNames = savedParameterNames;
1812                savedParameterNames = null;
1813                // discard the provided names if the list of names is the wrong size.
1814                if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) {
1815                    paramNames = List.nil();
1816                }
1817                ListBuffer<VarSymbol> buf = new ListBuffer<>();
1818                List<Name> remaining = paramNames;
1819                // assert: remaining and paramNames are both empty or both
1820                // have same cardinality as type.getParameterTypes()
1821                int i = 0;
1822                for (Type t : type.getParameterTypes()) {
1823                    Name paramName;
1824                    if (remaining.isEmpty()) {
1825                        // no names for any parameters available
1826                        paramName = createArgName(i, paramNames);
1827                    } else {
1828                        paramName = remaining.head;
1829                        remaining = remaining.tail;
1830                        if (paramName.isEmpty()) {
1831                            // no name for this specific parameter
1832                            paramName = createArgName(i, paramNames);
1833                        }
1834                    }
1835                    buf.append(new VarSymbol(PARAMETER, paramName, t, this));
1836                    i++;
1837                }
1838                params = buf.toList();
1839            }
1840            return params;
1841        }
1842
1843        // Create a name for the argument at position 'index' that is not in
1844        // the exclude list. In normal use, either no names will have been
1845        // provided, in which case the exclude list is empty, or all the names
1846        // will have been provided, in which case this method will not be called.
1847        private Name createArgName(int index, List<Name> exclude) {
1848            String prefix = "arg";
1849            while (true) {
1850                Name argName = name.table.fromString(prefix + index);
1851                if (!exclude.contains(argName))
1852                    return argName;
1853                prefix += "$";
1854            }
1855        }
1856
1857        public Symbol asMemberOf(Type site, Types types) {
1858            return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1859        }
1860
1861        @DefinedBy(Api.LANGUAGE_MODEL)
1862        public ElementKind getKind() {
1863            if (name == name.table.names.init)
1864                return ElementKind.CONSTRUCTOR;
1865            else if (name == name.table.names.clinit)
1866                return ElementKind.STATIC_INIT;
1867            else if ((flags() & BLOCK) != 0)
1868                return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT;
1869            else
1870                return ElementKind.METHOD;
1871        }
1872
1873        public boolean isStaticOrInstanceInit() {
1874            return getKind() == ElementKind.STATIC_INIT ||
1875                    getKind() == ElementKind.INSTANCE_INIT;
1876        }
1877
1878        @DefinedBy(Api.LANGUAGE_MODEL)
1879        public Attribute getDefaultValue() {
1880            return defaultValue;
1881        }
1882
1883        @DefinedBy(Api.LANGUAGE_MODEL)
1884        public List<VarSymbol> getParameters() {
1885            return params();
1886        }
1887
1888        @DefinedBy(Api.LANGUAGE_MODEL)
1889        public boolean isVarArgs() {
1890            return (flags() & VARARGS) != 0;
1891        }
1892
1893        @DefinedBy(Api.LANGUAGE_MODEL)
1894        public boolean isDefault() {
1895            return (flags() & DEFAULT) != 0;
1896        }
1897
1898        @DefinedBy(Api.LANGUAGE_MODEL)
1899        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1900            return v.visitExecutable(this, p);
1901        }
1902
1903        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1904            return v.visitMethodSymbol(this, p);
1905        }
1906
1907        @DefinedBy(Api.LANGUAGE_MODEL)
1908        public Type getReceiverType() {
1909            return asType().getReceiverType();
1910        }
1911
1912        @DefinedBy(Api.LANGUAGE_MODEL)
1913        public Type getReturnType() {
1914            return asType().getReturnType();
1915        }
1916
1917        @DefinedBy(Api.LANGUAGE_MODEL)
1918        public List<Type> getThrownTypes() {
1919            return asType().getThrownTypes();
1920        }
1921    }
1922
1923    /** A class for invokedynamic method calls.
1924     */
1925    public static class DynamicMethodSymbol extends MethodSymbol {
1926
1927        public Object[] staticArgs;
1928        public Symbol bsm;
1929        public int bsmKind;
1930
1931        public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
1932            super(0, name, type, owner);
1933            this.bsm = bsm;
1934            this.bsmKind = bsmKind;
1935            this.staticArgs = staticArgs;
1936        }
1937
1938        @Override
1939        public boolean isDynamic() {
1940            return true;
1941        }
1942    }
1943
1944    /** A class for predefined operators.
1945     */
1946    public static class OperatorSymbol extends MethodSymbol {
1947
1948        public int opcode;
1949
1950        public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1951            super(PUBLIC | STATIC, name, type, owner);
1952            this.opcode = opcode;
1953        }
1954
1955        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1956            return v.visitOperatorSymbol(this, p);
1957        }
1958    }
1959
1960    /** Symbol completer interface.
1961     */
1962    public static interface Completer {
1963
1964        /** Dummy completer to be used when the symbol has been completed or
1965         * does not need completion.
1966         */
1967        public final static Completer NULL_COMPLETER = new Completer() {
1968            public void complete(Symbol sym) { }
1969            public boolean isTerminal() { return true; }
1970        };
1971
1972        void complete(Symbol sym) throws CompletionFailure;
1973
1974        /** Returns true if this completer is <em>terminal</em>. A terminal
1975         * completer is used as a place holder when the symbol is completed.
1976         * Calling complete on a terminal completer will not affect the symbol.
1977         *
1978         * The dummy NULL_COMPLETER and the GraphDependencies completer are
1979         * examples of terminal completers.
1980         *
1981         * @return true iff this completer is terminal
1982         */
1983        default boolean isTerminal() {
1984            return false;
1985        }
1986    }
1987
1988    public static class CompletionFailure extends RuntimeException {
1989        private static final long serialVersionUID = 0;
1990        public Symbol sym;
1991
1992        /** A diagnostic object describing the failure
1993         */
1994        public JCDiagnostic diag;
1995
1996        /** A localized string describing the failure.
1997         * @deprecated Use {@code getDetail()} or {@code getMessage()}
1998         */
1999        @Deprecated
2000        public String errmsg;
2001
2002        public CompletionFailure(Symbol sym, String errmsg) {
2003            this.sym = sym;
2004            this.errmsg = errmsg;
2005//          this.printStackTrace();//DEBUG
2006        }
2007
2008        public CompletionFailure(Symbol sym, JCDiagnostic diag) {
2009            this.sym = sym;
2010            this.diag = diag;
2011//          this.printStackTrace();//DEBUG
2012        }
2013
2014        public JCDiagnostic getDiagnostic() {
2015            return diag;
2016        }
2017
2018        @Override
2019        public String getMessage() {
2020            if (diag != null)
2021                return diag.getMessage(null);
2022            else
2023                return errmsg;
2024        }
2025
2026        public Object getDetailValue() {
2027            return (diag != null ? diag : errmsg);
2028        }
2029
2030        @Override
2031        public CompletionFailure initCause(Throwable cause) {
2032            super.initCause(cause);
2033            return this;
2034        }
2035
2036    }
2037
2038    /**
2039     * A visitor for symbols.  A visitor is used to implement operations
2040     * (or relations) on symbols.  Most common operations on types are
2041     * binary relations and this interface is designed for binary
2042     * relations, that is, operations on the form
2043     * Symbol&nbsp;&times;&nbsp;P&nbsp;&rarr;&nbsp;R.
2044     * <!-- In plain text: Type x P -> R -->
2045     *
2046     * @param <R> the return type of the operation implemented by this
2047     * visitor; use Void if no return type is needed.
2048     * @param <P> the type of the second argument (the first being the
2049     * symbol itself) of the operation implemented by this visitor; use
2050     * Void if a second argument is not needed.
2051     */
2052    public interface Visitor<R,P> {
2053        R visitClassSymbol(ClassSymbol s, P arg);
2054        R visitMethodSymbol(MethodSymbol s, P arg);
2055        R visitPackageSymbol(PackageSymbol s, P arg);
2056        R visitOperatorSymbol(OperatorSymbol s, P arg);
2057        R visitVarSymbol(VarSymbol s, P arg);
2058        R visitTypeSymbol(TypeSymbol s, P arg);
2059        R visitSymbol(Symbol s, P arg);
2060    }
2061}
2062