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