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