Wed, 02 Jul 2008 12:56:02 -0700
6719955: Update copyright year
Summary: Update copyright year for files that have been modified in 2008
Reviewed-by: ohair, tbell
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 /** The Java source which this symbol represents.
136 * A description of this symbol; overrides Object.
137 */
138 public String toString() {
139 return name.toString();
140 }
142 /** A Java source description of the location of this symbol; used for
143 * error reporting. Use of this method may result in the loss of the
144 * symbol's description.
145 */
146 public String location() {
147 if (owner.name == null || (owner.name.len == 0 && owner.kind != PCK)) {
148 return "";
149 }
150 return owner.toString();
151 }
153 public String location(Type site, Types types) {
154 if (owner.name == null || owner.name.len == 0) {
155 return location();
156 }
157 if (owner.type.tag == CLASS) {
158 Type ownertype = types.asOuterSuper(site, owner);
159 if (ownertype != null) return ownertype.toString();
160 }
161 return owner.toString();
162 }
164 /** The symbol's erased type.
165 */
166 public Type erasure(Types types) {
167 if (erasure_field == null)
168 erasure_field = types.erasure(type);
169 return erasure_field;
170 }
172 /** The external type of a symbol. This is the symbol's erased type
173 * except for constructors of inner classes which get the enclosing
174 * instance class added as first argument.
175 */
176 public Type externalType(Types types) {
177 Type t = erasure(types);
178 if (name == name.table.init && owner.hasOuterInstance()) {
179 Type outerThisType = types.erasure(owner.type.getEnclosingType());
180 return new MethodType(t.getParameterTypes().prepend(outerThisType),
181 t.getReturnType(),
182 t.getThrownTypes(),
183 t.tsym);
184 } else {
185 return t;
186 }
187 }
189 public boolean isStatic() {
190 return
191 (flags() & STATIC) != 0 ||
192 (owner.flags() & INTERFACE) != 0 && kind != MTH;
193 }
195 public boolean isInterface() {
196 return (flags() & INTERFACE) != 0;
197 }
199 /** Is this symbol declared (directly or indirectly) local
200 * to a method or variable initializer?
201 * Also includes fields of inner classes which are in
202 * turn local to a method or variable initializer.
203 */
204 public boolean isLocal() {
205 return
206 (owner.kind & (VAR | MTH)) != 0 ||
207 (owner.kind == TYP && owner.isLocal());
208 }
210 /** Is this symbol a constructor?
211 */
212 public boolean isConstructor() {
213 return name == name.table.init;
214 }
216 /** The fully qualified name of this symbol.
217 * This is the same as the symbol's name except for class symbols,
218 * which are handled separately.
219 */
220 public Name getQualifiedName() {
221 return name;
222 }
224 /** The fully qualified name of this symbol after converting to flat
225 * representation. This is the same as the symbol's name except for
226 * class symbols, which are handled separately.
227 */
228 public Name flatName() {
229 return getQualifiedName();
230 }
232 /** If this is a class or package, its members, otherwise null.
233 */
234 public Scope members() {
235 return null;
236 }
238 /** A class is an inner class if it it has an enclosing instance class.
239 */
240 public boolean isInner() {
241 return type.getEnclosingType().tag == CLASS;
242 }
244 /** An inner class has an outer instance if it is not an interface
245 * it has an enclosing instance class which might be referenced from the class.
246 * Nested classes can see instance members of their enclosing class.
247 * Their constructors carry an additional this$n parameter, inserted
248 * implicitly by the compiler.
249 *
250 * @see #isInner
251 */
252 public boolean hasOuterInstance() {
253 return
254 type.getEnclosingType().tag == CLASS && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
255 }
257 /** The closest enclosing class of this symbol's declaration.
258 */
259 public ClassSymbol enclClass() {
260 Symbol c = this;
261 while (c != null &&
262 ((c.kind & TYP) == 0 || c.type.tag != CLASS)) {
263 c = c.owner;
264 }
265 return (ClassSymbol)c;
266 }
268 /** The outermost class which indirectly owns this symbol.
269 */
270 public ClassSymbol outermostClass() {
271 Symbol sym = this;
272 Symbol prev = null;
273 while (sym.kind != PCK) {
274 prev = sym;
275 sym = sym.owner;
276 }
277 return (ClassSymbol) prev;
278 }
280 /** The package which indirectly owns this symbol.
281 */
282 public PackageSymbol packge() {
283 Symbol sym = this;
284 while (sym.kind != PCK) {
285 sym = sym.owner;
286 }
287 return (PackageSymbol) sym;
288 }
290 /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
291 */
292 public boolean isSubClass(Symbol base, Types types) {
293 throw new AssertionError("isSubClass " + this);
294 }
296 /** Fully check membership: hierarchy, protection, and hiding.
297 * Does not exclude methods not inherited due to overriding.
298 */
299 public boolean isMemberOf(TypeSymbol clazz, Types types) {
300 return
301 owner == clazz ||
302 clazz.isSubClass(owner, types) &&
303 isInheritedIn(clazz, types) &&
304 !hiddenIn((ClassSymbol)clazz, types);
305 }
307 /** Is this symbol the same as or enclosed by the given class? */
308 public boolean isEnclosedBy(ClassSymbol clazz) {
309 for (Symbol sym = this; sym.kind != PCK; sym = sym.owner)
310 if (sym == clazz) return true;
311 return false;
312 }
314 /** Check for hiding. Note that this doesn't handle multiple
315 * (interface) inheritance. */
316 private boolean hiddenIn(ClassSymbol clazz, Types types) {
317 if (kind == MTH && (flags() & STATIC) == 0) return false;
318 while (true) {
319 if (owner == clazz) return false;
320 Scope.Entry e = clazz.members().lookup(name);
321 while (e.scope != null) {
322 if (e.sym == this) return false;
323 if (e.sym.kind == kind &&
324 (kind != MTH ||
325 (e.sym.flags() & STATIC) != 0 &&
326 types.isSubSignature(e.sym.type, type)))
327 return true;
328 e = e.next();
329 }
330 Type superType = types.supertype(clazz.type);
331 if (superType.tag != TypeTags.CLASS) return false;
332 clazz = (ClassSymbol)superType.tsym;
333 }
334 }
336 /** Is this symbol inherited into a given class?
337 * PRE: If symbol's owner is a interface,
338 * it is already assumed that the interface is a superinterface
339 * of given class.
340 * @param clazz The class for which we want to establish membership.
341 * This must be a subclass of the member's owner.
342 */
343 public boolean isInheritedIn(Symbol clazz, Types types) {
344 switch ((int)(flags_field & Flags.AccessFlags)) {
345 default: // error recovery
346 case PUBLIC:
347 return true;
348 case PRIVATE:
349 return this.owner == clazz;
350 case PROTECTED:
351 // we model interfaces as extending Object
352 return (clazz.flags() & INTERFACE) == 0;
353 case 0:
354 PackageSymbol thisPackage = this.packge();
355 for (Symbol sup = clazz;
356 sup != null && sup != this.owner;
357 sup = types.supertype(sup.type).tsym) {
358 if (sup.type.isErroneous())
359 return true; // error recovery
360 if ((sup.flags() & COMPOUND) != 0)
361 continue;
362 if (sup.packge() != thisPackage)
363 return false;
364 }
365 return (clazz.flags() & INTERFACE) == 0;
366 }
367 }
369 /** The (variable or method) symbol seen as a member of given
370 * class type`site' (this might change the symbol's type).
371 * This is used exclusively for producing diagnostics.
372 */
373 public Symbol asMemberOf(Type site, Types types) {
374 throw new AssertionError();
375 }
377 /** Does this method symbol override `other' symbol, when both are seen as
378 * members of class `origin'? It is assumed that _other is a member
379 * of origin.
380 *
381 * It is assumed that both symbols have the same name. The static
382 * modifier is ignored for this test.
383 *
384 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
385 */
386 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
387 return false;
388 }
390 /** Complete the elaboration of this symbol's definition.
391 */
392 public void complete() throws CompletionFailure {
393 if (completer != null) {
394 Completer c = completer;
395 completer = null;
396 c.complete(this);
397 }
398 }
400 /** True if the symbol represents an entity that exists.
401 */
402 public boolean exists() {
403 return true;
404 }
406 public Type asType() {
407 return type;
408 }
410 public Symbol getEnclosingElement() {
411 return owner;
412 }
414 public ElementKind getKind() {
415 return ElementKind.OTHER; // most unkind
416 }
418 public Set<Modifier> getModifiers() {
419 return Flags.asModifierSet(flags());
420 }
422 public Name getSimpleName() {
423 return name;
424 }
426 /**
427 * @deprecated this method should never be used by javac internally.
428 */
429 @Deprecated
430 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
431 return JavacElements.getAnnotation(this, annoType);
432 }
434 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
435 public java.util.List<Symbol> getEnclosedElements() {
436 return List.nil();
437 }
439 public List<TypeSymbol> getTypeParameters() {
440 ListBuffer<TypeSymbol> l = ListBuffer.lb();
441 for (Type t : type.getTypeArguments()) {
442 l.append(t.tsym);
443 }
444 return l.toList();
445 }
447 public static class DelegatedSymbol extends Symbol {
448 protected Symbol other;
449 public DelegatedSymbol(Symbol other) {
450 super(other.kind, other.flags_field, other.name, other.type, other.owner);
451 this.other = other;
452 }
453 public String toString() { return other.toString(); }
454 public String location() { return other.location(); }
455 public String location(Type site, Types types) { return other.location(site, types); }
456 public Type erasure(Types types) { return other.erasure(types); }
457 public Type externalType(Types types) { return other.externalType(types); }
458 public boolean isLocal() { return other.isLocal(); }
459 public boolean isConstructor() { return other.isConstructor(); }
460 public Name getQualifiedName() { return other.getQualifiedName(); }
461 public Name flatName() { return other.flatName(); }
462 public Scope members() { return other.members(); }
463 public boolean isInner() { return other.isInner(); }
464 public boolean hasOuterInstance() { return other.hasOuterInstance(); }
465 public ClassSymbol enclClass() { return other.enclClass(); }
466 public ClassSymbol outermostClass() { return other.outermostClass(); }
467 public PackageSymbol packge() { return other.packge(); }
468 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
469 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
470 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
471 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
472 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
473 public void complete() throws CompletionFailure { other.complete(); }
475 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
476 return other.accept(v, p);
477 }
478 }
480 /** A class for type symbols. Type variables are represented by instances
481 * of this class, classes and packages by instances of subclasses.
482 */
483 public static class TypeSymbol
484 extends Symbol implements TypeParameterElement {
485 // Implements TypeParameterElement because type parameters don't
486 // have their own TypeSymbol subclass.
487 // TODO: type parameters should have their own TypeSymbol subclass
489 public TypeSymbol(long flags, Name name, Type type, Symbol owner) {
490 super(TYP, flags, name, type, owner);
491 }
493 /** form a fully qualified name from a name and an owner
494 */
495 static public Name formFullName(Name name, Symbol owner) {
496 if (owner == null) return name;
497 if (((owner.kind != ERR)) &&
498 ((owner.kind & (VAR | MTH)) != 0
499 || (owner.kind == TYP && owner.type.tag == TYPEVAR)
500 )) return name;
501 Name prefix = owner.getQualifiedName();
502 if (prefix == null || prefix == prefix.table.empty)
503 return name;
504 else return prefix.append('.', name);
505 }
507 /** form a fully qualified name from a name and an owner, after
508 * converting to flat representation
509 */
510 static public Name formFlatName(Name name, Symbol owner) {
511 if (owner == null ||
512 (owner.kind & (VAR | MTH)) != 0
513 || (owner.kind == TYP && owner.type.tag == TYPEVAR)
514 ) return name;
515 char sep = owner.kind == TYP ? '$' : '.';
516 Name prefix = owner.flatName();
517 if (prefix == null || prefix == prefix.table.empty)
518 return name;
519 else return prefix.append(sep, name);
520 }
522 /**
523 * A total ordering between type symbols that refines the
524 * class inheritance graph.
525 *
526 * Typevariables always precede other kinds of symbols.
527 */
528 public final boolean precedes(TypeSymbol that, Types types) {
529 if (this == that)
530 return false;
531 if (this.type.tag == that.type.tag) {
532 if (this.type.tag == CLASS) {
533 return
534 types.rank(that.type) < types.rank(this.type) ||
535 types.rank(that.type) == types.rank(this.type) &&
536 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
537 } else if (this.type.tag == TYPEVAR) {
538 return types.isSubtype(this.type, that.type);
539 }
540 }
541 return this.type.tag == TYPEVAR;
542 }
544 // For type params; overridden in subclasses.
545 public ElementKind getKind() {
546 return ElementKind.TYPE_PARAMETER;
547 }
549 public java.util.List<Symbol> getEnclosedElements() {
550 List<Symbol> list = List.nil();
551 for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
552 if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this)
553 list = list.prepend(e.sym);
554 }
555 return list;
556 }
558 // For type params.
559 // Perhaps not needed if getEnclosingElement can be spec'ed
560 // to do the same thing.
561 // TODO: getGenericElement() might not be needed
562 public Symbol getGenericElement() {
563 return owner;
564 }
566 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
567 assert type.tag == TYPEVAR; // else override will be invoked
568 return v.visitTypeParameter(this, p);
569 }
571 public List<Type> getBounds() {
572 TypeVar t = (TypeVar)type;
573 Type bound = t.getUpperBound();
574 if (!bound.isCompound())
575 return List.of(bound);
576 ClassType ct = (ClassType)bound;
577 if (!ct.tsym.erasure_field.isInterface()) {
578 return ct.interfaces_field.prepend(ct.supertype_field);
579 } else {
580 // No superclass was given in bounds.
581 // In this case, supertype is Object, erasure is first interface.
582 return ct.interfaces_field;
583 }
584 }
585 }
587 /** A class for package symbols
588 */
589 public static class PackageSymbol extends TypeSymbol
590 implements PackageElement {
592 public Scope members_field;
593 public Name fullname;
594 public ClassSymbol package_info; // see bug 6443073
596 public PackageSymbol(Name name, Type type, Symbol owner) {
597 super(0, name, type, owner);
598 this.kind = PCK;
599 this.members_field = null;
600 this.fullname = formFullName(name, owner);
601 }
603 public PackageSymbol(Name name, Symbol owner) {
604 this(name, null, owner);
605 this.type = new PackageType(this);
606 }
608 public String toString() {
609 return fullname.toString();
610 }
612 public Name getQualifiedName() {
613 return fullname;
614 }
616 public boolean isUnnamed() {
617 return name.isEmpty() && owner != null;
618 }
620 public Scope members() {
621 if (completer != null) complete();
622 return members_field;
623 }
625 public long flags() {
626 if (completer != null) complete();
627 return flags_field;
628 }
630 public List<Attribute.Compound> getAnnotationMirrors() {
631 if (completer != null) complete();
632 assert attributes_field != null;
633 return attributes_field;
634 }
636 /** A package "exists" if a type or package that exists has
637 * been seen within it.
638 */
639 public boolean exists() {
640 return (flags_field & EXISTS) != 0;
641 }
643 public ElementKind getKind() {
644 return ElementKind.PACKAGE;
645 }
647 public Symbol getEnclosingElement() {
648 return null;
649 }
651 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
652 return v.visitPackage(this, p);
653 }
654 }
656 /** A class for class symbols
657 */
658 public static class ClassSymbol extends TypeSymbol implements TypeElement {
660 /** a scope for all class members; variables, methods and inner classes
661 * type parameters are not part of this scope
662 */
663 public Scope members_field;
665 /** the fully qualified name of the class, i.e. pck.outer.inner.
666 * null for anonymous classes
667 */
668 public Name fullname;
670 /** the fully qualified name of the class after converting to flat
671 * representation, i.e. pck.outer$inner,
672 * set externally for local and anonymous classes
673 */
674 public Name flatname;
676 /** the sourcefile where the class came from
677 */
678 public JavaFileObject sourcefile;
680 /** the classfile from where to load this class
681 * this will have extension .class or .java
682 */
683 public JavaFileObject classfile;
685 /** the constant pool of the class
686 */
687 public Pool pool;
689 public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
690 super(flags, name, type, owner);
691 this.members_field = null;
692 this.fullname = formFullName(name, owner);
693 this.flatname = formFlatName(name, owner);
694 this.sourcefile = null;
695 this.classfile = null;
696 this.pool = null;
697 }
699 public ClassSymbol(long flags, Name name, Symbol owner) {
700 this(
701 flags,
702 name,
703 new ClassType(Type.noType, null, null),
704 owner);
705 this.type.tsym = this;
706 }
708 /** The Java source which this symbol represents.
709 */
710 public String toString() {
711 return className();
712 }
714 public long flags() {
715 if (completer != null) complete();
716 return flags_field;
717 }
719 public Scope members() {
720 if (completer != null) complete();
721 return members_field;
722 }
724 public List<Attribute.Compound> getAnnotationMirrors() {
725 if (completer != null) complete();
726 assert attributes_field != null;
727 return attributes_field;
728 }
730 public Type erasure(Types types) {
731 if (erasure_field == null)
732 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
733 List.<Type>nil(), this);
734 return erasure_field;
735 }
737 public String className() {
738 if (name.len == 0)
739 return
740 Log.getLocalizedString("anonymous.class", flatname);
741 else
742 return fullname.toString();
743 }
745 public Name getQualifiedName() {
746 return fullname;
747 }
749 public Name flatName() {
750 return flatname;
751 }
753 public boolean isSubClass(Symbol base, Types types) {
754 if (this == base) {
755 return true;
756 } else if ((base.flags() & INTERFACE) != 0) {
757 for (Type t = type; t.tag == CLASS; t = types.supertype(t))
758 for (List<Type> is = types.interfaces(t);
759 is.nonEmpty();
760 is = is.tail)
761 if (is.head.tsym.isSubClass(base, types)) return true;
762 } else {
763 for (Type t = type; t.tag == CLASS; t = types.supertype(t))
764 if (t.tsym == base) return true;
765 }
766 return false;
767 }
769 /** Complete the elaboration of this symbol's definition.
770 */
771 public void complete() throws CompletionFailure {
772 try {
773 super.complete();
774 } catch (CompletionFailure ex) {
775 // quiet error recovery
776 flags_field |= (PUBLIC|STATIC);
777 this.type = new ErrorType(this);
778 throw ex;
779 }
780 }
782 public List<Type> getInterfaces() {
783 complete();
784 if (type instanceof ClassType) {
785 ClassType t = (ClassType)type;
786 if (t.interfaces_field == null) // FIXME: shouldn't be null
787 t.interfaces_field = List.nil();
788 return t.interfaces_field;
789 } else {
790 return List.nil();
791 }
792 }
794 public Type getSuperclass() {
795 complete();
796 if (type instanceof ClassType) {
797 ClassType t = (ClassType)type;
798 if (t.supertype_field == null) // FIXME: shouldn't be null
799 t.supertype_field = Type.noType;
800 // An interface has no superclass; its supertype is Object.
801 return t.isInterface()
802 ? Type.noType
803 : t.supertype_field;
804 } else {
805 return Type.noType;
806 }
807 }
809 public ElementKind getKind() {
810 long flags = flags();
811 if ((flags & ANNOTATION) != 0)
812 return ElementKind.ANNOTATION_TYPE;
813 else if ((flags & INTERFACE) != 0)
814 return ElementKind.INTERFACE;
815 else if ((flags & ENUM) != 0)
816 return ElementKind.ENUM;
817 else
818 return ElementKind.CLASS;
819 }
821 public NestingKind getNestingKind() {
822 complete();
823 if (owner.kind == PCK)
824 return NestingKind.TOP_LEVEL;
825 else if (name.isEmpty())
826 return NestingKind.ANONYMOUS;
827 else if (owner.kind == MTH)
828 return NestingKind.LOCAL;
829 else
830 return NestingKind.MEMBER;
831 }
833 /**
834 * @deprecated this method should never be used by javac internally.
835 */
836 @Override @Deprecated
837 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
838 return JavacElements.getAnnotation(this, annoType);
839 }
841 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
842 return v.visitType(this, p);
843 }
844 }
847 /** A class for variable symbols
848 */
849 public static class VarSymbol extends Symbol implements VariableElement {
851 /** The variable's declaration position.
852 */
853 public int pos = Position.NOPOS;
855 /** The variable's address. Used for different purposes during
856 * flow analysis, translation and code generation.
857 * Flow analysis:
858 * If this is a blank final or local variable, its sequence number.
859 * Translation:
860 * If this is a private field, its access number.
861 * Code generation:
862 * If this is a local variable, its logical slot number.
863 */
864 public int adr = -1;
866 /** Construct a variable symbol, given its flags, name, type and owner.
867 */
868 public VarSymbol(long flags, Name name, Type type, Symbol owner) {
869 super(VAR, flags, name, type, owner);
870 }
872 /** Clone this symbol with new owner.
873 */
874 public VarSymbol clone(Symbol newOwner) {
875 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner);
876 v.pos = pos;
877 v.adr = adr;
878 v.data = data;
879 // System.out.println("clone " + v + " in " + newOwner);//DEBUG
880 return v;
881 }
883 public String toString() {
884 return name.toString();
885 }
887 public Symbol asMemberOf(Type site, Types types) {
888 return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
889 }
891 public ElementKind getKind() {
892 long flags = flags();
893 if ((flags & PARAMETER) != 0) {
894 if (isExceptionParameter())
895 return ElementKind.EXCEPTION_PARAMETER;
896 else
897 return ElementKind.PARAMETER;
898 } else if ((flags & ENUM) != 0) {
899 return ElementKind.ENUM_CONSTANT;
900 } else if (owner.kind == TYP || owner.kind == ERR) {
901 return ElementKind.FIELD;
902 } else {
903 return ElementKind.LOCAL_VARIABLE;
904 }
905 }
907 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
908 return v.visitVariable(this, p);
909 }
911 public Object getConstantValue() { // Mirror API
912 return Constants.decode(getConstValue(), type);
913 }
915 public void setLazyConstValue(final Env<AttrContext> env,
916 final Log log,
917 final Attr attr,
918 final JCTree.JCExpression initializer)
919 {
920 setData(new Callable<Object>() {
921 public Object call() {
922 JavaFileObject source = log.useSource(env.toplevel.sourcefile);
923 try {
924 // In order to catch self-references, we set
925 // the variable's declaration position to
926 // maximal possible value, effectively marking
927 // the variable as undefined.
928 int pos = VarSymbol.this.pos;
929 VarSymbol.this.pos = Position.MAXPOS;
930 Type itype = attr.attribExpr(initializer, env, type);
931 VarSymbol.this.pos = pos;
932 if (itype.constValue() != null)
933 return attr.coerce(itype, type).constValue();
934 else
935 return null;
936 } finally {
937 log.useSource(source);
938 }
939 }
940 });
941 }
943 /**
944 * The variable's constant value, if this is a constant.
945 * Before the constant value is evaluated, it points to an
946 * initalizer environment. If this is not a constant, it can
947 * be used for other stuff.
948 */
949 private Object data;
951 public boolean isExceptionParameter() {
952 return data == ElementKind.EXCEPTION_PARAMETER;
953 }
955 public Object getConstValue() {
956 // TODO: Consider if getConstValue and getConstantValue can be collapsed
957 if (data == ElementKind.EXCEPTION_PARAMETER) {
958 return null;
959 } else if (data instanceof Callable<?>) {
960 // In this case, this is final a variable, with an as
961 // yet unevaluated initializer.
962 Callable<?> eval = (Callable<?>)data;
963 data = null; // to make sure we don't evaluate this twice.
964 try {
965 data = eval.call();
966 } catch (Exception ex) {
967 throw new AssertionError(ex);
968 }
969 }
970 return data;
971 }
973 public void setData(Object data) {
974 assert !(data instanceof Env<?>) : this;
975 this.data = data;
976 }
977 }
979 /** A class for method symbols.
980 */
981 public static class MethodSymbol extends Symbol implements ExecutableElement {
983 /** The code of the method. */
984 public Code code = null;
986 /** The parameters of the method. */
987 public List<VarSymbol> params = null;
989 /** The names of the parameters */
990 public List<Name> savedParameterNames;
992 /** For an attribute field accessor, its default value if any.
993 * The value is null if none appeared in the method
994 * declaration.
995 */
996 public Attribute defaultValue = null;
998 /** Construct a method symbol, given its flags, name, type and owner.
999 */
1000 public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1001 super(MTH, flags, name, type, owner);
1002 assert owner.type.tag != TYPEVAR : owner + "." + name;
1003 }
1005 /** Clone this symbol with new owner.
1006 */
1007 public MethodSymbol clone(Symbol newOwner) {
1008 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner);
1009 m.code = code;
1010 return m;
1011 }
1013 /** The Java source which this symbol represents.
1014 */
1015 public String toString() {
1016 if ((flags() & BLOCK) != 0) {
1017 return owner.name.toString();
1018 } else {
1019 String s = (name == name.table.init)
1020 ? owner.name.toString()
1021 : name.toString();
1022 if (type != null) {
1023 if (type.tag == FORALL)
1024 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1025 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1026 }
1027 return s;
1028 }
1029 }
1031 /** find a symbol that this (proxy method) symbol implements.
1032 * @param c The class whose members are searched for
1033 * implementations
1034 */
1035 public Symbol implemented(TypeSymbol c, Types types) {
1036 Symbol impl = null;
1037 for (List<Type> is = types.interfaces(c.type);
1038 impl == null && is.nonEmpty();
1039 is = is.tail) {
1040 TypeSymbol i = is.head.tsym;
1041 for (Scope.Entry e = i.members().lookup(name);
1042 impl == null && e.scope != null;
1043 e = e.next()) {
1044 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
1045 // FIXME: I suspect the following requires a
1046 // subst() for a parametric return type.
1047 types.isSameType(type.getReturnType(),
1048 types.memberType(owner.type, e.sym).getReturnType())) {
1049 impl = e.sym;
1050 }
1051 if (impl == null)
1052 impl = implemented(i, types);
1053 }
1054 }
1055 return impl;
1056 }
1058 /** Will the erasure of this method be considered by the VM to
1059 * override the erasure of the other when seen from class `origin'?
1060 */
1061 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1062 if (isConstructor() || _other.kind != MTH) return false;
1064 if (this == _other) return true;
1065 MethodSymbol other = (MethodSymbol)_other;
1067 // check for a direct implementation
1068 if (other.isOverridableIn((TypeSymbol)owner) &&
1069 types.asSuper(owner.type, other.owner) != null &&
1070 types.isSameType(erasure(types), other.erasure(types)))
1071 return true;
1073 // check for an inherited implementation
1074 return
1075 (flags() & ABSTRACT) == 0 &&
1076 other.isOverridableIn(origin) &&
1077 this.isMemberOf(origin, types) &&
1078 types.isSameType(erasure(types), other.erasure(types));
1079 }
1081 /** The implementation of this (abstract) symbol in class origin,
1082 * from the VM's point of view, null if method does not have an
1083 * implementation in class.
1084 * @param origin The class of which the implementation is a member.
1085 */
1086 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1087 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1088 for (Scope.Entry e = c.members().lookup(name);
1089 e.scope != null;
1090 e = e.next()) {
1091 if (e.sym.kind == MTH &&
1092 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
1093 return (MethodSymbol)e.sym;
1094 }
1095 }
1096 return null;
1097 }
1099 /** Does this symbol override `other' symbol, when both are seen as
1100 * members of class `origin'? It is assumed that _other is a member
1101 * of origin.
1102 *
1103 * It is assumed that both symbols have the same name. The static
1104 * modifier is ignored for this test.
1105 *
1106 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1107 */
1108 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1109 if (isConstructor() || _other.kind != MTH) return false;
1111 if (this == _other) return true;
1112 MethodSymbol other = (MethodSymbol)_other;
1114 // check for a direct implementation
1115 if (other.isOverridableIn((TypeSymbol)owner) &&
1116 types.asSuper(owner.type, other.owner) != null) {
1117 Type mt = types.memberType(owner.type, this);
1118 Type ot = types.memberType(owner.type, other);
1119 if (types.isSubSignature(mt, ot)) {
1120 if (!checkResult)
1121 return true;
1122 if (types.returnTypeSubstitutable(mt, ot))
1123 return true;
1124 }
1125 }
1127 // check for an inherited implementation
1128 if ((flags() & ABSTRACT) != 0 ||
1129 (other.flags() & ABSTRACT) == 0 ||
1130 !other.isOverridableIn(origin) ||
1131 !this.isMemberOf(origin, types))
1132 return false;
1134 // assert types.asSuper(origin.type, other.owner) != null;
1135 Type mt = types.memberType(origin.type, this);
1136 Type ot = types.memberType(origin.type, other);
1137 return
1138 types.isSubSignature(mt, ot) &&
1139 (!checkResult || types.resultSubtype(mt, ot, Warner.noWarnings));
1140 }
1142 private boolean isOverridableIn(TypeSymbol origin) {
1143 // JLS3 8.4.6.1
1144 switch ((int)(flags_field & Flags.AccessFlags)) {
1145 case Flags.PRIVATE:
1146 return false;
1147 case Flags.PUBLIC:
1148 return true;
1149 case Flags.PROTECTED:
1150 return (origin.flags() & INTERFACE) == 0;
1151 case 0:
1152 // for package private: can only override in the same
1153 // package
1154 return
1155 this.packge() == origin.packge() &&
1156 (origin.flags() & INTERFACE) == 0;
1157 default:
1158 return false;
1159 }
1160 }
1162 /** The implementation of this (abstract) symbol in class origin;
1163 * null if none exists. Synthetic methods are not considered
1164 * as possible implementations.
1165 */
1166 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1167 for (Type t = origin.type; t.tag == CLASS; t = types.supertype(t)) {
1168 TypeSymbol c = t.tsym;
1169 for (Scope.Entry e = c.members().lookup(name);
1170 e.scope != null;
1171 e = e.next()) {
1172 if (e.sym.kind == MTH) {
1173 MethodSymbol m = (MethodSymbol) e.sym;
1174 if (m.overrides(this, origin, types, checkResult) &&
1175 (m.flags() & SYNTHETIC) == 0)
1176 return m;
1177 }
1178 }
1179 }
1180 // if origin is derived from a raw type, we might have missed
1181 // an implementation because we do not know enough about instantiations.
1182 // in this case continue with the supertype as origin.
1183 if (types.isDerivedRaw(origin.type))
1184 return implementation(types.supertype(origin.type).tsym, types, checkResult);
1185 else
1186 return null;
1187 }
1189 public List<VarSymbol> params() {
1190 owner.complete();
1191 if (params == null) {
1192 List<Name> names = savedParameterNames;
1193 savedParameterNames = null;
1194 if (names == null) {
1195 names = List.nil();
1196 int i = 0;
1197 for (Type t : type.getParameterTypes())
1198 names = names.prepend(name.table.fromString("arg" + i++));
1199 names = names.reverse();
1200 }
1201 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
1202 for (Type t : type.getParameterTypes()) {
1203 buf.append(new VarSymbol(PARAMETER, names.head, t, this));
1204 names = names.tail;
1205 }
1206 params = buf.toList();
1207 }
1208 return params;
1209 }
1211 public Symbol asMemberOf(Type site, Types types) {
1212 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1213 }
1215 public ElementKind getKind() {
1216 if (name == name.table.init)
1217 return ElementKind.CONSTRUCTOR;
1218 else if (name == name.table.clinit)
1219 return ElementKind.STATIC_INIT;
1220 else
1221 return ElementKind.METHOD;
1222 }
1224 public Attribute getDefaultValue() {
1225 return defaultValue;
1226 }
1228 public List<VarSymbol> getParameters() {
1229 return params();
1230 }
1232 public boolean isVarArgs() {
1233 return (flags() & VARARGS) != 0;
1234 }
1236 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1237 return v.visitExecutable(this, p);
1238 }
1240 public Type getReturnType() {
1241 return asType().getReturnType();
1242 }
1244 public List<Type> getThrownTypes() {
1245 return asType().getThrownTypes();
1246 }
1247 }
1249 /** A class for predefined operators.
1250 */
1251 public static class OperatorSymbol extends MethodSymbol {
1253 public int opcode;
1255 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1256 super(PUBLIC | STATIC, name, type, owner);
1257 this.opcode = opcode;
1258 }
1259 }
1261 /** Symbol completer interface.
1262 */
1263 public static interface Completer {
1264 void complete(Symbol sym) throws CompletionFailure;
1265 }
1267 public static class CompletionFailure extends RuntimeException {
1268 private static final long serialVersionUID = 0;
1269 public Symbol sym;
1271 /** A diagnostic object describing the failure
1272 */
1273 public JCDiagnostic diag;
1275 /** A localized string describing the failure.
1276 * @deprecated Use {@code getDetail()} or {@code getMessage()}
1277 */
1278 @Deprecated
1279 public String errmsg;
1281 public CompletionFailure(Symbol sym, String errmsg) {
1282 this.sym = sym;
1283 this.errmsg = errmsg;
1284 // this.printStackTrace();//DEBUG
1285 }
1287 public CompletionFailure(Symbol sym, JCDiagnostic diag) {
1288 this.sym = sym;
1289 this.diag = diag;
1290 // this.printStackTrace();//DEBUG
1291 }
1293 public JCDiagnostic getDiagnostic() {
1294 return diag;
1295 }
1297 @Override
1298 public String getMessage() {
1299 if (diag != null)
1300 return diag.getMessage(null);
1301 else
1302 return errmsg;
1303 }
1305 public Object getDetailValue() {
1306 return (diag != null ? diag : errmsg);
1307 }
1309 @Override
1310 public CompletionFailure initCause(Throwable cause) {
1311 super.initCause(cause);
1312 return this;
1313 }
1315 }
1316 }