Thu, 09 Oct 2008 16:19:13 +0100
6731573: diagnostic output should optionally include source line
Summary: Added an -XD option to optionally prints out source lines in error messages
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 if (sup.type.isErroneous())
365 return true; // error recovery
366 if ((sup.flags() & COMPOUND) != 0)
367 continue;
368 if (sup.packge() != thisPackage)
369 return false;
370 }
371 return (clazz.flags() & INTERFACE) == 0;
372 }
373 }
375 /** The (variable or method) symbol seen as a member of given
376 * class type`site' (this might change the symbol's type).
377 * This is used exclusively for producing diagnostics.
378 */
379 public Symbol asMemberOf(Type site, Types types) {
380 throw new AssertionError();
381 }
383 /** Does this method symbol override `other' symbol, when both are seen as
384 * members of class `origin'? It is assumed that _other is a member
385 * of origin.
386 *
387 * It is assumed that both symbols have the same name. The static
388 * modifier is ignored for this test.
389 *
390 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
391 */
392 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
393 return false;
394 }
396 /** Complete the elaboration of this symbol's definition.
397 */
398 public void complete() throws CompletionFailure {
399 if (completer != null) {
400 Completer c = completer;
401 completer = null;
402 c.complete(this);
403 }
404 }
406 /** True if the symbol represents an entity that exists.
407 */
408 public boolean exists() {
409 return true;
410 }
412 public Type asType() {
413 return type;
414 }
416 public Symbol getEnclosingElement() {
417 return owner;
418 }
420 public ElementKind getKind() {
421 return ElementKind.OTHER; // most unkind
422 }
424 public Set<Modifier> getModifiers() {
425 return Flags.asModifierSet(flags());
426 }
428 public Name getSimpleName() {
429 return name;
430 }
432 /**
433 * @deprecated this method should never be used by javac internally.
434 */
435 @Deprecated
436 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
437 return JavacElements.getAnnotation(this, annoType);
438 }
440 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
441 public java.util.List<Symbol> getEnclosedElements() {
442 return List.nil();
443 }
445 public List<TypeSymbol> getTypeParameters() {
446 ListBuffer<TypeSymbol> l = ListBuffer.lb();
447 for (Type t : type.getTypeArguments()) {
448 l.append(t.tsym);
449 }
450 return l.toList();
451 }
453 public static class DelegatedSymbol extends Symbol {
454 protected Symbol other;
455 public DelegatedSymbol(Symbol other) {
456 super(other.kind, other.flags_field, other.name, other.type, other.owner);
457 this.other = other;
458 }
459 public String toString() { return other.toString(); }
460 public Symbol location() { return other.location(); }
461 public Symbol location(Type site, Types types) { return other.location(site, types); }
462 public Type erasure(Types types) { return other.erasure(types); }
463 public Type externalType(Types types) { return other.externalType(types); }
464 public boolean isLocal() { return other.isLocal(); }
465 public boolean isConstructor() { return other.isConstructor(); }
466 public Name getQualifiedName() { return other.getQualifiedName(); }
467 public Name flatName() { return other.flatName(); }
468 public Scope members() { return other.members(); }
469 public boolean isInner() { return other.isInner(); }
470 public boolean hasOuterInstance() { return other.hasOuterInstance(); }
471 public ClassSymbol enclClass() { return other.enclClass(); }
472 public ClassSymbol outermostClass() { return other.outermostClass(); }
473 public PackageSymbol packge() { return other.packge(); }
474 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
475 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
476 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
477 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
478 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
479 public void complete() throws CompletionFailure { other.complete(); }
481 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
482 return other.accept(v, p);
483 }
485 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
486 return v.visitSymbol(other, p);
487 }
488 }
490 /** A class for type symbols. Type variables are represented by instances
491 * of this class, classes and packages by instances of subclasses.
492 */
493 public static class TypeSymbol
494 extends Symbol implements TypeParameterElement {
495 // Implements TypeParameterElement because type parameters don't
496 // have their own TypeSymbol subclass.
497 // TODO: type parameters should have their own TypeSymbol subclass
499 public TypeSymbol(long flags, Name name, Type type, Symbol owner) {
500 super(TYP, flags, name, type, owner);
501 }
503 /** form a fully qualified name from a name and an owner
504 */
505 static public Name formFullName(Name name, Symbol owner) {
506 if (owner == null) return name;
507 if (((owner.kind != ERR)) &&
508 ((owner.kind & (VAR | MTH)) != 0
509 || (owner.kind == TYP && owner.type.tag == TYPEVAR)
510 )) return name;
511 Name prefix = owner.getQualifiedName();
512 if (prefix == null || prefix == prefix.table.names.empty)
513 return name;
514 else return prefix.append('.', name);
515 }
517 /** form a fully qualified name from a name and an owner, after
518 * converting to flat representation
519 */
520 static public Name formFlatName(Name name, Symbol owner) {
521 if (owner == null ||
522 (owner.kind & (VAR | MTH)) != 0
523 || (owner.kind == TYP && owner.type.tag == TYPEVAR)
524 ) return name;
525 char sep = owner.kind == TYP ? '$' : '.';
526 Name prefix = owner.flatName();
527 if (prefix == null || prefix == prefix.table.names.empty)
528 return name;
529 else return prefix.append(sep, name);
530 }
532 /**
533 * A total ordering between type symbols that refines the
534 * class inheritance graph.
535 *
536 * Typevariables always precede other kinds of symbols.
537 */
538 public final boolean precedes(TypeSymbol that, Types types) {
539 if (this == that)
540 return false;
541 if (this.type.tag == that.type.tag) {
542 if (this.type.tag == CLASS) {
543 return
544 types.rank(that.type) < types.rank(this.type) ||
545 types.rank(that.type) == types.rank(this.type) &&
546 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
547 } else if (this.type.tag == TYPEVAR) {
548 return types.isSubtype(this.type, that.type);
549 }
550 }
551 return this.type.tag == TYPEVAR;
552 }
554 // For type params; overridden in subclasses.
555 public ElementKind getKind() {
556 return ElementKind.TYPE_PARAMETER;
557 }
559 public java.util.List<Symbol> getEnclosedElements() {
560 List<Symbol> list = List.nil();
561 for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
562 if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this)
563 list = list.prepend(e.sym);
564 }
565 return list;
566 }
568 // For type params.
569 // Perhaps not needed if getEnclosingElement can be spec'ed
570 // to do the same thing.
571 // TODO: getGenericElement() might not be needed
572 public Symbol getGenericElement() {
573 return owner;
574 }
576 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
577 assert type.tag == TYPEVAR; // else override will be invoked
578 return v.visitTypeParameter(this, p);
579 }
581 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
582 return v.visitTypeSymbol(this, p);
583 }
585 public List<Type> getBounds() {
586 TypeVar t = (TypeVar)type;
587 Type bound = t.getUpperBound();
588 if (!bound.isCompound())
589 return List.of(bound);
590 ClassType ct = (ClassType)bound;
591 if (!ct.tsym.erasure_field.isInterface()) {
592 return ct.interfaces_field.prepend(ct.supertype_field);
593 } else {
594 // No superclass was given in bounds.
595 // In this case, supertype is Object, erasure is first interface.
596 return ct.interfaces_field;
597 }
598 }
599 }
601 /** A class for package symbols
602 */
603 public static class PackageSymbol extends TypeSymbol
604 implements PackageElement {
606 public Scope members_field;
607 public Name fullname;
608 public ClassSymbol package_info; // see bug 6443073
610 public PackageSymbol(Name name, Type type, Symbol owner) {
611 super(0, name, type, owner);
612 this.kind = PCK;
613 this.members_field = null;
614 this.fullname = formFullName(name, owner);
615 }
617 public PackageSymbol(Name name, Symbol owner) {
618 this(name, null, owner);
619 this.type = new PackageType(this);
620 }
622 public String toString() {
623 return fullname.toString();
624 }
626 public Name getQualifiedName() {
627 return fullname;
628 }
630 public boolean isUnnamed() {
631 return name.isEmpty() && owner != null;
632 }
634 public Scope members() {
635 if (completer != null) complete();
636 return members_field;
637 }
639 public long flags() {
640 if (completer != null) complete();
641 return flags_field;
642 }
644 public List<Attribute.Compound> getAnnotationMirrors() {
645 if (completer != null) complete();
646 assert attributes_field != null;
647 return attributes_field;
648 }
650 /** A package "exists" if a type or package that exists has
651 * been seen within it.
652 */
653 public boolean exists() {
654 return (flags_field & EXISTS) != 0;
655 }
657 public ElementKind getKind() {
658 return ElementKind.PACKAGE;
659 }
661 public Symbol getEnclosingElement() {
662 return null;
663 }
665 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
666 return v.visitPackage(this, p);
667 }
669 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
670 return v.visitPackageSymbol(this, p);
671 }
672 }
674 /** A class for class symbols
675 */
676 public static class ClassSymbol extends TypeSymbol implements TypeElement {
678 /** a scope for all class members; variables, methods and inner classes
679 * type parameters are not part of this scope
680 */
681 public Scope members_field;
683 /** the fully qualified name of the class, i.e. pck.outer.inner.
684 * null for anonymous classes
685 */
686 public Name fullname;
688 /** the fully qualified name of the class after converting to flat
689 * representation, i.e. pck.outer$inner,
690 * set externally for local and anonymous classes
691 */
692 public Name flatname;
694 /** the sourcefile where the class came from
695 */
696 public JavaFileObject sourcefile;
698 /** the classfile from where to load this class
699 * this will have extension .class or .java
700 */
701 public JavaFileObject classfile;
703 /** the constant pool of the class
704 */
705 public Pool pool;
707 public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
708 super(flags, name, type, owner);
709 this.members_field = null;
710 this.fullname = formFullName(name, owner);
711 this.flatname = formFlatName(name, owner);
712 this.sourcefile = null;
713 this.classfile = null;
714 this.pool = null;
715 }
717 public ClassSymbol(long flags, Name name, Symbol owner) {
718 this(
719 flags,
720 name,
721 new ClassType(Type.noType, null, null),
722 owner);
723 this.type.tsym = this;
724 }
726 /** The Java source which this symbol represents.
727 */
728 public String toString() {
729 return className();
730 }
732 public long flags() {
733 if (completer != null) complete();
734 return flags_field;
735 }
737 public Scope members() {
738 if (completer != null) complete();
739 return members_field;
740 }
742 public List<Attribute.Compound> getAnnotationMirrors() {
743 if (completer != null) complete();
744 assert attributes_field != null;
745 return attributes_field;
746 }
748 public Type erasure(Types types) {
749 if (erasure_field == null)
750 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
751 List.<Type>nil(), this);
752 return erasure_field;
753 }
755 public String className() {
756 if (name.isEmpty())
757 return
758 Log.getLocalizedString("anonymous.class", flatname);
759 else
760 return fullname.toString();
761 }
763 public Name getQualifiedName() {
764 return fullname;
765 }
767 public Name flatName() {
768 return flatname;
769 }
771 public boolean isSubClass(Symbol base, Types types) {
772 if (this == base) {
773 return true;
774 } else if ((base.flags() & INTERFACE) != 0) {
775 for (Type t = type; t.tag == CLASS; t = types.supertype(t))
776 for (List<Type> is = types.interfaces(t);
777 is.nonEmpty();
778 is = is.tail)
779 if (is.head.tsym.isSubClass(base, types)) return true;
780 } else {
781 for (Type t = type; t.tag == CLASS; t = types.supertype(t))
782 if (t.tsym == base) return true;
783 }
784 return false;
785 }
787 /** Complete the elaboration of this symbol's definition.
788 */
789 public void complete() throws CompletionFailure {
790 try {
791 super.complete();
792 } catch (CompletionFailure ex) {
793 // quiet error recovery
794 flags_field |= (PUBLIC|STATIC);
795 this.type = new ErrorType(this, Type.noType);
796 throw ex;
797 }
798 }
800 public List<Type> getInterfaces() {
801 complete();
802 if (type instanceof ClassType) {
803 ClassType t = (ClassType)type;
804 if (t.interfaces_field == null) // FIXME: shouldn't be null
805 t.interfaces_field = List.nil();
806 return t.interfaces_field;
807 } else {
808 return List.nil();
809 }
810 }
812 public Type getSuperclass() {
813 complete();
814 if (type instanceof ClassType) {
815 ClassType t = (ClassType)type;
816 if (t.supertype_field == null) // FIXME: shouldn't be null
817 t.supertype_field = Type.noType;
818 // An interface has no superclass; its supertype is Object.
819 return t.isInterface()
820 ? Type.noType
821 : t.supertype_field;
822 } else {
823 return Type.noType;
824 }
825 }
827 public ElementKind getKind() {
828 long flags = flags();
829 if ((flags & ANNOTATION) != 0)
830 return ElementKind.ANNOTATION_TYPE;
831 else if ((flags & INTERFACE) != 0)
832 return ElementKind.INTERFACE;
833 else if ((flags & ENUM) != 0)
834 return ElementKind.ENUM;
835 else
836 return ElementKind.CLASS;
837 }
839 public NestingKind getNestingKind() {
840 complete();
841 if (owner.kind == PCK)
842 return NestingKind.TOP_LEVEL;
843 else if (name.isEmpty())
844 return NestingKind.ANONYMOUS;
845 else if (owner.kind == MTH)
846 return NestingKind.LOCAL;
847 else
848 return NestingKind.MEMBER;
849 }
851 /**
852 * @deprecated this method should never be used by javac internally.
853 */
854 @Override @Deprecated
855 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
856 return JavacElements.getAnnotation(this, annoType);
857 }
859 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
860 return v.visitType(this, p);
861 }
863 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
864 return v.visitClassSymbol(this, p);
865 }
866 }
869 /** A class for variable symbols
870 */
871 public static class VarSymbol extends Symbol implements VariableElement {
873 /** The variable's declaration position.
874 */
875 public int pos = Position.NOPOS;
877 /** The variable's address. Used for different purposes during
878 * flow analysis, translation and code generation.
879 * Flow analysis:
880 * If this is a blank final or local variable, its sequence number.
881 * Translation:
882 * If this is a private field, its access number.
883 * Code generation:
884 * If this is a local variable, its logical slot number.
885 */
886 public int adr = -1;
888 /** Construct a variable symbol, given its flags, name, type and owner.
889 */
890 public VarSymbol(long flags, Name name, Type type, Symbol owner) {
891 super(VAR, flags, name, type, owner);
892 }
894 /** Clone this symbol with new owner.
895 */
896 public VarSymbol clone(Symbol newOwner) {
897 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner);
898 v.pos = pos;
899 v.adr = adr;
900 v.data = data;
901 // System.out.println("clone " + v + " in " + newOwner);//DEBUG
902 return v;
903 }
905 public String toString() {
906 return name.toString();
907 }
909 public Symbol asMemberOf(Type site, Types types) {
910 return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
911 }
913 public ElementKind getKind() {
914 long flags = flags();
915 if ((flags & PARAMETER) != 0) {
916 if (isExceptionParameter())
917 return ElementKind.EXCEPTION_PARAMETER;
918 else
919 return ElementKind.PARAMETER;
920 } else if ((flags & ENUM) != 0) {
921 return ElementKind.ENUM_CONSTANT;
922 } else if (owner.kind == TYP || owner.kind == ERR) {
923 return ElementKind.FIELD;
924 } else {
925 return ElementKind.LOCAL_VARIABLE;
926 }
927 }
929 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
930 return v.visitVariable(this, p);
931 }
933 public Object getConstantValue() { // Mirror API
934 return Constants.decode(getConstValue(), type);
935 }
937 public void setLazyConstValue(final Env<AttrContext> env,
938 final Log log,
939 final Attr attr,
940 final JCTree.JCExpression initializer)
941 {
942 setData(new Callable<Object>() {
943 public Object call() {
944 JavaFileObject source = log.useSource(env.toplevel.sourcefile);
945 try {
946 Type itype = attr.attribExpr(initializer, env, type);
947 if (itype.constValue() != null)
948 return attr.coerce(itype, type).constValue();
949 else
950 return null;
951 } finally {
952 log.useSource(source);
953 }
954 }
955 });
956 }
958 /**
959 * The variable's constant value, if this is a constant.
960 * Before the constant value is evaluated, it points to an
961 * initalizer environment. If this is not a constant, it can
962 * be used for other stuff.
963 */
964 private Object data;
966 public boolean isExceptionParameter() {
967 return data == ElementKind.EXCEPTION_PARAMETER;
968 }
970 public Object getConstValue() {
971 // TODO: Consider if getConstValue and getConstantValue can be collapsed
972 if (data == ElementKind.EXCEPTION_PARAMETER) {
973 return null;
974 } else if (data instanceof Callable<?>) {
975 // In this case, this is final a variable, with an as
976 // yet unevaluated initializer.
977 Callable<?> eval = (Callable<?>)data;
978 data = null; // to make sure we don't evaluate this twice.
979 try {
980 data = eval.call();
981 } catch (Exception ex) {
982 throw new AssertionError(ex);
983 }
984 }
985 return data;
986 }
988 public void setData(Object data) {
989 assert !(data instanceof Env<?>) : this;
990 this.data = data;
991 }
993 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
994 return v.visitVarSymbol(this, p);
995 }
996 }
998 /** A class for method symbols.
999 */
1000 public static class MethodSymbol extends Symbol implements ExecutableElement {
1002 /** The code of the method. */
1003 public Code code = null;
1005 /** The parameters of the method. */
1006 public List<VarSymbol> params = null;
1008 /** The names of the parameters */
1009 public List<Name> savedParameterNames;
1011 /** For an attribute field accessor, its default value if any.
1012 * The value is null if none appeared in the method
1013 * declaration.
1014 */
1015 public Attribute defaultValue = null;
1017 /** Construct a method symbol, given its flags, name, type and owner.
1018 */
1019 public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1020 super(MTH, flags, name, type, owner);
1021 assert owner.type.tag != TYPEVAR : owner + "." + name;
1022 }
1024 /** Clone this symbol with new owner.
1025 */
1026 public MethodSymbol clone(Symbol newOwner) {
1027 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner);
1028 m.code = code;
1029 return m;
1030 }
1032 /** The Java source which this symbol represents.
1033 */
1034 public String toString() {
1035 if ((flags() & BLOCK) != 0) {
1036 return owner.name.toString();
1037 } else {
1038 String s = (name == name.table.names.init)
1039 ? owner.name.toString()
1040 : name.toString();
1041 if (type != null) {
1042 if (type.tag == FORALL)
1043 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1044 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1045 }
1046 return s;
1047 }
1048 }
1050 /** find a symbol that this (proxy method) symbol implements.
1051 * @param c The class whose members are searched for
1052 * implementations
1053 */
1054 public Symbol implemented(TypeSymbol c, Types types) {
1055 Symbol impl = null;
1056 for (List<Type> is = types.interfaces(c.type);
1057 impl == null && is.nonEmpty();
1058 is = is.tail) {
1059 TypeSymbol i = is.head.tsym;
1060 for (Scope.Entry e = i.members().lookup(name);
1061 impl == null && e.scope != null;
1062 e = e.next()) {
1063 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
1064 // FIXME: I suspect the following requires a
1065 // subst() for a parametric return type.
1066 types.isSameType(type.getReturnType(),
1067 types.memberType(owner.type, e.sym).getReturnType())) {
1068 impl = e.sym;
1069 }
1070 if (impl == null)
1071 impl = implemented(i, types);
1072 }
1073 }
1074 return impl;
1075 }
1077 /** Will the erasure of this method be considered by the VM to
1078 * override the erasure of the other when seen from class `origin'?
1079 */
1080 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1081 if (isConstructor() || _other.kind != MTH) return false;
1083 if (this == _other) return true;
1084 MethodSymbol other = (MethodSymbol)_other;
1086 // check for a direct implementation
1087 if (other.isOverridableIn((TypeSymbol)owner) &&
1088 types.asSuper(owner.type, other.owner) != null &&
1089 types.isSameType(erasure(types), other.erasure(types)))
1090 return true;
1092 // check for an inherited implementation
1093 return
1094 (flags() & ABSTRACT) == 0 &&
1095 other.isOverridableIn(origin) &&
1096 this.isMemberOf(origin, types) &&
1097 types.isSameType(erasure(types), other.erasure(types));
1098 }
1100 /** The implementation of this (abstract) symbol in class origin,
1101 * from the VM's point of view, null if method does not have an
1102 * implementation in class.
1103 * @param origin The class of which the implementation is a member.
1104 */
1105 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1106 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1107 for (Scope.Entry e = c.members().lookup(name);
1108 e.scope != null;
1109 e = e.next()) {
1110 if (e.sym.kind == MTH &&
1111 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
1112 return (MethodSymbol)e.sym;
1113 }
1114 }
1115 return null;
1116 }
1118 /** Does this symbol override `other' symbol, when both are seen as
1119 * members of class `origin'? It is assumed that _other is a member
1120 * of origin.
1121 *
1122 * It is assumed that both symbols have the same name. The static
1123 * modifier is ignored for this test.
1124 *
1125 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1126 */
1127 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1128 if (isConstructor() || _other.kind != MTH) return false;
1130 if (this == _other) return true;
1131 MethodSymbol other = (MethodSymbol)_other;
1133 // check for a direct implementation
1134 if (other.isOverridableIn((TypeSymbol)owner) &&
1135 types.asSuper(owner.type, other.owner) != null) {
1136 Type mt = types.memberType(owner.type, this);
1137 Type ot = types.memberType(owner.type, other);
1138 if (types.isSubSignature(mt, ot)) {
1139 if (!checkResult)
1140 return true;
1141 if (types.returnTypeSubstitutable(mt, ot))
1142 return true;
1143 }
1144 }
1146 // check for an inherited implementation
1147 if ((flags() & ABSTRACT) != 0 ||
1148 (other.flags() & ABSTRACT) == 0 ||
1149 !other.isOverridableIn(origin) ||
1150 !this.isMemberOf(origin, types))
1151 return false;
1153 // assert types.asSuper(origin.type, other.owner) != null;
1154 Type mt = types.memberType(origin.type, this);
1155 Type ot = types.memberType(origin.type, other);
1156 return
1157 types.isSubSignature(mt, ot) &&
1158 (!checkResult || types.resultSubtype(mt, ot, Warner.noWarnings));
1159 }
1161 private boolean isOverridableIn(TypeSymbol origin) {
1162 // JLS3 8.4.6.1
1163 switch ((int)(flags_field & Flags.AccessFlags)) {
1164 case Flags.PRIVATE:
1165 return false;
1166 case Flags.PUBLIC:
1167 return true;
1168 case Flags.PROTECTED:
1169 return (origin.flags() & INTERFACE) == 0;
1170 case 0:
1171 // for package private: can only override in the same
1172 // package
1173 return
1174 this.packge() == origin.packge() &&
1175 (origin.flags() & INTERFACE) == 0;
1176 default:
1177 return false;
1178 }
1179 }
1181 /** The implementation of this (abstract) symbol in class origin;
1182 * null if none exists. Synthetic methods are not considered
1183 * as possible implementations.
1184 */
1185 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1186 for (Type t = origin.type; t.tag == CLASS; t = types.supertype(t)) {
1187 TypeSymbol c = t.tsym;
1188 for (Scope.Entry e = c.members().lookup(name);
1189 e.scope != null;
1190 e = e.next()) {
1191 if (e.sym.kind == MTH) {
1192 MethodSymbol m = (MethodSymbol) e.sym;
1193 if (m.overrides(this, origin, types, checkResult) &&
1194 (m.flags() & SYNTHETIC) == 0)
1195 return m;
1196 }
1197 }
1198 }
1199 // if origin is derived from a raw type, we might have missed
1200 // an implementation because we do not know enough about instantiations.
1201 // in this case continue with the supertype as origin.
1202 if (types.isDerivedRaw(origin.type))
1203 return implementation(types.supertype(origin.type).tsym, types, checkResult);
1204 else
1205 return null;
1206 }
1208 public List<VarSymbol> params() {
1209 owner.complete();
1210 if (params == null) {
1211 List<Name> names = savedParameterNames;
1212 savedParameterNames = null;
1213 if (names == null) {
1214 names = List.nil();
1215 int i = 0;
1216 for (Type t : type.getParameterTypes())
1217 names = names.prepend(name.table.fromString("arg" + i++));
1218 names = names.reverse();
1219 }
1220 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
1221 for (Type t : type.getParameterTypes()) {
1222 buf.append(new VarSymbol(PARAMETER, names.head, t, this));
1223 names = names.tail;
1224 }
1225 params = buf.toList();
1226 }
1227 return params;
1228 }
1230 public Symbol asMemberOf(Type site, Types types) {
1231 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1232 }
1234 public ElementKind getKind() {
1235 if (name == name.table.names.init)
1236 return ElementKind.CONSTRUCTOR;
1237 else if (name == name.table.names.clinit)
1238 return ElementKind.STATIC_INIT;
1239 else
1240 return ElementKind.METHOD;
1241 }
1243 public Attribute getDefaultValue() {
1244 return defaultValue;
1245 }
1247 public List<VarSymbol> getParameters() {
1248 return params();
1249 }
1251 public boolean isVarArgs() {
1252 return (flags() & VARARGS) != 0;
1253 }
1255 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1256 return v.visitExecutable(this, p);
1257 }
1259 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1260 return v.visitMethodSymbol(this, p);
1261 }
1263 public Type getReturnType() {
1264 return asType().getReturnType();
1265 }
1267 public List<Type> getThrownTypes() {
1268 return asType().getThrownTypes();
1269 }
1270 }
1272 /** A class for predefined operators.
1273 */
1274 public static class OperatorSymbol extends MethodSymbol {
1276 public int opcode;
1278 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1279 super(PUBLIC | STATIC, name, type, owner);
1280 this.opcode = opcode;
1281 }
1283 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1284 return v.visitOperatorSymbol(this, p);
1285 }
1286 }
1288 /** Symbol completer interface.
1289 */
1290 public static interface Completer {
1291 void complete(Symbol sym) throws CompletionFailure;
1292 }
1294 public static class CompletionFailure extends RuntimeException {
1295 private static final long serialVersionUID = 0;
1296 public Symbol sym;
1298 /** A diagnostic object describing the failure
1299 */
1300 public JCDiagnostic diag;
1302 /** A localized string describing the failure.
1303 * @deprecated Use {@code getDetail()} or {@code getMessage()}
1304 */
1305 @Deprecated
1306 public String errmsg;
1308 public CompletionFailure(Symbol sym, String errmsg) {
1309 this.sym = sym;
1310 this.errmsg = errmsg;
1311 // this.printStackTrace();//DEBUG
1312 }
1314 public CompletionFailure(Symbol sym, JCDiagnostic diag) {
1315 this.sym = sym;
1316 this.diag = diag;
1317 // this.printStackTrace();//DEBUG
1318 }
1320 public JCDiagnostic getDiagnostic() {
1321 return diag;
1322 }
1324 @Override
1325 public String getMessage() {
1326 if (diag != null)
1327 return diag.getMessage(null);
1328 else
1329 return errmsg;
1330 }
1332 public Object getDetailValue() {
1333 return (diag != null ? diag : errmsg);
1334 }
1336 @Override
1337 public CompletionFailure initCause(Throwable cause) {
1338 super.initCause(cause);
1339 return this;
1340 }
1342 }
1344 /**
1345 * A visitor for symbols. A visitor is used to implement operations
1346 * (or relations) on symbols. Most common operations on types are
1347 * binary relations and this interface is designed for binary
1348 * relations, that is, operations on the form
1349 * Symbol × P → R.
1350 * <!-- In plain text: Type x P -> R -->
1351 *
1352 * @param <R> the return type of the operation implemented by this
1353 * visitor; use Void if no return type is needed.
1354 * @param <P> the type of the second argument (the first being the
1355 * symbol itself) of the operation implemented by this visitor; use
1356 * Void if a second argument is not needed.
1357 */
1358 public interface Visitor<R,P> {
1359 R visitClassSymbol(ClassSymbol s, P arg);
1360 R visitMethodSymbol(MethodSymbol s, P arg);
1361 R visitPackageSymbol(PackageSymbol s, P arg);
1362 R visitOperatorSymbol(OperatorSymbol s, P arg);
1363 R visitVarSymbol(VarSymbol s, P arg);
1364 R visitTypeSymbol(TypeSymbol s, P arg);
1365 R visitSymbol(Symbol s, P arg);
1366 }
1367 }