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