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