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