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