Symbol.java revision 3822:d8766c39123a
1/*
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.javac.code;
27
28import java.lang.annotation.Annotation;
29import java.lang.annotation.Inherited;
30import java.util.Collections;
31import java.util.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.<Attribute.Compound>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.<Attribute.TypeCompound>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.<Attribute.TypeCompound>nil()
196                : metadata.getClassInitTypeAttributes();
197    }
198
199    public List<Attribute.TypeCompound> getInitTypeAttributes() {
200        return (metadata == null)
201                ? List.<Attribute.TypeCompound>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.<Attribute.Compound>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 List<Symbol> enclosedPackages = List.nil();
925
926        public Completer usesProvidesCompleter = Completer.NULL_COMPLETER;
927        public final Set<ModuleFlags> flags = EnumSet.noneOf(ModuleFlags.class);
928        public final Set<ModuleResolutionFlags> resolutionFlags = EnumSet.noneOf(ModuleResolutionFlags.class);
929
930        /**
931         * Create a ModuleSymbol with an associated module-info ClassSymbol.
932         */
933        public static ModuleSymbol create(Name name, Name module_info) {
934            ModuleSymbol msym = new ModuleSymbol(name, null);
935            ClassSymbol info = new ClassSymbol(Flags.MODULE, module_info, msym);
936            info.fullname = formFullName(module_info, msym);
937            info.flatname = info.fullname;
938            info.members_field = WriteableScope.create(info);
939            msym.module_info = info;
940            return msym;
941        }
942
943        public ModuleSymbol(Name name, Symbol owner) {
944            super(MDL, 0, name, null, owner);
945            Assert.checkNonNull(name);
946            this.type = new ModuleType(this);
947        }
948
949        @Override @DefinedBy(Api.LANGUAGE_MODEL)
950        public boolean isUnnamed() {
951            return name.isEmpty() && owner == null;
952        }
953
954        @Override
955        public boolean isDeprecated() {
956            return hasDeprecatedAnnotation();
957        }
958
959        public boolean isNoModule() {
960            return false;
961        }
962
963        @Override @DefinedBy(Api.LANGUAGE_MODEL)
964        public ElementKind getKind() {
965            return ElementKind.MODULE;
966        }
967
968        @Override @DefinedBy(Api.LANGUAGE_MODEL)
969        public java.util.List<Directive> getDirectives() {
970            complete();
971            completeUsesProvides();
972            return Collections.unmodifiableList(directives);
973        }
974
975        public void completeUsesProvides() {
976            if (usesProvidesCompleter != Completer.NULL_COMPLETER) {
977                Completer c = usesProvidesCompleter;
978                usesProvidesCompleter = Completer.NULL_COMPLETER;
979                c.complete(this);
980            }
981        }
982
983        @Override
984        public ClassSymbol outermostClass() {
985            return null;
986        }
987
988        @Override
989        public String toString() {
990            // TODO: the following strings should be localized
991            // Do this with custom anon subtypes in Symtab
992            String n = (name == null) ? "<unknown>"
993                    : (name.isEmpty()) ? "<unnamed>"
994                    : String.valueOf(name);
995            return n;
996        }
997
998        @Override @DefinedBy(Api.LANGUAGE_MODEL)
999        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1000            return v.visitModule(this, p);
1001        }
1002
1003        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1004        public List<Symbol> getEnclosedElements() {
1005            List<Symbol> list = List.nil();
1006            for (Symbol sym : enclosedPackages) {
1007                if (sym.members().anyMatch(m -> m.kind == TYP))
1008                    list = list.prepend(sym);
1009            }
1010            return list;
1011        }
1012
1013        public void reset() {
1014            this.directives = null;
1015            this.requires = null;
1016            this.exports = null;
1017            this.provides = null;
1018            this.uses = null;
1019            this.visiblePackages = null;
1020        }
1021
1022    }
1023
1024    public enum ModuleFlags {
1025        OPEN(0x0020),
1026        SYNTHETIC(0x1000),
1027        MANDATED(0x8000);
1028
1029        public static int value(Set<ModuleFlags> s) {
1030            int v = 0;
1031            for (ModuleFlags f: s)
1032                v |= f.value;
1033            return v;
1034        }
1035
1036        private ModuleFlags(int value) {
1037            this.value = value;
1038        }
1039
1040        public final int value;
1041    }
1042
1043    public enum ModuleResolutionFlags {
1044        DO_NOT_RESOLVE_BY_DEFAULT(0x0001),
1045        WARN_DEPRECATED(0x0002),
1046        WARN_DEPRECATED_REMOVAL(0x0004),
1047        WARN_INCUBATOR(0x0008);
1048
1049        public static int value(Set<ModuleResolutionFlags> s) {
1050            int v = 0;
1051            for (ModuleResolutionFlags f: s)
1052                v |= f.value;
1053            return v;
1054        }
1055
1056        private ModuleResolutionFlags(int value) {
1057            this.value = value;
1058        }
1059
1060        public final int value;
1061    }
1062
1063    /** A class for package symbols
1064     */
1065    public static class PackageSymbol extends TypeSymbol
1066        implements PackageElement {
1067
1068        public WriteableScope members_field;
1069        public Name fullname;
1070        public ClassSymbol package_info; // see bug 6443073
1071        public ModuleSymbol modle;
1072
1073        public PackageSymbol(Name name, Type type, Symbol owner) {
1074            super(PCK, 0, name, type, owner);
1075            this.members_field = null;
1076            this.fullname = formFullName(name, owner);
1077        }
1078
1079        public PackageSymbol(Name name, Symbol owner) {
1080            this(name, null, owner);
1081            this.type = new PackageType(this);
1082        }
1083
1084        public String toString() {
1085            return fullname.toString();
1086        }
1087
1088        @DefinedBy(Api.LANGUAGE_MODEL)
1089        public Name getQualifiedName() {
1090            return fullname;
1091        }
1092
1093        @DefinedBy(Api.LANGUAGE_MODEL)
1094        public boolean isUnnamed() {
1095            return name.isEmpty() && owner != null;
1096        }
1097
1098        public WriteableScope members() {
1099            complete();
1100            return members_field;
1101        }
1102
1103        public long flags() {
1104            complete();
1105            return flags_field;
1106        }
1107
1108        @Override
1109        public List<Attribute.Compound> getRawAttributes() {
1110            complete();
1111            if (package_info != null) {
1112                package_info.complete();
1113                mergeAttributes();
1114            }
1115            return super.getRawAttributes();
1116        }
1117
1118        private void mergeAttributes() {
1119            if (metadata == null &&
1120                package_info.metadata != null) {
1121                metadata = new SymbolMetadata(this);
1122                metadata.setAttributes(package_info.metadata);
1123            }
1124        }
1125
1126        /** A package "exists" if a type or package that exists has
1127         *  been seen within it.
1128         */
1129        public boolean exists() {
1130            return (flags_field & EXISTS) != 0;
1131        }
1132
1133        @DefinedBy(Api.LANGUAGE_MODEL)
1134        public ElementKind getKind() {
1135            return ElementKind.PACKAGE;
1136        }
1137
1138        @DefinedBy(Api.LANGUAGE_MODEL)
1139        public Symbol getEnclosingElement() {
1140            return modle != null && !modle.isNoModule() ? modle : null;
1141        }
1142
1143        @DefinedBy(Api.LANGUAGE_MODEL)
1144        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1145            return v.visitPackage(this, p);
1146        }
1147
1148        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1149            return v.visitPackageSymbol(this, p);
1150        }
1151
1152        /**Resets the Symbol into the state good for next round of annotation processing.*/
1153        public void reset() {
1154            metadata = null;
1155        }
1156
1157    }
1158
1159    /** A class for class symbols
1160     */
1161    public static class ClassSymbol extends TypeSymbol implements TypeElement {
1162
1163        /** a scope for all class members; variables, methods and inner classes
1164         *  type parameters are not part of this scope
1165         */
1166        public WriteableScope members_field;
1167
1168        /** the fully qualified name of the class, i.e. pck.outer.inner.
1169         *  null for anonymous classes
1170         */
1171        public Name fullname;
1172
1173        /** the fully qualified name of the class after converting to flat
1174         *  representation, i.e. pck.outer$inner,
1175         *  set externally for local and anonymous classes
1176         */
1177        public Name flatname;
1178
1179        /** the sourcefile where the class came from
1180         */
1181        public JavaFileObject sourcefile;
1182
1183        /** the classfile from where to load this class
1184         *  this will have extension .class or .java
1185         */
1186        public JavaFileObject classfile;
1187
1188        /** the list of translated local classes (used for generating
1189         * InnerClasses attribute)
1190         */
1191        public List<ClassSymbol> trans_local;
1192
1193        /** the constant pool of the class
1194         */
1195        public Pool pool;
1196
1197        /** the annotation metadata attached to this class */
1198        private AnnotationTypeMetadata annotationTypeMetadata;
1199
1200        public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
1201            super(TYP, flags, name, type, owner);
1202            this.members_field = null;
1203            this.fullname = formFullName(name, owner);
1204            this.flatname = formFlatName(name, owner);
1205            this.sourcefile = null;
1206            this.classfile = null;
1207            this.pool = null;
1208            this.annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1209        }
1210
1211        public ClassSymbol(long flags, Name name, Symbol owner) {
1212            this(
1213                flags,
1214                name,
1215                new ClassType(Type.noType, null, null),
1216                owner);
1217            this.type.tsym = this;
1218        }
1219
1220        /** The Java source which this symbol represents.
1221         */
1222        public String toString() {
1223            return className();
1224        }
1225
1226        public long flags() {
1227            complete();
1228            return flags_field;
1229        }
1230
1231        public WriteableScope members() {
1232            complete();
1233            return members_field;
1234        }
1235
1236        @Override
1237        public List<Attribute.Compound> getRawAttributes() {
1238            complete();
1239            return super.getRawAttributes();
1240        }
1241
1242        @Override
1243        public List<Attribute.TypeCompound> getRawTypeAttributes() {
1244            complete();
1245            return super.getRawTypeAttributes();
1246        }
1247
1248        public Type erasure(Types types) {
1249            if (erasure_field == null)
1250                erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
1251                                              List.<Type>nil(), this,
1252                                              type.getMetadata());
1253            return erasure_field;
1254        }
1255
1256        public String className() {
1257            if (name.isEmpty())
1258                return
1259                    Log.getLocalizedString("anonymous.class", flatname);
1260            else
1261                return fullname.toString();
1262        }
1263
1264        @DefinedBy(Api.LANGUAGE_MODEL)
1265        public Name getQualifiedName() {
1266            return fullname;
1267        }
1268
1269        public Name flatName() {
1270            return flatname;
1271        }
1272
1273        public boolean isSubClass(Symbol base, Types types) {
1274            if (this == base) {
1275                return true;
1276            } else if ((base.flags() & INTERFACE) != 0) {
1277                for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1278                    for (List<Type> is = types.interfaces(t);
1279                         is.nonEmpty();
1280                         is = is.tail)
1281                        if (is.head.tsym.isSubClass(base, types)) return true;
1282            } else {
1283                for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1284                    if (t.tsym == base) return true;
1285            }
1286            return false;
1287        }
1288
1289        /** Complete the elaboration of this symbol's definition.
1290         */
1291        public void complete() throws CompletionFailure {
1292            try {
1293                super.complete();
1294            } catch (CompletionFailure ex) {
1295                // quiet error recovery
1296                flags_field |= (PUBLIC|STATIC);
1297                this.type = new ErrorType(this, Type.noType);
1298                throw ex;
1299            }
1300        }
1301
1302        @DefinedBy(Api.LANGUAGE_MODEL)
1303        public List<Type> getInterfaces() {
1304            complete();
1305            if (type instanceof ClassType) {
1306                ClassType t = (ClassType)type;
1307                if (t.interfaces_field == null) // FIXME: shouldn't be null
1308                    t.interfaces_field = List.nil();
1309                if (t.all_interfaces_field != null)
1310                    return Type.getModelTypes(t.all_interfaces_field);
1311                return t.interfaces_field;
1312            } else {
1313                return List.nil();
1314            }
1315        }
1316
1317        @DefinedBy(Api.LANGUAGE_MODEL)
1318        public Type getSuperclass() {
1319            complete();
1320            if (type instanceof ClassType) {
1321                ClassType t = (ClassType)type;
1322                if (t.supertype_field == null) // FIXME: shouldn't be null
1323                    t.supertype_field = Type.noType;
1324                // An interface has no superclass; its supertype is Object.
1325                return t.isInterface()
1326                    ? Type.noType
1327                    : t.supertype_field.getModelType();
1328            } else {
1329                return Type.noType;
1330            }
1331        }
1332
1333        /**
1334         * Returns the next class to search for inherited annotations or {@code null}
1335         * if the next class can't be found.
1336         */
1337        private ClassSymbol getSuperClassToSearchForAnnotations() {
1338
1339            Type sup = getSuperclass();
1340
1341            if (!sup.hasTag(CLASS) || sup.isErroneous())
1342                return null;
1343
1344            return (ClassSymbol) sup.tsym;
1345        }
1346
1347
1348        @Override
1349        protected <A extends Annotation> A[] getInheritedAnnotations(Class<A> annoType) {
1350
1351            ClassSymbol sup = getSuperClassToSearchForAnnotations();
1352
1353            return sup == null ? super.getInheritedAnnotations(annoType)
1354                               : sup.getAnnotationsByType(annoType);
1355        }
1356
1357
1358        @DefinedBy(Api.LANGUAGE_MODEL)
1359        public ElementKind getKind() {
1360            long flags = flags();
1361            if ((flags & ANNOTATION) != 0)
1362                return ElementKind.ANNOTATION_TYPE;
1363            else if ((flags & INTERFACE) != 0)
1364                return ElementKind.INTERFACE;
1365            else if ((flags & ENUM) != 0)
1366                return ElementKind.ENUM;
1367            else
1368                return ElementKind.CLASS;
1369        }
1370
1371        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1372        public Set<Modifier> getModifiers() {
1373            long flags = flags();
1374            return Flags.asModifierSet(flags & ~DEFAULT);
1375        }
1376
1377        @DefinedBy(Api.LANGUAGE_MODEL)
1378        public NestingKind getNestingKind() {
1379            complete();
1380            if (owner.kind == PCK)
1381                return NestingKind.TOP_LEVEL;
1382            else if (name.isEmpty())
1383                return NestingKind.ANONYMOUS;
1384            else if (owner.kind == MTH)
1385                return NestingKind.LOCAL;
1386            else
1387                return NestingKind.MEMBER;
1388        }
1389
1390
1391        @Override
1392        protected <A extends Annotation> Attribute.Compound getAttribute(final Class<A> annoType) {
1393
1394            Attribute.Compound attrib = super.getAttribute(annoType);
1395
1396            boolean inherited = annoType.isAnnotationPresent(Inherited.class);
1397            if (attrib != null || !inherited)
1398                return attrib;
1399
1400            // Search supertypes
1401            ClassSymbol superType = getSuperClassToSearchForAnnotations();
1402            return superType == null ? null
1403                                     : superType.getAttribute(annoType);
1404        }
1405
1406
1407
1408
1409        @DefinedBy(Api.LANGUAGE_MODEL)
1410        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1411            return v.visitType(this, p);
1412        }
1413
1414        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1415            return v.visitClassSymbol(this, p);
1416        }
1417
1418        public void markAbstractIfNeeded(Types types) {
1419            if (types.enter.getEnv(this) != null &&
1420                (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym &&
1421                (flags() & (FINAL | ABSTRACT)) == 0) {
1422                if (types.firstUnimplementedAbstract(this) != null)
1423                    // add the ABSTRACT flag to an enum
1424                    flags_field |= ABSTRACT;
1425            }
1426        }
1427
1428        /**Resets the Symbol into the state good for next round of annotation processing.*/
1429        public void reset() {
1430            kind = TYP;
1431            erasure_field = null;
1432            members_field = null;
1433            flags_field = 0;
1434            if (type instanceof ClassType) {
1435                ClassType t = (ClassType)type;
1436                t.setEnclosingType(Type.noType);
1437                t.rank_field = -1;
1438                t.typarams_field = null;
1439                t.allparams_field = null;
1440                t.supertype_field = null;
1441                t.interfaces_field = null;
1442                t.all_interfaces_field = null;
1443            }
1444            clearAnnotationMetadata();
1445        }
1446
1447        public void clearAnnotationMetadata() {
1448            metadata = null;
1449            annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1450        }
1451
1452        @Override
1453        public AnnotationTypeMetadata getAnnotationTypeMetadata() {
1454            return annotationTypeMetadata;
1455        }
1456
1457        @Override
1458        public boolean isAnnotationType() {
1459            return (flags_field & Flags.ANNOTATION) != 0;
1460        }
1461
1462        public void setAnnotationTypeMetadata(AnnotationTypeMetadata a) {
1463            Assert.checkNonNull(a);
1464            Assert.check(!annotationTypeMetadata.isMetadataForAnnotationType());
1465            this.annotationTypeMetadata = a;
1466        }
1467    }
1468
1469
1470    /** A class for variable symbols
1471     */
1472    public static class VarSymbol extends Symbol implements VariableElement {
1473
1474        /** The variable's declaration position.
1475         */
1476        public int pos = Position.NOPOS;
1477
1478        /** The variable's address. Used for different purposes during
1479         *  flow analysis, translation and code generation.
1480         *  Flow analysis:
1481         *    If this is a blank final or local variable, its sequence number.
1482         *  Translation:
1483         *    If this is a private field, its access number.
1484         *  Code generation:
1485         *    If this is a local variable, its logical slot number.
1486         */
1487        public int adr = -1;
1488
1489        /** Construct a variable symbol, given its flags, name, type and owner.
1490         */
1491        public VarSymbol(long flags, Name name, Type type, Symbol owner) {
1492            super(VAR, flags, name, type, owner);
1493        }
1494
1495        /** Clone this symbol with new owner.
1496         */
1497        public VarSymbol clone(Symbol newOwner) {
1498            VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) {
1499                @Override
1500                public Symbol baseSymbol() {
1501                    return VarSymbol.this;
1502                }
1503            };
1504            v.pos = pos;
1505            v.adr = adr;
1506            v.data = data;
1507//          System.out.println("clone " + v + " in " + newOwner);//DEBUG
1508            return v;
1509        }
1510
1511        public String toString() {
1512            return name.toString();
1513        }
1514
1515        public Symbol asMemberOf(Type site, Types types) {
1516            return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
1517        }
1518
1519        @DefinedBy(Api.LANGUAGE_MODEL)
1520        public ElementKind getKind() {
1521            long flags = flags();
1522            if ((flags & PARAMETER) != 0) {
1523                if (isExceptionParameter())
1524                    return ElementKind.EXCEPTION_PARAMETER;
1525                else
1526                    return ElementKind.PARAMETER;
1527            } else if ((flags & ENUM) != 0) {
1528                return ElementKind.ENUM_CONSTANT;
1529            } else if (owner.kind == TYP || owner.kind == ERR) {
1530                return ElementKind.FIELD;
1531            } else if (isResourceVariable()) {
1532                return ElementKind.RESOURCE_VARIABLE;
1533            } else {
1534                return ElementKind.LOCAL_VARIABLE;
1535            }
1536        }
1537
1538        @DefinedBy(Api.LANGUAGE_MODEL)
1539        public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1540            return v.visitVariable(this, p);
1541        }
1542
1543        @DefinedBy(Api.LANGUAGE_MODEL)
1544        public Object getConstantValue() { // Mirror API
1545            return Constants.decode(getConstValue(), type);
1546        }
1547
1548        public void setLazyConstValue(final Env<AttrContext> env,
1549                                      final Attr attr,
1550                                      final JCVariableDecl variable)
1551        {
1552            setData(new Callable<Object>() {
1553                public Object call() {
1554                    return attr.attribLazyConstantValue(env, variable, type);
1555                }
1556            });
1557        }
1558
1559        /**
1560         * The variable's constant value, if this is a constant.
1561         * Before the constant value is evaluated, it points to an
1562         * initializer environment.  If this is not a constant, it can
1563         * be used for other stuff.
1564         */
1565        private Object data;
1566
1567        public boolean isExceptionParameter() {
1568            return data == ElementKind.EXCEPTION_PARAMETER;
1569        }
1570
1571        public boolean isResourceVariable() {
1572            return data == ElementKind.RESOURCE_VARIABLE;
1573        }
1574
1575        public Object getConstValue() {
1576            // TODO: Consider if getConstValue and getConstantValue can be collapsed
1577            if (data == ElementKind.EXCEPTION_PARAMETER ||
1578                data == ElementKind.RESOURCE_VARIABLE) {
1579                return null;
1580            } else if (data instanceof Callable<?>) {
1581                // In this case, this is a final variable, with an as
1582                // yet unevaluated initializer.
1583                Callable<?> eval = (Callable<?>)data;
1584                data = null; // to make sure we don't evaluate this twice.
1585                try {
1586                    data = eval.call();
1587                } catch (Exception ex) {
1588                    throw new AssertionError(ex);
1589                }
1590            }
1591            return data;
1592        }
1593
1594        public void setData(Object data) {
1595            Assert.check(!(data instanceof Env<?>), this);
1596            this.data = data;
1597        }
1598
1599        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1600            return v.visitVarSymbol(this, p);
1601        }
1602    }
1603
1604    /** A class for method symbols.
1605     */
1606    public static class MethodSymbol extends Symbol implements ExecutableElement {
1607
1608        /** The code of the method. */
1609        public Code code = null;
1610
1611        /** The extra (synthetic/mandated) parameters of the method. */
1612        public List<VarSymbol> extraParams = List.nil();
1613
1614        /** The captured local variables in an anonymous class */
1615        public List<VarSymbol> capturedLocals = List.nil();
1616
1617        /** The parameters of the method. */
1618        public List<VarSymbol> params = null;
1619
1620        /** The names of the parameters */
1621        public List<Name> savedParameterNames;
1622
1623        /** For an annotation type element, its default value if any.
1624         *  The value is null if none appeared in the method
1625         *  declaration.
1626         */
1627        public Attribute defaultValue = null;
1628
1629        /** Construct a method symbol, given its flags, name, type and owner.
1630         */
1631        public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1632            super(MTH, flags, name, type, owner);
1633            if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name);
1634        }
1635
1636        /** Clone this symbol with new owner.
1637         */
1638        public MethodSymbol clone(Symbol newOwner) {
1639            MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) {
1640                @Override
1641                public Symbol baseSymbol() {
1642                    return MethodSymbol.this;
1643                }
1644            };
1645            m.code = code;
1646            return m;
1647        }
1648
1649        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1650        public Set<Modifier> getModifiers() {
1651            long flags = flags();
1652            return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags);
1653        }
1654
1655        /** The Java source which this symbol represents.
1656         */
1657        public String toString() {
1658            if ((flags() & BLOCK) != 0) {
1659                return owner.name.toString();
1660            } else {
1661                String s = (name == name.table.names.init)
1662                    ? owner.name.toString()
1663                    : name.toString();
1664                if (type != null) {
1665                    if (type.hasTag(FORALL))
1666                        s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1667                    s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1668                }
1669                return s;
1670            }
1671        }
1672
1673        public boolean isDynamic() {
1674            return false;
1675        }
1676
1677        /** find a symbol that this (proxy method) symbol implements.
1678         *  @param    c       The class whose members are searched for
1679         *                    implementations
1680         */
1681        public Symbol implemented(TypeSymbol c, Types types) {
1682            Symbol impl = null;
1683            for (List<Type> is = types.interfaces(c.type);
1684                 impl == null && is.nonEmpty();
1685                 is = is.tail) {
1686                TypeSymbol i = is.head.tsym;
1687                impl = implementedIn(i, types);
1688                if (impl == null)
1689                    impl = implemented(i, types);
1690            }
1691            return impl;
1692        }
1693
1694        public Symbol implementedIn(TypeSymbol c, Types types) {
1695            Symbol impl = null;
1696            for (Symbol sym : c.members().getSymbolsByName(name)) {
1697                if (this.overrides(sym, (TypeSymbol)owner, types, true) &&
1698                    // FIXME: I suspect the following requires a
1699                    // subst() for a parametric return type.
1700                    types.isSameType(type.getReturnType(),
1701                                     types.memberType(owner.type, sym).getReturnType())) {
1702                    impl = sym;
1703                }
1704            }
1705            return impl;
1706        }
1707
1708        /** Will the erasure of this method be considered by the VM to
1709         *  override the erasure of the other when seen from class `origin'?
1710         */
1711        public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1712            if (isConstructor() || _other.kind != MTH) return false;
1713
1714            if (this == _other) return true;
1715            MethodSymbol other = (MethodSymbol)_other;
1716
1717            // check for a direct implementation
1718            if (other.isOverridableIn((TypeSymbol)owner) &&
1719                types.asSuper(owner.type, other.owner) != null &&
1720                types.isSameType(erasure(types), other.erasure(types)))
1721                return true;
1722
1723            // check for an inherited implementation
1724            return
1725                (flags() & ABSTRACT) == 0 &&
1726                other.isOverridableIn(origin) &&
1727                this.isMemberOf(origin, types) &&
1728                types.isSameType(erasure(types), other.erasure(types));
1729        }
1730
1731        /** The implementation of this (abstract) symbol in class origin,
1732         *  from the VM's point of view, null if method does not have an
1733         *  implementation in class.
1734         *  @param origin   The class of which the implementation is a member.
1735         */
1736        public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1737            for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1738                for (Symbol sym : c.members().getSymbolsByName(name)) {
1739                    if (sym.kind == MTH &&
1740                        ((MethodSymbol)sym).binaryOverrides(this, origin, types))
1741                        return (MethodSymbol)sym;
1742                }
1743            }
1744            return null;
1745        }
1746
1747        /** Does this symbol override `other' symbol, when both are seen as
1748         *  members of class `origin'?  It is assumed that _other is a member
1749         *  of origin.
1750         *
1751         *  It is assumed that both symbols have the same name.  The static
1752         *  modifier is ignored for this test.
1753         *
1754         *  A quirk in the works is that if the receiver is a method symbol for
1755         *  an inherited abstract method we answer false summarily all else being
1756         *  immaterial. Abstract "own" methods (i.e `this' is a direct member of
1757         *  origin) don't get rejected as summarily and are put to test against the
1758         *  suitable criteria.
1759         *
1760         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1761         */
1762        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1763            return overrides(_other, origin, types, checkResult, true);
1764        }
1765
1766        /** Does this symbol override `other' symbol, when both are seen as
1767         *  members of class `origin'?  It is assumed that _other is a member
1768         *  of origin.
1769         *
1770         *  Caveat: If `this' is an abstract inherited member of origin, it is
1771         *  deemed to override `other' only when `requireConcreteIfInherited'
1772         *  is false.
1773         *
1774         *  It is assumed that both symbols have the same name.  The static
1775         *  modifier is ignored for this test.
1776         *
1777         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1778         */
1779        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult,
1780                                            boolean requireConcreteIfInherited) {
1781            if (isConstructor() || _other.kind != MTH) return false;
1782
1783            if (this == _other) return true;
1784            MethodSymbol other = (MethodSymbol)_other;
1785
1786            // check for a direct implementation
1787            if (other.isOverridableIn((TypeSymbol)owner) &&
1788                types.asSuper(owner.type, other.owner) != null) {
1789                Type mt = types.memberType(owner.type, this);
1790                Type ot = types.memberType(owner.type, other);
1791                if (types.isSubSignature(mt, ot)) {
1792                    if (!checkResult)
1793                        return true;
1794                    if (types.returnTypeSubstitutable(mt, ot))
1795                        return true;
1796                }
1797            }
1798
1799            // check for an inherited implementation
1800            if (((flags() & ABSTRACT) != 0 && requireConcreteIfInherited) ||
1801                    ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
1802                    !other.isOverridableIn(origin) ||
1803                    !this.isMemberOf(origin, types))
1804                return false;
1805
1806            // assert types.asSuper(origin.type, other.owner) != null;
1807            Type mt = types.memberType(origin.type, this);
1808            Type ot = types.memberType(origin.type, other);
1809            return
1810                types.isSubSignature(mt, ot) &&
1811                (!checkResult || types.resultSubtype(mt, ot, types.noWarnings));
1812        }
1813
1814        private boolean isOverridableIn(TypeSymbol origin) {
1815            // JLS 8.4.6.1
1816            switch ((int)(flags_field & Flags.AccessFlags)) {
1817            case Flags.PRIVATE:
1818                return false;
1819            case Flags.PUBLIC:
1820                return !this.owner.isInterface() ||
1821                        (flags_field & STATIC) == 0;
1822            case Flags.PROTECTED:
1823                return (origin.flags() & INTERFACE) == 0;
1824            case 0:
1825                // for package private: can only override in the same
1826                // package
1827                return
1828                    this.packge() == origin.packge() &&
1829                    (origin.flags() & INTERFACE) == 0;
1830            default:
1831                return false;
1832            }
1833        }
1834
1835        @Override
1836        public boolean isInheritedIn(Symbol clazz, Types types) {
1837            switch ((int)(flags_field & Flags.AccessFlags)) {
1838                case PUBLIC:
1839                    return !this.owner.isInterface() ||
1840                            clazz == owner ||
1841                            (flags_field & STATIC) == 0;
1842                default:
1843                    return super.isInheritedIn(clazz, types);
1844            }
1845        }
1846
1847        public boolean isLambdaMethod() {
1848            return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD;
1849        }
1850
1851        /** The implementation of this (abstract) symbol in class origin;
1852         *  null if none exists. Synthetic methods are not considered
1853         *  as possible implementations.
1854         */
1855        public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1856            return implementation(origin, types, checkResult, implementation_filter);
1857        }
1858        // where
1859            public static final Filter<Symbol> implementation_filter = new Filter<Symbol>() {
1860                public boolean accepts(Symbol s) {
1861                    return s.kind == MTH &&
1862                            (s.flags() & SYNTHETIC) == 0;
1863                }
1864            };
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