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