Symbol.java revision 3930:a21e5b9dc5c3
1/*
2 * Copyright (c) 1999, 2017, 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.EnumSet;
32import java.util.Map;
33import java.util.Set;
34import java.util.concurrent.Callable;
35
36import javax.lang.model.element.Element;
37import javax.lang.model.element.ElementKind;
38import javax.lang.model.element.ElementVisitor;
39import javax.lang.model.element.ExecutableElement;
40import javax.lang.model.element.Modifier;
41import javax.lang.model.element.ModuleElement;
42import javax.lang.model.element.NestingKind;
43import javax.lang.model.element.PackageElement;
44import javax.lang.model.element.TypeElement;
45import javax.lang.model.element.TypeParameterElement;
46import javax.lang.model.element.VariableElement;
47import javax.tools.JavaFileManager;
48import javax.tools.JavaFileObject;
49
50import com.sun.tools.javac.code.ClassFinder.BadEnclosingMethodAttr;
51import 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 isOpen() {
952            return flags.contains(ModuleFlags.OPEN);
953        }
954
955        @Override @DefinedBy(Api.LANGUAGE_MODEL)
956        public boolean isUnnamed() {
957            return name.isEmpty() && owner == null;
958        }
959
960        @Override
961        public boolean isDeprecated() {
962            return hasDeprecatedAnnotation();
963        }
964
965        public boolean isNoModule() {
966            return false;
967        }
968
969        @Override @DefinedBy(Api.LANGUAGE_MODEL)
970        public ElementKind getKind() {
971            return ElementKind.MODULE;
972        }
973
974        @Override @DefinedBy(Api.LANGUAGE_MODEL)
975        public java.util.List<Directive> getDirectives() {
976            complete();
977            completeUsesProvides();
978            return Collections.unmodifiableList(directives);
979        }
980
981        public void completeUsesProvides() {
982            if (usesProvidesCompleter != Completer.NULL_COMPLETER) {
983                Completer c = usesProvidesCompleter;
984                usesProvidesCompleter = Completer.NULL_COMPLETER;
985                c.complete(this);
986            }
987        }
988
989        @Override
990        public ClassSymbol outermostClass() {
991            return null;
992        }
993
994        @Override
995        public String toString() {
996            // TODO: the following strings should be localized
997            // Do this with custom anon subtypes in Symtab
998            String n = (name == null) ? "<unknown>"
999                    : (name.isEmpty()) ? "<unnamed>"
1000                    : String.valueOf(name);
1001            return n;
1002        }
1003
1004        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1005        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1006            return v.visitModule(this, p);
1007        }
1008
1009        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1010        public List<Symbol> getEnclosedElements() {
1011            List<Symbol> list = List.nil();
1012            for (Symbol sym : enclosedPackages) {
1013                if (sym.members().anyMatch(m -> m.kind == TYP))
1014                    list = list.prepend(sym);
1015            }
1016            return list;
1017        }
1018
1019        public void reset() {
1020            this.directives = null;
1021            this.requires = null;
1022            this.exports = null;
1023            this.provides = null;
1024            this.uses = null;
1025            this.visiblePackages = null;
1026        }
1027
1028    }
1029
1030    public enum ModuleFlags {
1031        OPEN(0x0020),
1032        SYNTHETIC(0x1000),
1033        MANDATED(0x8000);
1034
1035        public static int value(Set<ModuleFlags> s) {
1036            int v = 0;
1037            for (ModuleFlags f: s)
1038                v |= f.value;
1039            return v;
1040        }
1041
1042        private ModuleFlags(int value) {
1043            this.value = value;
1044        }
1045
1046        public final int value;
1047    }
1048
1049    public enum ModuleResolutionFlags {
1050        DO_NOT_RESOLVE_BY_DEFAULT(0x0001),
1051        WARN_DEPRECATED(0x0002),
1052        WARN_DEPRECATED_REMOVAL(0x0004),
1053        WARN_INCUBATING(0x0008);
1054
1055        public static int value(Set<ModuleResolutionFlags> s) {
1056            int v = 0;
1057            for (ModuleResolutionFlags f: s)
1058                v |= f.value;
1059            return v;
1060        }
1061
1062        private ModuleResolutionFlags(int value) {
1063            this.value = value;
1064        }
1065
1066        public final int value;
1067    }
1068
1069    /** A class for package symbols
1070     */
1071    public static class PackageSymbol extends TypeSymbol
1072        implements PackageElement {
1073
1074        public WriteableScope members_field;
1075        public Name fullname;
1076        public ClassSymbol package_info; // see bug 6443073
1077        public ModuleSymbol modle;
1078        // the file containing the documentation comments for the package
1079        public JavaFileObject sourcefile;
1080
1081        public PackageSymbol(Name name, Type type, Symbol owner) {
1082            super(PCK, 0, name, type, owner);
1083            this.members_field = null;
1084            this.fullname = formFullName(name, owner);
1085        }
1086
1087        public PackageSymbol(Name name, Symbol owner) {
1088            this(name, null, owner);
1089            this.type = new PackageType(this);
1090        }
1091
1092        public String toString() {
1093            return fullname.toString();
1094        }
1095
1096        @DefinedBy(Api.LANGUAGE_MODEL)
1097        public Name getQualifiedName() {
1098            return fullname;
1099        }
1100
1101        @DefinedBy(Api.LANGUAGE_MODEL)
1102        public boolean isUnnamed() {
1103            return name.isEmpty() && owner != null;
1104        }
1105
1106        public WriteableScope members() {
1107            complete();
1108            return members_field;
1109        }
1110
1111        public long flags() {
1112            complete();
1113            return flags_field;
1114        }
1115
1116        @Override
1117        public List<Attribute.Compound> getRawAttributes() {
1118            complete();
1119            if (package_info != null) {
1120                package_info.complete();
1121                mergeAttributes();
1122            }
1123            return super.getRawAttributes();
1124        }
1125
1126        private void mergeAttributes() {
1127            if (metadata == null &&
1128                package_info.metadata != null) {
1129                metadata = new SymbolMetadata(this);
1130                metadata.setAttributes(package_info.metadata);
1131            }
1132        }
1133
1134        /** A package "exists" if a type or package that exists has
1135         *  been seen within it.
1136         */
1137        public boolean exists() {
1138            return (flags_field & EXISTS) != 0;
1139        }
1140
1141        @DefinedBy(Api.LANGUAGE_MODEL)
1142        public ElementKind getKind() {
1143            return ElementKind.PACKAGE;
1144        }
1145
1146        @DefinedBy(Api.LANGUAGE_MODEL)
1147        public Symbol getEnclosingElement() {
1148            return modle != null && !modle.isNoModule() ? modle : null;
1149        }
1150
1151        @DefinedBy(Api.LANGUAGE_MODEL)
1152        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1153            return v.visitPackage(this, p);
1154        }
1155
1156        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1157            return v.visitPackageSymbol(this, p);
1158        }
1159
1160        /**Resets the Symbol into the state good for next round of annotation processing.*/
1161        public void reset() {
1162            metadata = null;
1163        }
1164
1165    }
1166
1167    /** A class for class symbols
1168     */
1169    public static class ClassSymbol extends TypeSymbol implements TypeElement {
1170
1171        /** a scope for all class members; variables, methods and inner classes
1172         *  type parameters are not part of this scope
1173         */
1174        public WriteableScope members_field;
1175
1176        /** the fully qualified name of the class, i.e. pck.outer.inner.
1177         *  null for anonymous classes
1178         */
1179        public Name fullname;
1180
1181        /** the fully qualified name of the class after converting to flat
1182         *  representation, i.e. pck.outer$inner,
1183         *  set externally for local and anonymous classes
1184         */
1185        public Name flatname;
1186
1187        /** the sourcefile where the class came from
1188         */
1189        public JavaFileObject sourcefile;
1190
1191        /** the classfile from where to load this class
1192         *  this will have extension .class or .java
1193         */
1194        public JavaFileObject classfile;
1195
1196        /** the list of translated local classes (used for generating
1197         * InnerClasses attribute)
1198         */
1199        public List<ClassSymbol> trans_local;
1200
1201        /** the constant pool of the class
1202         */
1203        public Pool pool;
1204
1205        /** the annotation metadata attached to this class */
1206        private AnnotationTypeMetadata annotationTypeMetadata;
1207
1208        public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
1209            super(TYP, flags, name, type, owner);
1210            this.members_field = null;
1211            this.fullname = formFullName(name, owner);
1212            this.flatname = formFlatName(name, owner);
1213            this.sourcefile = null;
1214            this.classfile = null;
1215            this.pool = null;
1216            this.annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1217        }
1218
1219        public ClassSymbol(long flags, Name name, Symbol owner) {
1220            this(
1221                flags,
1222                name,
1223                new ClassType(Type.noType, null, null),
1224                owner);
1225            this.type.tsym = this;
1226        }
1227
1228        /** The Java source which this symbol represents.
1229         */
1230        public String toString() {
1231            return className();
1232        }
1233
1234        public long flags() {
1235            complete();
1236            return flags_field;
1237        }
1238
1239        public WriteableScope members() {
1240            complete();
1241            return members_field;
1242        }
1243
1244        @Override
1245        public List<Attribute.Compound> getRawAttributes() {
1246            complete();
1247            return super.getRawAttributes();
1248        }
1249
1250        @Override
1251        public List<Attribute.TypeCompound> getRawTypeAttributes() {
1252            complete();
1253            return super.getRawTypeAttributes();
1254        }
1255
1256        public Type erasure(Types types) {
1257            if (erasure_field == null)
1258                erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
1259                                              List.nil(), this,
1260                                              type.getMetadata());
1261            return erasure_field;
1262        }
1263
1264        public String className() {
1265            if (name.isEmpty())
1266                return
1267                    Log.getLocalizedString("anonymous.class", flatname);
1268            else
1269                return fullname.toString();
1270        }
1271
1272        @DefinedBy(Api.LANGUAGE_MODEL)
1273        public Name getQualifiedName() {
1274            return fullname;
1275        }
1276
1277        public Name flatName() {
1278            return flatname;
1279        }
1280
1281        public boolean isSubClass(Symbol base, Types types) {
1282            if (this == base) {
1283                return true;
1284            } else if ((base.flags() & INTERFACE) != 0) {
1285                for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1286                    for (List<Type> is = types.interfaces(t);
1287                         is.nonEmpty();
1288                         is = is.tail)
1289                        if (is.head.tsym.isSubClass(base, types)) return true;
1290            } else {
1291                for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1292                    if (t.tsym == base) return true;
1293            }
1294            return false;
1295        }
1296
1297        /** Complete the elaboration of this symbol's definition.
1298         */
1299        public void complete() throws CompletionFailure {
1300            try {
1301                super.complete();
1302            } catch (CompletionFailure ex) {
1303                // quiet error recovery
1304                flags_field |= (PUBLIC|STATIC);
1305                this.type = new ErrorType(this, Type.noType);
1306                throw ex;
1307            }
1308        }
1309
1310        @DefinedBy(Api.LANGUAGE_MODEL)
1311        public List<Type> getInterfaces() {
1312            complete();
1313            if (type instanceof ClassType) {
1314                ClassType t = (ClassType)type;
1315                if (t.interfaces_field == null) // FIXME: shouldn't be null
1316                    t.interfaces_field = List.nil();
1317                if (t.all_interfaces_field != null)
1318                    return Type.getModelTypes(t.all_interfaces_field);
1319                return t.interfaces_field;
1320            } else {
1321                return List.nil();
1322            }
1323        }
1324
1325        @DefinedBy(Api.LANGUAGE_MODEL)
1326        public Type getSuperclass() {
1327            complete();
1328            if (type instanceof ClassType) {
1329                ClassType t = (ClassType)type;
1330                if (t.supertype_field == null) // FIXME: shouldn't be null
1331                    t.supertype_field = Type.noType;
1332                // An interface has no superclass; its supertype is Object.
1333                return t.isInterface()
1334                    ? Type.noType
1335                    : t.supertype_field.getModelType();
1336            } else {
1337                return Type.noType;
1338            }
1339        }
1340
1341        /**
1342         * Returns the next class to search for inherited annotations or {@code null}
1343         * if the next class can't be found.
1344         */
1345        private ClassSymbol getSuperClassToSearchForAnnotations() {
1346
1347            Type sup = getSuperclass();
1348
1349            if (!sup.hasTag(CLASS) || sup.isErroneous())
1350                return null;
1351
1352            return (ClassSymbol) sup.tsym;
1353        }
1354
1355
1356        @Override
1357        protected <A extends Annotation> A[] getInheritedAnnotations(Class<A> annoType) {
1358
1359            ClassSymbol sup = getSuperClassToSearchForAnnotations();
1360
1361            return sup == null ? super.getInheritedAnnotations(annoType)
1362                               : sup.getAnnotationsByType(annoType);
1363        }
1364
1365
1366        @DefinedBy(Api.LANGUAGE_MODEL)
1367        public ElementKind getKind() {
1368            long flags = flags();
1369            if ((flags & ANNOTATION) != 0)
1370                return ElementKind.ANNOTATION_TYPE;
1371            else if ((flags & INTERFACE) != 0)
1372                return ElementKind.INTERFACE;
1373            else if ((flags & ENUM) != 0)
1374                return ElementKind.ENUM;
1375            else
1376                return ElementKind.CLASS;
1377        }
1378
1379        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1380        public Set<Modifier> getModifiers() {
1381            long flags = flags();
1382            return Flags.asModifierSet(flags & ~DEFAULT);
1383        }
1384
1385        @DefinedBy(Api.LANGUAGE_MODEL)
1386        public NestingKind getNestingKind() {
1387            complete();
1388            if (owner.kind == PCK)
1389                return NestingKind.TOP_LEVEL;
1390            else if (name.isEmpty())
1391                return NestingKind.ANONYMOUS;
1392            else if (owner.kind == MTH)
1393                return NestingKind.LOCAL;
1394            else
1395                return NestingKind.MEMBER;
1396        }
1397
1398
1399        @Override
1400        protected <A extends Annotation> Attribute.Compound getAttribute(final Class<A> annoType) {
1401
1402            Attribute.Compound attrib = super.getAttribute(annoType);
1403
1404            boolean inherited = annoType.isAnnotationPresent(Inherited.class);
1405            if (attrib != null || !inherited)
1406                return attrib;
1407
1408            // Search supertypes
1409            ClassSymbol superType = getSuperClassToSearchForAnnotations();
1410            return superType == null ? null
1411                                     : superType.getAttribute(annoType);
1412        }
1413
1414
1415
1416
1417        @DefinedBy(Api.LANGUAGE_MODEL)
1418        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1419            return v.visitType(this, p);
1420        }
1421
1422        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1423            return v.visitClassSymbol(this, p);
1424        }
1425
1426        public void markAbstractIfNeeded(Types types) {
1427            if (types.enter.getEnv(this) != null &&
1428                (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym &&
1429                (flags() & (FINAL | ABSTRACT)) == 0) {
1430                if (types.firstUnimplementedAbstract(this) != null)
1431                    // add the ABSTRACT flag to an enum
1432                    flags_field |= ABSTRACT;
1433            }
1434        }
1435
1436        /**Resets the Symbol into the state good for next round of annotation processing.*/
1437        public void reset() {
1438            kind = TYP;
1439            erasure_field = null;
1440            members_field = null;
1441            flags_field = 0;
1442            if (type instanceof ClassType) {
1443                ClassType t = (ClassType)type;
1444                t.setEnclosingType(Type.noType);
1445                t.rank_field = -1;
1446                t.typarams_field = null;
1447                t.allparams_field = null;
1448                t.supertype_field = null;
1449                t.interfaces_field = null;
1450                t.all_interfaces_field = null;
1451            }
1452            clearAnnotationMetadata();
1453        }
1454
1455        public void clearAnnotationMetadata() {
1456            metadata = null;
1457            annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1458        }
1459
1460        @Override
1461        public AnnotationTypeMetadata getAnnotationTypeMetadata() {
1462            return annotationTypeMetadata;
1463        }
1464
1465        @Override
1466        public boolean isAnnotationType() {
1467            return (flags_field & Flags.ANNOTATION) != 0;
1468        }
1469
1470        public void setAnnotationTypeMetadata(AnnotationTypeMetadata a) {
1471            Assert.checkNonNull(a);
1472            Assert.check(!annotationTypeMetadata.isMetadataForAnnotationType());
1473            this.annotationTypeMetadata = a;
1474        }
1475    }
1476
1477
1478    /** A class for variable symbols
1479     */
1480    public static class VarSymbol extends Symbol implements VariableElement {
1481
1482        /** The variable's declaration position.
1483         */
1484        public int pos = Position.NOPOS;
1485
1486        /** The variable's address. Used for different purposes during
1487         *  flow analysis, translation and code generation.
1488         *  Flow analysis:
1489         *    If this is a blank final or local variable, its sequence number.
1490         *  Translation:
1491         *    If this is a private field, its access number.
1492         *  Code generation:
1493         *    If this is a local variable, its logical slot number.
1494         */
1495        public int adr = -1;
1496
1497        /** Construct a variable symbol, given its flags, name, type and owner.
1498         */
1499        public VarSymbol(long flags, Name name, Type type, Symbol owner) {
1500            super(VAR, flags, name, type, owner);
1501        }
1502
1503        /** Clone this symbol with new owner.
1504         */
1505        public VarSymbol clone(Symbol newOwner) {
1506            VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) {
1507                @Override
1508                public Symbol baseSymbol() {
1509                    return VarSymbol.this;
1510                }
1511            };
1512            v.pos = pos;
1513            v.adr = adr;
1514            v.data = data;
1515//          System.out.println("clone " + v + " in " + newOwner);//DEBUG
1516            return v;
1517        }
1518
1519        public String toString() {
1520            return name.toString();
1521        }
1522
1523        public Symbol asMemberOf(Type site, Types types) {
1524            return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
1525        }
1526
1527        @DefinedBy(Api.LANGUAGE_MODEL)
1528        public ElementKind getKind() {
1529            long flags = flags();
1530            if ((flags & PARAMETER) != 0) {
1531                if (isExceptionParameter())
1532                    return ElementKind.EXCEPTION_PARAMETER;
1533                else
1534                    return ElementKind.PARAMETER;
1535            } else if ((flags & ENUM) != 0) {
1536                return ElementKind.ENUM_CONSTANT;
1537            } else if (owner.kind == TYP || owner.kind == ERR) {
1538                return ElementKind.FIELD;
1539            } else if (isResourceVariable()) {
1540                return ElementKind.RESOURCE_VARIABLE;
1541            } else {
1542                return ElementKind.LOCAL_VARIABLE;
1543            }
1544        }
1545
1546        @DefinedBy(Api.LANGUAGE_MODEL)
1547        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1548            return v.visitVariable(this, p);
1549        }
1550
1551        @DefinedBy(Api.LANGUAGE_MODEL)
1552        public Object getConstantValue() { // Mirror API
1553            return Constants.decode(getConstValue(), type);
1554        }
1555
1556        public void setLazyConstValue(final Env<AttrContext> env,
1557                                      final Attr attr,
1558                                      final JCVariableDecl variable)
1559        {
1560            setData((Callable<Object>)() -> attr.attribLazyConstantValue(env, variable, type));
1561        }
1562
1563        /**
1564         * The variable's constant value, if this is a constant.
1565         * Before the constant value is evaluated, it points to an
1566         * initializer environment.  If this is not a constant, it can
1567         * be used for other stuff.
1568         */
1569        private Object data;
1570
1571        public boolean isExceptionParameter() {
1572            return data == ElementKind.EXCEPTION_PARAMETER;
1573        }
1574
1575        public boolean isResourceVariable() {
1576            return data == ElementKind.RESOURCE_VARIABLE;
1577        }
1578
1579        public Object getConstValue() {
1580            // TODO: Consider if getConstValue and getConstantValue can be collapsed
1581            if (data == ElementKind.EXCEPTION_PARAMETER ||
1582                data == ElementKind.RESOURCE_VARIABLE) {
1583                return null;
1584            } else if (data instanceof Callable<?>) {
1585                // In this case, this is a final variable, with an as
1586                // yet unevaluated initializer.
1587                Callable<?> eval = (Callable<?>)data;
1588                data = null; // to make sure we don't evaluate this twice.
1589                try {
1590                    data = eval.call();
1591                } catch (Exception ex) {
1592                    throw new AssertionError(ex);
1593                }
1594            }
1595            return data;
1596        }
1597
1598        public void setData(Object data) {
1599            Assert.check(!(data instanceof Env<?>), this);
1600            this.data = data;
1601        }
1602
1603        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1604            return v.visitVarSymbol(this, p);
1605        }
1606    }
1607
1608    /** A class for method symbols.
1609     */
1610    public static class MethodSymbol extends Symbol implements ExecutableElement {
1611
1612        /** The code of the method. */
1613        public Code code = null;
1614
1615        /** The extra (synthetic/mandated) parameters of the method. */
1616        public List<VarSymbol> extraParams = List.nil();
1617
1618        /** The captured local variables in an anonymous class */
1619        public List<VarSymbol> capturedLocals = List.nil();
1620
1621        /** The parameters of the method. */
1622        public List<VarSymbol> params = null;
1623
1624        /** The names of the parameters */
1625        public List<Name> savedParameterNames;
1626
1627        /** For an annotation type element, its default value if any.
1628         *  The value is null if none appeared in the method
1629         *  declaration.
1630         */
1631        public Attribute defaultValue = null;
1632
1633        /** Construct a method symbol, given its flags, name, type and owner.
1634         */
1635        public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1636            super(MTH, flags, name, type, owner);
1637            if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name);
1638        }
1639
1640        /** Clone this symbol with new owner.
1641         */
1642        public MethodSymbol clone(Symbol newOwner) {
1643            MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) {
1644                @Override
1645                public Symbol baseSymbol() {
1646                    return MethodSymbol.this;
1647                }
1648            };
1649            m.code = code;
1650            return m;
1651        }
1652
1653        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1654        public Set<Modifier> getModifiers() {
1655            long flags = flags();
1656            return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags);
1657        }
1658
1659        /** The Java source which this symbol represents.
1660         */
1661        public String toString() {
1662            if ((flags() & BLOCK) != 0) {
1663                return owner.name.toString();
1664            } else {
1665                String s = (name == name.table.names.init)
1666                    ? owner.name.toString()
1667                    : name.toString();
1668                if (type != null) {
1669                    if (type.hasTag(FORALL))
1670                        s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1671                    s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1672                }
1673                return s;
1674            }
1675        }
1676
1677        public boolean isDynamic() {
1678            return false;
1679        }
1680
1681        /** find a symbol that this (proxy method) symbol implements.
1682         *  @param    c       The class whose members are searched for
1683         *                    implementations
1684         */
1685        public Symbol implemented(TypeSymbol c, Types types) {
1686            Symbol impl = null;
1687            for (List<Type> is = types.interfaces(c.type);
1688                 impl == null && is.nonEmpty();
1689                 is = is.tail) {
1690                TypeSymbol i = is.head.tsym;
1691                impl = implementedIn(i, types);
1692                if (impl == null)
1693                    impl = implemented(i, types);
1694            }
1695            return impl;
1696        }
1697
1698        public Symbol implementedIn(TypeSymbol c, Types types) {
1699            Symbol impl = null;
1700            for (Symbol sym : c.members().getSymbolsByName(name)) {
1701                if (this.overrides(sym, (TypeSymbol)owner, types, true) &&
1702                    // FIXME: I suspect the following requires a
1703                    // subst() for a parametric return type.
1704                    types.isSameType(type.getReturnType(),
1705                                     types.memberType(owner.type, sym).getReturnType())) {
1706                    impl = sym;
1707                }
1708            }
1709            return impl;
1710        }
1711
1712        /** Will the erasure of this method be considered by the VM to
1713         *  override the erasure of the other when seen from class `origin'?
1714         */
1715        public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1716            if (isConstructor() || _other.kind != MTH) return false;
1717
1718            if (this == _other) return true;
1719            MethodSymbol other = (MethodSymbol)_other;
1720
1721            // check for a direct implementation
1722            if (other.isOverridableIn((TypeSymbol)owner) &&
1723                types.asSuper(owner.type, other.owner) != null &&
1724                types.isSameType(erasure(types), other.erasure(types)))
1725                return true;
1726
1727            // check for an inherited implementation
1728            return
1729                (flags() & ABSTRACT) == 0 &&
1730                other.isOverridableIn(origin) &&
1731                this.isMemberOf(origin, types) &&
1732                types.isSameType(erasure(types), other.erasure(types));
1733        }
1734
1735        /** The implementation of this (abstract) symbol in class origin,
1736         *  from the VM's point of view, null if method does not have an
1737         *  implementation in class.
1738         *  @param origin   The class of which the implementation is a member.
1739         */
1740        public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1741            for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1742                for (Symbol sym : c.members().getSymbolsByName(name)) {
1743                    if (sym.kind == MTH &&
1744                        ((MethodSymbol)sym).binaryOverrides(this, origin, types))
1745                        return (MethodSymbol)sym;
1746                }
1747            }
1748            return null;
1749        }
1750
1751        /** Does this symbol override `other' symbol, when both are seen as
1752         *  members of class `origin'?  It is assumed that _other is a member
1753         *  of origin.
1754         *
1755         *  It is assumed that both symbols have the same name.  The static
1756         *  modifier is ignored for this test.
1757         *
1758         *  A quirk in the works is that if the receiver is a method symbol for
1759         *  an inherited abstract method we answer false summarily all else being
1760         *  immaterial. Abstract "own" methods (i.e `this' is a direct member of
1761         *  origin) don't get rejected as summarily and are put to test against the
1762         *  suitable criteria.
1763         *
1764         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1765         */
1766        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1767            return overrides(_other, origin, types, checkResult, true);
1768        }
1769
1770        /** Does this symbol override `other' symbol, when both are seen as
1771         *  members of class `origin'?  It is assumed that _other is a member
1772         *  of origin.
1773         *
1774         *  Caveat: If `this' is an abstract inherited member of origin, it is
1775         *  deemed to override `other' only when `requireConcreteIfInherited'
1776         *  is false.
1777         *
1778         *  It is assumed that both symbols have the same name.  The static
1779         *  modifier is ignored for this test.
1780         *
1781         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1782         */
1783        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult,
1784                                            boolean requireConcreteIfInherited) {
1785            if (isConstructor() || _other.kind != MTH) return false;
1786
1787            if (this == _other) return true;
1788            MethodSymbol other = (MethodSymbol)_other;
1789
1790            // check for a direct implementation
1791            if (other.isOverridableIn((TypeSymbol)owner) &&
1792                types.asSuper(owner.type, other.owner) != null) {
1793                Type mt = types.memberType(owner.type, this);
1794                Type ot = types.memberType(owner.type, other);
1795                if (types.isSubSignature(mt, ot)) {
1796                    if (!checkResult)
1797                        return true;
1798                    if (types.returnTypeSubstitutable(mt, ot))
1799                        return true;
1800                }
1801            }
1802
1803            // check for an inherited implementation
1804            if (((flags() & ABSTRACT) != 0 && requireConcreteIfInherited) ||
1805                    ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
1806                    !other.isOverridableIn(origin) ||
1807                    !this.isMemberOf(origin, types))
1808                return false;
1809
1810            // assert types.asSuper(origin.type, other.owner) != null;
1811            Type mt = types.memberType(origin.type, this);
1812            Type ot = types.memberType(origin.type, other);
1813            return
1814                types.isSubSignature(mt, ot) &&
1815                (!checkResult || types.resultSubtype(mt, ot, types.noWarnings));
1816        }
1817
1818        private boolean isOverridableIn(TypeSymbol origin) {
1819            // JLS 8.4.6.1
1820            switch ((int)(flags_field & Flags.AccessFlags)) {
1821            case Flags.PRIVATE:
1822                return false;
1823            case Flags.PUBLIC:
1824                return !this.owner.isInterface() ||
1825                        (flags_field & STATIC) == 0;
1826            case Flags.PROTECTED:
1827                return (origin.flags() & INTERFACE) == 0;
1828            case 0:
1829                // for package private: can only override in the same
1830                // package
1831                return
1832                    this.packge() == origin.packge() &&
1833                    (origin.flags() & INTERFACE) == 0;
1834            default:
1835                return false;
1836            }
1837        }
1838
1839        @Override
1840        public boolean isInheritedIn(Symbol clazz, Types types) {
1841            switch ((int)(flags_field & Flags.AccessFlags)) {
1842                case PUBLIC:
1843                    return !this.owner.isInterface() ||
1844                            clazz == owner ||
1845                            (flags_field & STATIC) == 0;
1846                default:
1847                    return super.isInheritedIn(clazz, types);
1848            }
1849        }
1850
1851        public boolean isLambdaMethod() {
1852            return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD;
1853        }
1854
1855        /** The implementation of this (abstract) symbol in class origin;
1856         *  null if none exists. Synthetic methods are not considered
1857         *  as possible implementations.
1858         */
1859        public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1860            return implementation(origin, types, checkResult, implementation_filter);
1861        }
1862        // where
1863            public static final Filter<Symbol> implementation_filter = s ->
1864                    s.kind == MTH && (s.flags() & SYNTHETIC) == 0;
1865
1866        public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
1867            MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
1868            if (res != null)
1869                return res;
1870            // if origin is derived from a raw type, we might have missed
1871            // an implementation because we do not know enough about instantiations.
1872            // in this case continue with the supertype as origin.
1873            if (types.isDerivedRaw(origin.type) && !origin.isInterface())
1874                return implementation(types.supertype(origin.type).tsym, types, checkResult);
1875            else
1876                return null;
1877        }
1878
1879        public List<VarSymbol> params() {
1880            owner.complete();
1881            if (params == null) {
1882                // If ClassReader.saveParameterNames has been set true, then
1883                // savedParameterNames will be set to a list of names that
1884                // matches the types in type.getParameterTypes().  If any names
1885                // were not found in the class file, those names in the list will
1886                // be set to the empty name.
1887                // If ClassReader.saveParameterNames has been set false, then
1888                // savedParameterNames will be null.
1889                List<Name> paramNames = savedParameterNames;
1890                savedParameterNames = null;
1891                // discard the provided names if the list of names is the wrong size.
1892                if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) {
1893                    paramNames = List.nil();
1894                }
1895                ListBuffer<VarSymbol> buf = new ListBuffer<>();
1896                List<Name> remaining = paramNames;
1897                // assert: remaining and paramNames are both empty or both
1898                // have same cardinality as type.getParameterTypes()
1899                int i = 0;
1900                for (Type t : type.getParameterTypes()) {
1901                    Name paramName;
1902                    if (remaining.isEmpty()) {
1903                        // no names for any parameters available
1904                        paramName = createArgName(i, paramNames);
1905                    } else {
1906                        paramName = remaining.head;
1907                        remaining = remaining.tail;
1908                        if (paramName.isEmpty()) {
1909                            // no name for this specific parameter
1910                            paramName = createArgName(i, paramNames);
1911                        }
1912                    }
1913                    buf.append(new VarSymbol(PARAMETER, paramName, t, this));
1914                    i++;
1915                }
1916                params = buf.toList();
1917            }
1918            return params;
1919        }
1920
1921        // Create a name for the argument at position 'index' that is not in
1922        // the exclude list. In normal use, either no names will have been
1923        // provided, in which case the exclude list is empty, or all the names
1924        // will have been provided, in which case this method will not be called.
1925        private Name createArgName(int index, List<Name> exclude) {
1926            String prefix = "arg";
1927            while (true) {
1928                Name argName = name.table.fromString(prefix + index);
1929                if (!exclude.contains(argName))
1930                    return argName;
1931                prefix += "$";
1932            }
1933        }
1934
1935        public Symbol asMemberOf(Type site, Types types) {
1936            return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1937        }
1938
1939        @DefinedBy(Api.LANGUAGE_MODEL)
1940        public ElementKind getKind() {
1941            if (name == name.table.names.init)
1942                return ElementKind.CONSTRUCTOR;
1943            else if (name == name.table.names.clinit)
1944                return ElementKind.STATIC_INIT;
1945            else if ((flags() & BLOCK) != 0)
1946                return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT;
1947            else
1948                return ElementKind.METHOD;
1949        }
1950
1951        public boolean isStaticOrInstanceInit() {
1952            return getKind() == ElementKind.STATIC_INIT ||
1953                    getKind() == ElementKind.INSTANCE_INIT;
1954        }
1955
1956        @DefinedBy(Api.LANGUAGE_MODEL)
1957        public Attribute getDefaultValue() {
1958            return defaultValue;
1959        }
1960
1961        @DefinedBy(Api.LANGUAGE_MODEL)
1962        public List<VarSymbol> getParameters() {
1963            return params();
1964        }
1965
1966        @DefinedBy(Api.LANGUAGE_MODEL)
1967        public boolean isVarArgs() {
1968            return (flags() & VARARGS) != 0;
1969        }
1970
1971        @DefinedBy(Api.LANGUAGE_MODEL)
1972        public boolean isDefault() {
1973            return (flags() & DEFAULT) != 0;
1974        }
1975
1976        @DefinedBy(Api.LANGUAGE_MODEL)
1977        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1978            return v.visitExecutable(this, p);
1979        }
1980
1981        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1982            return v.visitMethodSymbol(this, p);
1983        }
1984
1985        @DefinedBy(Api.LANGUAGE_MODEL)
1986        public Type getReceiverType() {
1987            return asType().getReceiverType();
1988        }
1989
1990        @DefinedBy(Api.LANGUAGE_MODEL)
1991        public Type getReturnType() {
1992            return asType().getReturnType();
1993        }
1994
1995        @DefinedBy(Api.LANGUAGE_MODEL)
1996        public List<Type> getThrownTypes() {
1997            return asType().getThrownTypes();
1998        }
1999    }
2000
2001    /** A class for invokedynamic method calls.
2002     */
2003    public static class DynamicMethodSymbol extends MethodSymbol {
2004
2005        public Object[] staticArgs;
2006        public Symbol bsm;
2007        public int bsmKind;
2008
2009        public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
2010            super(0, name, type, owner);
2011            this.bsm = bsm;
2012            this.bsmKind = bsmKind;
2013            this.staticArgs = staticArgs;
2014        }
2015
2016        @Override
2017        public boolean isDynamic() {
2018            return true;
2019        }
2020    }
2021
2022    /** A class for predefined operators.
2023     */
2024    public static class OperatorSymbol extends MethodSymbol {
2025
2026        public int opcode;
2027        private int accessCode = Integer.MIN_VALUE;
2028
2029        public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
2030            super(PUBLIC | STATIC, name, type, owner);
2031            this.opcode = opcode;
2032        }
2033
2034        @Override
2035        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
2036            return v.visitOperatorSymbol(this, p);
2037        }
2038
2039        public int getAccessCode(Tag tag) {
2040            if (accessCode != Integer.MIN_VALUE && !tag.isIncOrDecUnaryOp()) {
2041                return accessCode;
2042            }
2043            accessCode = AccessCode.from(tag, opcode);
2044            return accessCode;
2045        }
2046
2047        /** Access codes for dereferencing, assignment,
2048         *  and pre/post increment/decrement.
2049
2050         *  All access codes for accesses to the current class are even.
2051         *  If a member of the superclass should be accessed instead (because
2052         *  access was via a qualified super), add one to the corresponding code
2053         *  for the current class, making the number odd.
2054         *  This numbering scheme is used by the backend to decide whether
2055         *  to issue an invokevirtual or invokespecial call.
2056         *
2057         *  @see Gen#visitSelect(JCFieldAccess tree)
2058         */
2059        public enum AccessCode {
2060            UNKNOWN(-1, Tag.NO_TAG),
2061            DEREF(0, Tag.NO_TAG),
2062            ASSIGN(2, Tag.ASSIGN),
2063            PREINC(4, Tag.PREINC),
2064            PREDEC(6, Tag.PREDEC),
2065            POSTINC(8, Tag.POSTINC),
2066            POSTDEC(10, Tag.POSTDEC),
2067            FIRSTASGOP(12, Tag.NO_TAG);
2068
2069            public final int code;
2070            public final Tag tag;
2071            public static final int numberOfAccessCodes = (lushrl - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code + 2;
2072
2073            AccessCode(int code, Tag tag) {
2074                this.code = code;
2075                this.tag = tag;
2076            }
2077
2078            static public AccessCode getFromCode(int code) {
2079                for (AccessCode aCodes : AccessCode.values()) {
2080                    if (aCodes.code == code) {
2081                        return aCodes;
2082                    }
2083                }
2084                return UNKNOWN;
2085            }
2086
2087            static int from(Tag tag, int opcode) {
2088                /** Map bytecode of binary operation to access code of corresponding
2089                *  assignment operation. This is always an even number.
2090                */
2091                switch (tag) {
2092                    case PREINC:
2093                        return AccessCode.PREINC.code;
2094                    case PREDEC:
2095                        return AccessCode.PREDEC.code;
2096                    case POSTINC:
2097                        return AccessCode.POSTINC.code;
2098                    case POSTDEC:
2099                        return AccessCode.POSTDEC.code;
2100                }
2101                if (iadd <= opcode && opcode <= lxor) {
2102                    return (opcode - iadd) * 2 + FIRSTASGOP.code;
2103                } else if (opcode == string_add) {
2104                    return (lxor + 1 - iadd) * 2 + FIRSTASGOP.code;
2105                } else if (ishll <= opcode && opcode <= lushrl) {
2106                    return (opcode - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code;
2107                }
2108                return -1;
2109            }
2110        }
2111    }
2112
2113    /** Symbol completer interface.
2114     */
2115    public static interface Completer {
2116
2117        /** Dummy completer to be used when the symbol has been completed or
2118         * does not need completion.
2119         */
2120        public final static Completer NULL_COMPLETER = new Completer() {
2121            public void complete(Symbol sym) { }
2122            public boolean isTerminal() { return true; }
2123        };
2124
2125        void complete(Symbol sym) throws CompletionFailure;
2126
2127        /** Returns true if this completer is <em>terminal</em>. A terminal
2128         * completer is used as a place holder when the symbol is completed.
2129         * Calling complete on a terminal completer will not affect the symbol.
2130         *
2131         * The dummy NULL_COMPLETER and the GraphDependencies completer are
2132         * examples of terminal completers.
2133         *
2134         * @return true iff this completer is terminal
2135         */
2136        default boolean isTerminal() {
2137            return false;
2138        }
2139    }
2140
2141    public static class CompletionFailure extends RuntimeException {
2142        private static final long serialVersionUID = 0;
2143        public Symbol sym;
2144
2145        /** A diagnostic object describing the failure
2146         */
2147        public JCDiagnostic diag;
2148
2149        /** A localized string describing the failure.
2150         * @deprecated Use {@code getDetail()} or {@code getMessage()}
2151         */
2152        @Deprecated
2153        public String errmsg;
2154
2155        public CompletionFailure(Symbol sym, String errmsg) {
2156            this.sym = sym;
2157            this.errmsg = errmsg;
2158//          this.printStackTrace();//DEBUG
2159        }
2160
2161        public CompletionFailure(Symbol sym, JCDiagnostic diag) {
2162            this.sym = sym;
2163            this.diag = diag;
2164//          this.printStackTrace();//DEBUG
2165        }
2166
2167        public JCDiagnostic getDiagnostic() {
2168            return diag;
2169        }
2170
2171        @Override
2172        public String getMessage() {
2173            if (diag != null)
2174                return diag.getMessage(null);
2175            else
2176                return errmsg;
2177        }
2178
2179        public Object getDetailValue() {
2180            return (diag != null ? diag : errmsg);
2181        }
2182
2183        @Override
2184        public CompletionFailure initCause(Throwable cause) {
2185            super.initCause(cause);
2186            return this;
2187        }
2188
2189    }
2190
2191    /**
2192     * A visitor for symbols.  A visitor is used to implement operations
2193     * (or relations) on symbols.  Most common operations on types are
2194     * binary relations and this interface is designed for binary
2195     * relations, that is, operations on the form
2196     * Symbol&nbsp;&times;&nbsp;P&nbsp;&rarr;&nbsp;R.
2197     * <!-- In plain text: Type x P -> R -->
2198     *
2199     * @param <R> the return type of the operation implemented by this
2200     * visitor; use Void if no return type is needed.
2201     * @param <P> the type of the second argument (the first being the
2202     * symbol itself) of the operation implemented by this visitor; use
2203     * Void if a second argument is not needed.
2204     */
2205    public interface Visitor<R,P> {
2206        R visitClassSymbol(ClassSymbol s, P arg);
2207        R visitMethodSymbol(MethodSymbol s, P arg);
2208        R visitPackageSymbol(PackageSymbol s, P arg);
2209        R visitOperatorSymbol(OperatorSymbol s, P arg);
2210        R visitVarSymbol(VarSymbol s, P arg);
2211        R visitTypeSymbol(TypeSymbol s, P arg);
2212        R visitSymbol(Symbol s, P arg);
2213    }
2214}
2215