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