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