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 × P → 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 }