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