001    /*
002     * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
003     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004     *
005     * This code is free software; you can redistribute it and/or modify it
006     * under the terms of the GNU General Public License version 2 only, as
007     * published by the Free Software Foundation.  Sun designates this
008     * particular file as subject to the "Classpath" exception as provided
009     * by Sun in the LICENSE file that accompanied this code.
010     *
011     * This code is distributed in the hope that it will be useful, but WITHOUT
012     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013     * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014     * version 2 for more details (a copy is included in the LICENSE file that
015     * accompanied this code).
016     *
017     * You should have received a copy of the GNU General Public License version
018     * 2 along with this work; if not, write to the Free Software Foundation,
019     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020     *
021     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022     * CA 95054 USA or visit www.sun.com if you need additional information or
023     * have any questions.
024     */
025    
026    package com.sun.tools.javac.code;
027    
028    import java.util.Set;
029    import java.util.concurrent.Callable;
030    import javax.lang.model.element.*;
031    import javax.tools.JavaFileObject;
032    
033    import com.sun.tools.javac.util.*;
034    import com.sun.tools.javac.util.Name;
035    import com.sun.tools.javac.code.Type.*;
036    import com.sun.tools.javac.comp.Attr;
037    import com.sun.tools.javac.comp.AttrContext;
038    import com.sun.tools.javac.comp.Env;
039    import com.sun.tools.javac.jvm.*;
040    import com.sun.tools.javac.model.*;
041    import com.sun.tools.javac.tree.JCTree;
042    
043    import static com.sun.tools.javac.code.Flags.*;
044    import static com.sun.tools.javac.code.Kinds.*;
045    import static com.sun.tools.javac.code.TypeTags.*;
046    
047    /** Root class for Java symbols. It contains subclasses
048     *  for specific sorts of symbols, such as variables, methods and operators,
049     *  types, packages. Each subclass is represented as a static inner class
050     *  inside Symbol.
051     *
052     *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
053     *  you write code that depends on this, you do so at your own risk.
054     *  This code and its internal interfaces are subject to change or
055     *  deletion without notice.</b>
056     */
057    public abstract class Symbol implements Element {
058        // public Throwable debug = new Throwable();
059    
060        /** The kind of this symbol.
061         *  @see Kinds
062         */
063        public int kind;
064    
065        /** The flags of this symbol.
066         */
067        public long flags_field;
068    
069        /** An accessor method for the flags of this symbol.
070         *  Flags of class symbols should be accessed through the accessor
071         *  method to make sure that the class symbol is loaded.
072         */
073        public long flags() { return flags_field; }
074    
075        /** The attributes of this symbol.
076         */
077        public List<Attribute.Compound> attributes_field;
078    
079        /** An accessor method for the attributes of this symbol.
080         *  Attributes of class symbols should be accessed through the accessor
081         *  method to make sure that the class symbol is loaded.
082         */
083        public List<Attribute.Compound> getAnnotationMirrors() {
084            assert attributes_field != null;
085            return attributes_field;
086        }
087    
088        /** Fetch a particular annotation from a symbol. */
089        public Attribute.Compound attribute(Symbol anno) {
090            for (Attribute.Compound a : getAnnotationMirrors())
091                if (a.type.tsym == anno) return a;
092            return null;
093        }
094    
095        /** The name of this symbol in Utf8 representation.
096         */
097        public Name name;
098    
099        /** The type of this symbol.
100         */
101        public Type type;
102    
103        /** The owner of this symbol.
104         */
105        public Symbol owner;
106    
107        /** The completer of this symbol.
108         */
109        public Completer completer;
110    
111        /** A cache for the type erasure of this symbol.
112         */
113        public Type erasure_field;
114    
115        /** Construct a symbol with given kind, flags, name, type and owner.
116         */
117        public Symbol(int kind, long flags, Name name, Type type, Symbol owner) {
118            this.kind = kind;
119            this.flags_field = flags;
120            this.type = type;
121            this.owner = owner;
122            this.completer = null;
123            this.erasure_field = null;
124            this.attributes_field = List.nil();
125            this.name = name;
126        }
127    
128        /** Clone this symbol with new owner.
129         *  Legal only for fields and methods.
130         */
131        public Symbol clone(Symbol newOwner) {
132            throw new AssertionError();
133        }
134    
135        public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
136            return v.visitSymbol(this, p);
137        }
138    
139        /** The Java source which this symbol represents.
140         *  A description of this symbol; overrides Object.
141         */
142        public String toString() {
143            return name.toString();
144        }
145        
146        // mgr: staging additions
147        public Level level = new Level(0);
148        public int getLevel() { return level.getLevel(); }
149        public void addParentLevel(Level l) { level.addParent(l); }
150        public void removeParentLevel(Level l) { level.removeParent(l); }
151    
152        /** A Java source description of the location of this symbol; used for
153         *  error reporting.
154         *
155         * @return null if the symbol is a package or a toplevel class defined in
156         * the default package; otherwise, the owner symbol is returned
157         */
158        public Symbol location() {
159            if (owner.name == null || (owner.name.isEmpty() && owner.kind != PCK)) {
160                return null;
161            }
162            return owner;
163        }
164    
165        public Symbol location(Type site, Types types) {
166            if (owner.name == null || owner.name.isEmpty()) {
167                return location();
168            }
169            if (owner.type.tag == CLASS) {
170                Type ownertype = types.asOuterSuper(site, owner);
171                if (ownertype != null) return ownertype.tsym;
172            }
173            return owner;
174        }
175    
176        /** The symbol's erased type.
177         */
178        public Type erasure(Types types) {
179            if (erasure_field == null)
180                erasure_field = types.erasure(type);
181            return erasure_field;
182        }
183    
184        /** The external type of a symbol. This is the symbol's erased type
185         *  except for constructors of inner classes which get the enclosing
186         *  instance class added as first argument.
187         */
188        public Type externalType(Types types) {
189            Type t = erasure(types);
190            if (name == name.table.names.init && owner.hasOuterInstance()) {
191                Type outerThisType = types.erasure(owner.type.getEnclosingType());
192                return new MethodType(t.getParameterTypes().prepend(outerThisType),
193                                      t.getReturnType(),
194                                      t.getThrownTypes(),
195                                      t.tsym);
196            } else {
197                return t;
198            }
199        }
200    
201        public boolean isStatic() {
202            return
203                (flags() & STATIC) != 0 ||
204                (owner.flags() & INTERFACE) != 0 && kind != MTH;
205        }
206    
207        public boolean isInterface() {
208            return (flags() & INTERFACE) != 0;
209        }
210    
211        /** Is this symbol declared (directly or indirectly) local
212         *  to a method or variable initializer?
213         *  Also includes fields of inner classes which are in
214         *  turn local to a method or variable initializer.
215         */
216        public boolean isLocal() {
217            return
218                (owner.kind & (VAR | MTH)) != 0 ||
219                (owner.kind == TYP && owner.isLocal());
220        }
221    
222        /** Is this symbol a constructor?
223         */
224        public boolean isConstructor() {
225            return name == name.table.names.init;
226        }
227    
228        /** The fully qualified name of this symbol.
229         *  This is the same as the symbol's name except for class symbols,
230         *  which are handled separately.
231         */
232        public Name getQualifiedName() {
233            return name;
234        }
235    
236        /** The fully qualified name of this symbol after converting to flat
237         *  representation. This is the same as the symbol's name except for
238         *  class symbols, which are handled separately.
239         */
240        public Name flatName() {
241            return getQualifiedName();
242        }
243    
244        /** If this is a class or package, its members, otherwise null.
245         */
246        public Scope members() {
247            return null;
248        }
249    
250        /** A class is an inner class if it it has an enclosing instance class.
251         */
252        public boolean isInner() {
253            return type.getEnclosingType().tag == CLASS;
254        }
255    
256        /** An inner class has an outer instance if it is not an interface
257         *  it has an enclosing instance class which might be referenced from the class.
258         *  Nested classes can see instance members of their enclosing class.
259         *  Their constructors carry an additional this$n parameter, inserted
260         *  implicitly by the compiler.
261         *
262         *  @see #isInner
263         */
264        public boolean hasOuterInstance() {
265            return
266                type.getEnclosingType().tag == CLASS && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
267        }
268    
269        /** The closest enclosing class of this symbol's declaration.
270         */
271        public ClassSymbol enclClass() {
272            Symbol c = this;
273            while (c != null &&
274                   ((c.kind & TYP) == 0 || c.type.tag != CLASS)) {
275                c = c.owner;
276            }
277            return (ClassSymbol)c;
278        }
279    
280        /** The outermost class which indirectly owns this symbol.
281         */
282        public ClassSymbol outermostClass() {
283            Symbol sym = this;
284            Symbol prev = null;
285            while (sym.kind != PCK) {
286                prev = sym;
287                sym = sym.owner;
288            }
289            return (ClassSymbol) prev;
290        }
291    
292        /** The package which indirectly owns this symbol.
293         */
294        public PackageSymbol packge() {
295            Symbol sym = this;
296            while (sym.kind != PCK) {
297                sym = sym.owner;
298            }
299            return (PackageSymbol) sym;
300        }
301    
302        /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
303         */
304        public boolean isSubClass(Symbol base, Types types) {
305            throw new AssertionError("isSubClass " + this);
306        }
307    
308        /** Fully check membership: hierarchy, protection, and hiding.
309         *  Does not exclude methods not inherited due to overriding.
310         */
311        public boolean isMemberOf(TypeSymbol clazz, Types types) {
312            return
313                owner == clazz ||
314                clazz.isSubClass(owner, types) &&
315                isInheritedIn(clazz, types) &&
316                !hiddenIn((ClassSymbol)clazz, types);
317        }
318    
319        /** Is this symbol the same as or enclosed by the given class? */
320        public boolean isEnclosedBy(ClassSymbol clazz) {
321            for (Symbol sym = this; sym.kind != PCK; sym = sym.owner)
322                if (sym == clazz) return true;
323            return false;
324        }
325    
326        /** Check for hiding.  Note that this doesn't handle multiple
327         *  (interface) inheritance. */
328        private boolean hiddenIn(ClassSymbol clazz, Types types) {
329            if (kind == MTH && (flags() & STATIC) == 0) return false;
330            while (true) {
331                if (owner == clazz) return false;
332                Scope.Entry e = clazz.members().lookup(name);
333                while (e.scope != null) {
334                    if (e.sym == this) return false;
335                    if (e.sym.kind == kind &&
336                        (kind != MTH ||
337                         (e.sym.flags() & STATIC) != 0 &&
338                         types.isSubSignature(e.sym.type, type)))
339                        return true;
340                    e = e.next();
341                }
342                Type superType = types.supertype(clazz.type);
343                if (superType.tag != TypeTags.CLASS) return false;
344                clazz = (ClassSymbol)superType.tsym;
345            }
346        }
347    
348        /** Is this symbol inherited into a given class?
349         *  PRE: If symbol's owner is a interface,
350         *       it is already assumed that the interface is a superinterface
351         *       of given class.
352         *  @param clazz  The class for which we want to establish membership.
353         *                This must be a subclass of the member's owner.
354         */
355        public boolean isInheritedIn(Symbol clazz, Types types) {
356            switch ((int)(flags_field & Flags.AccessFlags)) {
357            default: // error recovery
358            case PUBLIC:
359                return true;
360            case PRIVATE:
361                return this.owner == clazz;
362            case PROTECTED:
363                // we model interfaces as extending Object
364                return (clazz.flags() & INTERFACE) == 0;
365            case 0:
366                PackageSymbol thisPackage = this.packge();
367                for (Symbol sup = clazz;
368                     sup != null && sup != this.owner;
369                     sup = types.supertype(sup.type).tsym) {
370                    while (sup.type.tag == TYPEVAR)
371                        sup = sup.type.getUpperBound().tsym;
372                    if (sup.type.isErroneous())
373                        return true; // error recovery
374                    if ((sup.flags() & COMPOUND) != 0)
375                        continue;
376                    if (sup.packge() != thisPackage)
377                        return false;
378                }
379                return (clazz.flags() & INTERFACE) == 0;
380            }
381        }
382    
383        /** The (variable or method) symbol seen as a member of given
384         *  class type`site' (this might change the symbol's type).
385         *  This is used exclusively for producing diagnostics.
386         */
387        public Symbol asMemberOf(Type site, Types types) {
388            throw new AssertionError();
389        }
390    
391        /** Does this method symbol override `other' symbol, when both are seen as
392         *  members of class `origin'?  It is assumed that _other is a member
393         *  of origin.
394         *
395         *  It is assumed that both symbols have the same name.  The static
396         *  modifier is ignored for this test.
397         *
398         *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
399         */
400        public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
401            return false;
402        }
403    
404        /** Complete the elaboration of this symbol's definition.
405         */
406        public void complete() throws CompletionFailure {
407            if (completer != null) {
408                Completer c = completer;
409                completer = null;
410                c.complete(this);
411            }
412        }
413    
414        /** True if the symbol represents an entity that exists.
415         */
416        public boolean exists() {
417            return true;
418        }
419    
420        public Type asType() {
421            return type;
422        }
423    
424        public Symbol getEnclosingElement() {
425            return owner;
426        }
427    
428        public ElementKind getKind() {
429            return ElementKind.OTHER;       // most unkind
430        }
431    
432        public Set<Modifier> getModifiers() {
433            return Flags.asModifierSet(flags());
434        }
435    
436        public Name getSimpleName() {
437            return name;
438        }
439    
440        /**
441         * @deprecated this method should never be used by javac internally.
442         */
443        @Deprecated
444        public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
445            return JavacElements.getAnnotation(this, annoType);
446        }
447    
448        // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
449        public java.util.List<Symbol> getEnclosedElements() {
450            return List.nil();
451        }
452    
453        public List<TypeSymbol> getTypeParameters() {
454            ListBuffer<TypeSymbol> l = ListBuffer.lb();
455            for (Type t : type.getTypeArguments()) {
456                l.append(t.tsym);
457            }
458            return l.toList();
459        }
460    
461        public static class DelegatedSymbol extends Symbol {
462            protected Symbol other;
463            public DelegatedSymbol(Symbol other) {
464                super(other.kind, other.flags_field, other.name, other.type, other.owner);
465                this.other = other;
466            }
467            public String toString() { return other.toString(); }
468            public Symbol location() { return other.location(); }
469            public Symbol location(Type site, Types types) { return other.location(site, types); }
470            public Type erasure(Types types) { return other.erasure(types); }
471            public Type externalType(Types types) { return other.externalType(types); }
472            public boolean isLocal() { return other.isLocal(); }
473            public boolean isConstructor() { return other.isConstructor(); }
474            public Name getQualifiedName() { return other.getQualifiedName(); }
475            public Name flatName() { return other.flatName(); }
476            public Scope members() { return other.members(); }
477            public boolean isInner() { return other.isInner(); }
478            public boolean hasOuterInstance() { return other.hasOuterInstance(); }
479            public ClassSymbol enclClass() { return other.enclClass(); }
480            public ClassSymbol outermostClass() { return other.outermostClass(); }
481            public PackageSymbol packge() { return other.packge(); }
482            public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
483            public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
484            public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
485            public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
486            public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
487            public void complete() throws CompletionFailure { other.complete(); }
488    
489            public <R, P> R accept(ElementVisitor<R, P> v, P p) {
490                return other.accept(v, p);
491            }
492    
493            public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
494                return v.visitSymbol(other, p);
495            }
496        }
497    
498        /** A class for type symbols. Type variables are represented by instances
499         *  of this class, classes and packages by instances of subclasses.
500         */
501        public static class TypeSymbol
502                extends Symbol implements TypeParameterElement {
503            // Implements TypeParameterElement because type parameters don't
504            // have their own TypeSymbol subclass.
505            // TODO: type parameters should have their own TypeSymbol subclass
506    
507            public TypeSymbol(long flags, Name name, Type type, Symbol owner) {
508                super(TYP, flags, name, type, owner);
509            }
510    
511            /** form a fully qualified name from a name and an owner
512             */
513            static public Name formFullName(Name name, Symbol owner) {
514                if (owner == null) return name;
515                if (((owner.kind != ERR)) &&
516                    ((owner.kind & (VAR | MTH)) != 0
517                     || (owner.kind == TYP && owner.type.tag == TYPEVAR)
518                     )) return name;
519                Name prefix = owner.getQualifiedName();
520                if (prefix == null || prefix == prefix.table.names.empty)
521                    return name;
522                else return prefix.append('.', name);
523            }
524    
525            /** form a fully qualified name from a name and an owner, after
526             *  converting to flat representation
527             */
528            static public Name formFlatName(Name name, Symbol owner) {
529                if (owner == null ||
530                    (owner.kind & (VAR | MTH)) != 0
531                    || (owner.kind == TYP && owner.type.tag == TYPEVAR)
532                    ) return name;
533                char sep = owner.kind == TYP ? '$' : '.';
534                Name prefix = owner.flatName();
535                if (prefix == null || prefix == prefix.table.names.empty)
536                    return name;
537                else return prefix.append(sep, name);
538            }
539    
540            /**
541             * A total ordering between type symbols that refines the
542             * class inheritance graph.
543             *
544             * Typevariables always precede other kinds of symbols.
545             */
546            public final boolean precedes(TypeSymbol that, Types types) {
547                if (this == that)
548                    return false;
549                if (this.type.tag == that.type.tag) {
550                    if (this.type.tag == CLASS) {
551                        return
552                            types.rank(that.type) < types.rank(this.type) ||
553                            types.rank(that.type) == types.rank(this.type) &&
554                            that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
555                    } else if (this.type.tag == TYPEVAR) {
556                        return types.isSubtype(this.type, that.type);
557                    }
558                }
559                return this.type.tag == TYPEVAR;
560            }
561    
562            // For type params; overridden in subclasses.
563            public ElementKind getKind() {
564                return ElementKind.TYPE_PARAMETER;
565            }
566    
567            public java.util.List<Symbol> getEnclosedElements() {
568                List<Symbol> list = List.nil();
569                for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
570                    if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this)
571                        list = list.prepend(e.sym);
572                }
573                return list;
574            }
575    
576            // For type params.
577            // Perhaps not needed if getEnclosingElement can be spec'ed
578            // to do the same thing.
579            // TODO: getGenericElement() might not be needed
580            public Symbol getGenericElement() {
581                return owner;
582            }
583    
584            public <R, P> R accept(ElementVisitor<R, P> v, P p) {
585                assert type.tag == TYPEVAR; // else override will be invoked
586                return v.visitTypeParameter(this, p);
587            }
588    
589            public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
590                return v.visitTypeSymbol(this, p);
591            }
592    
593            public List<Type> getBounds() {
594                TypeVar t = (TypeVar)type;
595                Type bound = t.getUpperBound();
596                if (!bound.isCompound())
597                    return List.of(bound);
598                ClassType ct = (ClassType)bound;
599                if (!ct.tsym.erasure_field.isInterface()) {
600                    return ct.interfaces_field.prepend(ct.supertype_field);
601                } else {
602                    // No superclass was given in bounds.
603                    // In this case, supertype is Object, erasure is first interface.
604                    return ct.interfaces_field;
605                }
606            }
607        }
608    
609        /** A class for package symbols
610         */
611        public static class PackageSymbol extends TypeSymbol
612            implements PackageElement {
613    
614            public Scope members_field;
615            public Name fullname;
616            public ClassSymbol package_info; // see bug 6443073
617    
618            public PackageSymbol(Name name, Type type, Symbol owner) {
619                super(0, name, type, owner);
620                this.kind = PCK;
621                this.members_field = null;
622                this.fullname = formFullName(name, owner);
623            }
624    
625            public PackageSymbol(Name name, Symbol owner) {
626                this(name, null, owner);
627                this.type = new PackageType(this);
628            }
629    
630            public String toString() {
631                return fullname.toString();
632            }
633    
634            public Name getQualifiedName() {
635                return fullname;
636            }
637    
638            public boolean isUnnamed() {
639                return name.isEmpty() && owner != null;
640            }
641    
642            public Scope members() {
643                if (completer != null) complete();
644                return members_field;
645            }
646    
647            public long flags() {
648                if (completer != null) complete();
649                return flags_field;
650            }
651    
652            public List<Attribute.Compound> getAnnotationMirrors() {
653                if (completer != null) complete();
654                assert attributes_field != null;
655                return attributes_field;
656            }
657    
658            /** A package "exists" if a type or package that exists has
659             *  been seen within it.
660             */
661            public boolean exists() {
662                return (flags_field & EXISTS) != 0;
663            }
664    
665            public ElementKind getKind() {
666                return ElementKind.PACKAGE;
667            }
668    
669            public Symbol getEnclosingElement() {
670                return null;
671            }
672    
673            public <R, P> R accept(ElementVisitor<R, P> v, P p) {
674                return v.visitPackage(this, p);
675            }
676    
677            public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
678                return v.visitPackageSymbol(this, p);
679            }
680        }
681    
682        /** A class for class symbols
683         */
684        public static class ClassSymbol extends TypeSymbol implements TypeElement {
685    
686            /** a scope for all class members; variables, methods and inner classes
687             *  type parameters are not part of this scope
688             */
689            public Scope members_field;
690    
691            /** the fully qualified name of the class, i.e. pck.outer.inner.
692             *  null for anonymous classes
693             */
694            public Name fullname;
695    
696            /** the fully qualified name of the class after converting to flat
697             *  representation, i.e. pck.outer$inner,
698             *  set externally for local and anonymous classes
699             */
700            public Name flatname;
701    
702            /** the sourcefile where the class came from
703             */
704            public JavaFileObject sourcefile;
705    
706            /** the classfile from where to load this class
707             *  this will have extension .class or .java
708             */
709            public JavaFileObject classfile;
710    
711            /** the constant pool of the class
712             */
713            public Pool pool;
714    
715            public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
716                super(flags, name, type, owner);
717                this.level = new Level();
718                this.members_field = null;
719                this.fullname = formFullName(name, owner);
720                this.flatname = formFlatName(name, owner);
721                this.sourcefile = null;
722                this.classfile = null;
723                this.pool = null;
724            }
725    
726            public ClassSymbol(long flags, Name name, Symbol owner) {
727                this(
728                    flags,
729                    name,
730                    new ClassType(Type.noType, null, null),
731                    owner);
732                this.type.tsym = this;
733            }
734    
735            /** The Java source which this symbol represents.
736             */
737            public String toString() {
738                return className();
739            }
740    
741            public long flags() {
742                if (completer != null) complete();
743                return flags_field;
744            }
745    
746            public Scope members() {
747                if (completer != null) complete();
748                return members_field;
749            }
750    
751            public List<Attribute.Compound> getAnnotationMirrors() {
752                if (completer != null) complete();
753                assert attributes_field != null;
754                return attributes_field;
755            }
756    
757            public Type erasure(Types types) {
758                if (erasure_field == null)
759                    erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
760                                                  List.<Type>nil(), this);
761                return erasure_field;
762            }
763    
764            public String className() {
765                if (name.isEmpty())
766                    return
767                        Log.getLocalizedString("anonymous.class", flatname);
768                else
769                    return fullname.toString();
770            }
771    
772            public Name getQualifiedName() {
773                return fullname;
774            }
775    
776            public Name flatName() {
777                return flatname;
778            }
779    
780            public boolean isSubClass(Symbol base, Types types) {
781                if (this == base) {
782                    return true;
783                } else if ((base.flags() & INTERFACE) != 0) {
784                    for (Type t = type; t.tag == CLASS; t = types.supertype(t))
785                        for (List<Type> is = types.interfaces(t);
786                             is.nonEmpty();
787                             is = is.tail)
788                            if (is.head.tsym.isSubClass(base, types)) return true;
789                } else {
790                    for (Type t = type; t.tag == CLASS; t = types.supertype(t))
791                        if (t.tsym == base) return true;
792                }
793                return false;
794            }
795    
796            /** Complete the elaboration of this symbol's definition.
797             */
798            public void complete() throws CompletionFailure {
799                try {
800                    super.complete();
801                } catch (CompletionFailure ex) {
802                    // quiet error recovery
803                    flags_field |= (PUBLIC|STATIC);
804                    this.type = new ErrorType(this, Type.noType);
805                    throw ex;
806                }
807            }
808    
809            public List<Type> getInterfaces() {
810                complete();
811                if (type instanceof ClassType) {
812                    ClassType t = (ClassType)type;
813                    if (t.interfaces_field == null) // FIXME: shouldn't be null
814                        t.interfaces_field = List.nil();
815                    return t.interfaces_field;
816                } else {
817                    return List.nil();
818                }
819            }
820    
821            public Type getSuperclass() {
822                complete();
823                if (type instanceof ClassType) {
824                    ClassType t = (ClassType)type;
825                    if (t.supertype_field == null) // FIXME: shouldn't be null
826                        t.supertype_field = Type.noType;
827                    // An interface has no superclass; its supertype is Object.
828                    return t.isInterface()
829                        ? Type.noType
830                        : t.supertype_field;
831                } else {
832                    return Type.noType;
833                }
834            }
835    
836            public ElementKind getKind() {
837                long flags = flags();
838                if ((flags & ANNOTATION) != 0)
839                    return ElementKind.ANNOTATION_TYPE;
840                else if ((flags & INTERFACE) != 0)
841                    return ElementKind.INTERFACE;
842                else if ((flags & ENUM) != 0)
843                    return ElementKind.ENUM;
844                else
845                    return ElementKind.CLASS;
846            }
847    
848            public NestingKind getNestingKind() {
849                complete();
850                if (owner.kind == PCK)
851                    return NestingKind.TOP_LEVEL;
852                else if (name.isEmpty())
853                    return NestingKind.ANONYMOUS;
854                else if (owner.kind == MTH)
855                    return NestingKind.LOCAL;
856                else
857                    return NestingKind.MEMBER;
858            }
859    
860            /**
861             * @deprecated this method should never be used by javac internally.
862             */
863            @Override @Deprecated
864            public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
865                return JavacElements.getAnnotation(this, annoType);
866            }
867    
868            public <R, P> R accept(ElementVisitor<R, P> v, P p) {
869                return v.visitType(this, p);
870            }
871    
872            public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
873                return v.visitClassSymbol(this, p);
874            }
875        }
876    
877    
878        /** A class for variable symbols
879         */
880        public static class VarSymbol extends Symbol implements VariableElement {
881    
882            /** The variable's declaration position.
883             */
884            public int pos = Position.NOPOS;
885    
886            /** The variable's address. Used for different purposes during
887             *  flow analysis, translation and code generation.
888             *  Flow analysis:
889             *    If this is a blank final or local variable, its sequence number.
890             *  Translation:
891             *    If this is a private field, its access number.
892             *  Code generation:
893             *    If this is a local variable, its logical slot number.
894             */
895            public int adr = -1;
896    
897            /** Construct a variable symbol, given its flags, name, type and owner.
898             */
899            public VarSymbol(long flags, Name name, Type type, Symbol owner) {
900                super(VAR, flags, name, type, owner);
901                this.level = new Level();
902            }
903    
904            /** Clone this symbol with new owner.
905             */
906            public VarSymbol clone(Symbol newOwner) {
907                VarSymbol v = new VarSymbol(flags_field, name, type, newOwner);
908                v.pos = pos;
909                v.adr = adr;
910                v.data = data;
911                v.level = level.dup();
912    //          System.out.println("clone " + v + " in " + newOwner);//DEBUG
913                return v;
914            }
915    
916            public String toString() {
917                return name.toString();
918            }
919    
920            public Symbol asMemberOf(Type site, Types types) {
921                return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
922            }
923    
924            public ElementKind getKind() {
925                long flags = flags();
926                if ((flags & PARAMETER) != 0) {
927                    if (isExceptionParameter())
928                        return ElementKind.EXCEPTION_PARAMETER;
929                    else
930                        return ElementKind.PARAMETER;
931                } else if ((flags & ENUM) != 0) {
932                    return ElementKind.ENUM_CONSTANT;
933                } else if (owner.kind == TYP || owner.kind == ERR) {
934                    return ElementKind.FIELD;
935                } else {
936                    return ElementKind.LOCAL_VARIABLE;
937                }
938            }
939    
940            public <R, P> R accept(ElementVisitor<R, P> v, P p) {
941                return v.visitVariable(this, p);
942            }
943    
944            public Object getConstantValue() { // Mirror API
945                return Constants.decode(getConstValue(), type);
946            }
947    
948            public void setLazyConstValue(final Env<AttrContext> env,
949                                          final Log log,
950                                          final Attr attr,
951                                          final JCTree.JCExpression initializer)
952            {
953                setData(new Callable<Object>() {
954                    public Object call() {
955                        JavaFileObject source = log.useSource(env.toplevel.sourcefile);
956                        try {
957                            Type itype = attr.attribExpr(initializer, env, type);
958                            if (itype.constValue() != null)
959                                return attr.coerce(itype, type).constValue();
960                            else
961                                return null;
962                        } finally {
963                            log.useSource(source);
964                        }
965                    }
966                });
967            }
968    
969            /**
970             * The variable's constant value, if this is a constant.
971             * Before the constant value is evaluated, it points to an
972             * initalizer environment.  If this is not a constant, it can
973             * be used for other stuff.
974             */
975            private Object data;
976    
977            public boolean isExceptionParameter() {
978                return data == ElementKind.EXCEPTION_PARAMETER;
979            }
980    
981            public Object getConstValue() {
982                // TODO: Consider if getConstValue and getConstantValue can be collapsed
983                if (data == ElementKind.EXCEPTION_PARAMETER) {
984                    return null;
985                } else if (data instanceof Callable<?>) {
986                    // In this case, this is final a variable, with an as
987                    // yet unevaluated initializer.
988                    Callable<?> eval = (Callable<?>)data;
989                    data = null; // to make sure we don't evaluate this twice.
990                    try {
991                        data = eval.call();
992                    } catch (Exception ex) {
993                        throw new AssertionError(ex);
994                    }
995                }
996                return data;
997            }
998    
999            public void setData(Object data) {
1000                assert !(data instanceof Env<?>) : this;
1001                this.data = data;
1002            }
1003    
1004            public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1005                return v.visitVarSymbol(this, p);
1006            }
1007        }
1008    
1009        /** A class for method symbols.
1010         */
1011        public static class MethodSymbol extends Symbol implements ExecutableElement {
1012    
1013            /** The code of the method. */
1014            public Code code = null;
1015    
1016            /** The parameters of the method. */
1017            public List<VarSymbol> params = null;
1018    
1019            /** The names of the parameters */
1020            public List<Name> savedParameterNames;
1021    
1022            /** For an attribute field accessor, its default value if any.
1023             *  The value is null if none appeared in the method
1024             *  declaration.
1025             */
1026            public Attribute defaultValue = null;
1027            
1028            /** Construct a method symbol, given its flags, name, type and owner.
1029             */
1030            public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1031                super(MTH, flags, name, type, owner);
1032                this.level = new Level();
1033                assert owner.type.tag != TYPEVAR : owner + "." + name;
1034            }
1035    
1036            /** Clone this symbol with new owner.
1037             */
1038            public MethodSymbol clone(Symbol newOwner) {
1039                MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner);
1040                m.code = code;
1041                m.level = level.dup();
1042                return m;
1043            }
1044    
1045            /** The Java source which this symbol represents.
1046             */
1047            public String toString() {
1048                if ((flags() & BLOCK) != 0) {
1049                    return owner.name.toString();
1050                } else {
1051                    String s = (name == name.table.names.init)
1052                        ? owner.name.toString()
1053                        : name.toString();
1054                    if (type != null) {
1055                        if (type.tag == FORALL)
1056                            s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1057                        s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1058                    }
1059                    return s;
1060                }
1061            }
1062    
1063            /** find a symbol that this (proxy method) symbol implements.
1064             *  @param    c       The class whose members are searched for
1065             *                    implementations
1066             */
1067            public Symbol implemented(TypeSymbol c, Types types) {
1068                Symbol impl = null;
1069                for (List<Type> is = types.interfaces(c.type);
1070                     impl == null && is.nonEmpty();
1071                     is = is.tail) {
1072                    TypeSymbol i = is.head.tsym;
1073                    for (Scope.Entry e = i.members().lookup(name);
1074                         impl == null && e.scope != null;
1075                         e = e.next()) {
1076                        if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
1077                            // FIXME: I suspect the following requires a
1078                            // subst() for a parametric return type.
1079                            types.isSameType(type.getReturnType(),
1080                                             types.memberType(owner.type, e.sym).getReturnType())) {
1081                            impl = e.sym;
1082                        }
1083                        if (impl == null)
1084                            impl = implemented(i, types);
1085                    }
1086                }
1087                return impl;
1088            }
1089    
1090            /** Will the erasure of this method be considered by the VM to
1091             *  override the erasure of the other when seen from class `origin'?
1092             */
1093            public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1094                if (isConstructor() || _other.kind != MTH) return false;
1095    
1096                if (this == _other) return true;
1097                MethodSymbol other = (MethodSymbol)_other;
1098    
1099                // check for a direct implementation
1100                if (other.isOverridableIn((TypeSymbol)owner) &&
1101                    types.asSuper(owner.type, other.owner) != null &&
1102                    types.isSameType(erasure(types), other.erasure(types)))
1103                    return true;
1104    
1105                // check for an inherited implementation
1106                return
1107                    (flags() & ABSTRACT) == 0 &&
1108                    other.isOverridableIn(origin) &&
1109                    this.isMemberOf(origin, types) &&
1110                    types.isSameType(erasure(types), other.erasure(types));
1111            }
1112    
1113            /** The implementation of this (abstract) symbol in class origin,
1114             *  from the VM's point of view, null if method does not have an
1115             *  implementation in class.
1116             *  @param origin   The class of which the implementation is a member.
1117             */
1118            public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1119                for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1120                    for (Scope.Entry e = c.members().lookup(name);
1121                         e.scope != null;
1122                         e = e.next()) {
1123                        if (e.sym.kind == MTH &&
1124                            ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
1125                            return (MethodSymbol)e.sym;
1126                    }
1127                }
1128                return null;
1129            }
1130    
1131            /** Does this symbol override `other' symbol, when both are seen as
1132             *  members of class `origin'?  It is assumed that _other is a member
1133             *  of origin.
1134             *
1135             *  It is assumed that both symbols have the same name.  The static
1136             *  modifier is ignored for this test.
1137             *
1138             *  See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1139             */
1140            public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1141                if (isConstructor() || _other.kind != MTH) return false;
1142    
1143                if (this == _other) return true;
1144                MethodSymbol other = (MethodSymbol)_other;
1145    
1146                // check for a direct implementation
1147                if (other.isOverridableIn((TypeSymbol)owner) &&
1148                    types.asSuper(owner.type, other.owner) != null) {
1149                    Type mt = types.memberType(owner.type, this);
1150                    Type ot = types.memberType(owner.type, other);
1151                    if (types.isSubSignature(mt, ot)) {
1152                        if (!checkResult)
1153                            return true;
1154                        if (types.returnTypeSubstitutable(mt, ot))
1155                            return true;
1156                    }
1157                }
1158    
1159                // check for an inherited implementation
1160                if ((flags() & ABSTRACT) != 0 ||
1161                    (other.flags() & ABSTRACT) == 0 ||
1162                    !other.isOverridableIn(origin) ||
1163                    !this.isMemberOf(origin, types))
1164                    return false;
1165    
1166                // assert types.asSuper(origin.type, other.owner) != null;
1167                Type mt = types.memberType(origin.type, this);
1168                Type ot = types.memberType(origin.type, other);
1169                return
1170                    types.isSubSignature(mt, ot) &&
1171                    (!checkResult || types.resultSubtype(mt, ot, Warner.noWarnings));
1172            }
1173    
1174            private boolean isOverridableIn(TypeSymbol origin) {
1175                // JLS3 8.4.6.1
1176                switch ((int)(flags_field & Flags.AccessFlags)) {
1177                case Flags.PRIVATE:
1178                    return false;
1179                case Flags.PUBLIC:
1180                    return true;
1181                case Flags.PROTECTED:
1182                    return (origin.flags() & INTERFACE) == 0;
1183                case 0:
1184                    // for package private: can only override in the same
1185                    // package
1186                    return
1187                        this.packge() == origin.packge() &&
1188                        (origin.flags() & INTERFACE) == 0;
1189                default:
1190                    return false;
1191                }
1192            }
1193    
1194            /** The implementation of this (abstract) symbol in class origin;
1195             *  null if none exists. Synthetic methods are not considered
1196             *  as possible implementations.
1197             */
1198            public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1199                for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) {
1200                    while (t.tag == TYPEVAR)
1201                        t = t.getUpperBound();
1202                    TypeSymbol c = t.tsym;
1203                    for (Scope.Entry e = c.members().lookup(name);
1204                         e.scope != null;
1205                         e = e.next()) {
1206                        if (e.sym.kind == MTH) {
1207                            MethodSymbol m = (MethodSymbol) e.sym;
1208                            if (m.overrides(this, origin, types, checkResult) &&
1209                                (m.flags() & SYNTHETIC) == 0)
1210                                return m;
1211                        }
1212                    }
1213                }
1214                // if origin is derived from a raw type, we might have missed
1215                // an implementation because we do not know enough about instantiations.
1216                // in this case continue with the supertype as origin.
1217                if (types.isDerivedRaw(origin.type))
1218                    return implementation(types.supertype(origin.type).tsym, types, checkResult);
1219                else
1220                    return null;
1221            }
1222    
1223            public List<VarSymbol> params() {
1224                owner.complete();
1225                if (params == null) {
1226                    List<Name> names = savedParameterNames;
1227                    savedParameterNames = null;
1228                    if (names == null) {
1229                        names = List.nil();
1230                        int i = 0;
1231                        for (Type t : type.getParameterTypes())
1232                            names = names.prepend(name.table.fromString("arg" + i++));
1233                        names = names.reverse();
1234                    }
1235                    ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
1236                    for (Type t : type.getParameterTypes()) {
1237                        buf.append(new VarSymbol(PARAMETER, names.head, t, this));
1238                        names = names.tail;
1239                    }
1240                    params = buf.toList();
1241                }
1242                return params;
1243            }
1244    
1245            public Symbol asMemberOf(Type site, Types types) {
1246                return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1247            }
1248    
1249            public ElementKind getKind() {
1250                if (name == name.table.names.init)
1251                    return ElementKind.CONSTRUCTOR;
1252                else if (name == name.table.names.clinit)
1253                    return ElementKind.STATIC_INIT;
1254                else
1255                    return ElementKind.METHOD;
1256            }
1257    
1258            public Attribute getDefaultValue() {
1259                return defaultValue;
1260            }
1261    
1262            public List<VarSymbol> getParameters() {
1263                return params();
1264            }
1265    
1266            public boolean isVarArgs() {
1267                return (flags() & VARARGS) != 0;
1268            }
1269    
1270            public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1271                return v.visitExecutable(this, p);
1272            }
1273    
1274            public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1275                return v.visitMethodSymbol(this, p);
1276            }
1277    
1278            public Type getReturnType() {
1279                return asType().getReturnType();
1280            }
1281    
1282            public List<Type> getThrownTypes() {
1283                return asType().getThrownTypes();
1284            }
1285        }
1286    
1287        /** A class for predefined operators.
1288         */
1289        public static class OperatorSymbol extends MethodSymbol {
1290    
1291            public int opcode;
1292    
1293            public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1294                super(PUBLIC | STATIC, name, type, owner);
1295                this.opcode = opcode;
1296            }
1297    
1298            public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1299                return v.visitOperatorSymbol(this, p);
1300            }
1301        }
1302    
1303        /** Symbol completer interface.
1304         */
1305        public static interface Completer {
1306            void complete(Symbol sym) throws CompletionFailure;
1307        }
1308    
1309        public static class CompletionFailure extends RuntimeException {
1310            private static final long serialVersionUID = 0;
1311            public Symbol sym;
1312    
1313            /** A diagnostic object describing the failure
1314             */
1315            public JCDiagnostic diag;
1316    
1317            /** A localized string describing the failure.
1318             * @deprecated Use {@code getDetail()} or {@code getMessage()}
1319             */
1320            @Deprecated
1321            public String errmsg;
1322    
1323            public CompletionFailure(Symbol sym, String errmsg) {
1324                this.sym = sym;
1325                this.errmsg = errmsg;
1326    //          this.printStackTrace();//DEBUG
1327            }
1328    
1329            public CompletionFailure(Symbol sym, JCDiagnostic diag) {
1330                this.sym = sym;
1331                this.diag = diag;
1332    //          this.printStackTrace();//DEBUG
1333            }
1334    
1335            public JCDiagnostic getDiagnostic() {
1336                return diag;
1337            }
1338    
1339            @Override
1340            public String getMessage() {
1341                if (diag != null)
1342                    return diag.getMessage(null);
1343                else
1344                    return errmsg;
1345            }
1346    
1347            public Object getDetailValue() {
1348                return (diag != null ? diag : errmsg);
1349            }
1350    
1351            @Override
1352            public CompletionFailure initCause(Throwable cause) {
1353                super.initCause(cause);
1354                return this;
1355            }
1356    
1357        }
1358    
1359        /**
1360         * A visitor for symbols.  A visitor is used to implement operations
1361         * (or relations) on symbols.  Most common operations on types are
1362         * binary relations and this interface is designed for binary
1363         * relations, that is, operations on the form
1364         * Symbol&nbsp;&times;&nbsp;P&nbsp;&rarr;&nbsp;R.
1365         * <!-- In plain text: Type x P -> R -->
1366         *
1367         * @param <R> the return type of the operation implemented by this
1368         * visitor; use Void if no return type is needed.
1369         * @param <P> the type of the second argument (the first being the
1370         * symbol itself) of the operation implemented by this visitor; use
1371         * Void if a second argument is not needed.
1372         */
1373        public interface Visitor<R,P> {
1374            R visitClassSymbol(ClassSymbol s, P arg);
1375            R visitMethodSymbol(MethodSymbol s, P arg);
1376            R visitPackageSymbol(PackageSymbol s, P arg);
1377            R visitOperatorSymbol(OperatorSymbol s, P arg);
1378            R visitVarSymbol(VarSymbol s, P arg);
1379            R visitTypeSymbol(TypeSymbol s, P arg);
1380            R visitSymbol(Symbol s, P arg);
1381        }
1382        
1383        // Level that implements a directed union-find that allows cutting links
1384        public static class Level {
1385            public static final int UNSET = -1;
1386            
1387            protected int value = UNSET;
1388            protected List<Level> parents = List.<Level>nil();
1389            
1390            public Level() { }
1391            public Level(int v) { value = v; }
1392            public Level(Level l) { this(); addParent(l); }
1393            
1394            public int getLevel() {
1395                if (findLevel()==UNSET) throw new AssertionError("Unknown level.");
1396                return value;
1397            }
1398            
1399            protected int findLevel() {
1400                if ((value!=UNSET) || (parents.size()==0)) return value;
1401                for(Level parent: parents) {
1402                    int v = parent.findLevel();
1403                    if (v!=UNSET) {
1404                        if ((value!=UNSET) && (v!=value)) throw new AssertionError("Unequal levels.");
1405                        value = v;
1406                    }
1407                }
1408                return value;
1409            }
1410            
1411            public void addParent(Level that) {
1412                parents = parents.append(that);
1413            }
1414            
1415            public void removeParent(Level that) {
1416                if (value!=UNSET) throw new AssertionError("Removing parent from level with set value."); // FIXME: is this right?
1417                ListBuffer<Level> lb = new ListBuffer<Level>();
1418                for(Level parent: parents) {
1419                    if (!parent.equals(that)) lb.append(parent);
1420                }
1421                parents = lb.toList();
1422            }
1423            
1424            public Level dup() {
1425                Level l = new Level(value);
1426                for(Level parent: parents) l.addParent(parent);
1427                return l;
1428            }
1429        }
1430    }