Tue, 09 Oct 2012 19:10:00 -0700
8000663: clean up langtools imports
Reviewed-by: darcy
1 /*
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.code;
28 import java.util.Set;
29 import java.util.concurrent.Callable;
31 import javax.lang.model.element.*;
32 import javax.tools.JavaFileObject;
34 import com.sun.tools.javac.code.Type.*;
35 import com.sun.tools.javac.comp.Attr;
36 import com.sun.tools.javac.comp.AttrContext;
37 import com.sun.tools.javac.comp.Env;
38 import com.sun.tools.javac.jvm.*;
39 import com.sun.tools.javac.model.*;
40 import com.sun.tools.javac.tree.JCTree;
41 import com.sun.tools.javac.util.*;
42 import com.sun.tools.javac.util.Name;
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 supported API.
53 * If 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 are contained in this
76 * Annotations. The Annotations instance is NOT immutable.
77 */
78 public final Annotations annotations = new Annotations(this);
80 /** An accessor method for the attributes of this symbol.
81 * Attributes of class symbols should be accessed through the accessor
82 * method to make sure that the class symbol is loaded.
83 */
84 public List<Attribute.Compound> getAnnotationMirrors() {
85 return Assert.checkNonNull(annotations.getAttributes());
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 }
93 return null;
94 }
96 /** The name of this symbol in Utf8 representation.
97 */
98 public Name name;
100 /** The type of this symbol.
101 */
102 public Type type;
104 /** The owner of this symbol.
105 */
106 public Symbol owner;
108 /** The completer of this symbol.
109 */
110 public Completer completer;
112 /** A cache for the type erasure of this symbol.
113 */
114 public Type erasure_field;
116 /** Construct a symbol with given kind, flags, name, type and owner.
117 */
118 public Symbol(int kind, long flags, Name name, Type type, Symbol owner) {
119 this.kind = kind;
120 this.flags_field = flags;
121 this.type = type;
122 this.owner = owner;
123 this.completer = null;
124 this.erasure_field = null;
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() &&
154 (owner.flags() & BLOCK) == 0 && owner.kind != PCK && owner.kind != TYP)) {
155 return null;
156 }
157 return owner;
158 }
160 public Symbol location(Type site, Types types) {
161 if (owner.name == null || owner.name.isEmpty()) {
162 return location();
163 }
164 if (owner.type.tag == CLASS) {
165 Type ownertype = types.asOuterSuper(site, owner);
166 if (ownertype != null) return ownertype.tsym;
167 }
168 return owner;
169 }
171 public Symbol baseSymbol() {
172 return this;
173 }
175 /** The symbol's erased type.
176 */
177 public Type erasure(Types types) {
178 if (erasure_field == null)
179 erasure_field = types.erasure(type);
180 return erasure_field;
181 }
183 /** The external type of a symbol. This is the symbol's erased type
184 * except for constructors of inner classes which get the enclosing
185 * instance class added as first argument.
186 */
187 public Type externalType(Types types) {
188 Type t = erasure(types);
189 if (name == name.table.names.init && owner.hasOuterInstance()) {
190 Type outerThisType = types.erasure(owner.type.getEnclosingType());
191 return new MethodType(t.getParameterTypes().prepend(outerThisType),
192 t.getReturnType(),
193 t.getThrownTypes(),
194 t.tsym);
195 } else {
196 return t;
197 }
198 }
200 public boolean isStatic() {
201 return
202 (flags() & STATIC) != 0 ||
203 (owner.flags() & INTERFACE) != 0 && kind != MTH;
204 }
206 public boolean isInterface() {
207 return (flags() & INTERFACE) != 0;
208 }
210 /** Is this symbol declared (directly or indirectly) local
211 * to a method or variable initializer?
212 * Also includes fields of inner classes which are in
213 * turn local to a method or variable initializer.
214 */
215 public boolean isLocal() {
216 return
217 (owner.kind & (VAR | MTH)) != 0 ||
218 (owner.kind == TYP && owner.isLocal());
219 }
221 /** Has this symbol an empty name? This includes anonymous
222 * inner classses.
223 */
224 public boolean isAnonymous() {
225 return name.isEmpty();
226 }
228 /** Is this symbol a constructor?
229 */
230 public boolean isConstructor() {
231 return name == name.table.names.init;
232 }
234 /** The fully qualified name of this symbol.
235 * This is the same as the symbol's name except for class symbols,
236 * which are handled separately.
237 */
238 public Name getQualifiedName() {
239 return name;
240 }
242 /** The fully qualified name of this symbol after converting to flat
243 * representation. This is the same as the symbol's name except for
244 * class symbols, which are handled separately.
245 */
246 public Name flatName() {
247 return getQualifiedName();
248 }
250 /** If this is a class or package, its members, otherwise null.
251 */
252 public Scope members() {
253 return null;
254 }
256 /** A class is an inner class if it it has an enclosing instance class.
257 */
258 public boolean isInner() {
259 return type.getEnclosingType().tag == CLASS;
260 }
262 /** An inner class has an outer instance if it is not an interface
263 * it has an enclosing instance class which might be referenced from the class.
264 * Nested classes can see instance members of their enclosing class.
265 * Their constructors carry an additional this$n parameter, inserted
266 * implicitly by the compiler.
267 *
268 * @see #isInner
269 */
270 public boolean hasOuterInstance() {
271 return
272 type.getEnclosingType().tag == CLASS && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
273 }
275 /** The closest enclosing class of this symbol's declaration.
276 */
277 public ClassSymbol enclClass() {
278 Symbol c = this;
279 while (c != null &&
280 ((c.kind & TYP) == 0 || c.type.tag != CLASS)) {
281 c = c.owner;
282 }
283 return (ClassSymbol)c;
284 }
286 /** The outermost class which indirectly owns this symbol.
287 */
288 public ClassSymbol outermostClass() {
289 Symbol sym = this;
290 Symbol prev = null;
291 while (sym.kind != PCK) {
292 prev = sym;
293 sym = sym.owner;
294 }
295 return (ClassSymbol) prev;
296 }
298 /** The package which indirectly owns this symbol.
299 */
300 public PackageSymbol packge() {
301 Symbol sym = this;
302 while (sym.kind != PCK) {
303 sym = sym.owner;
304 }
305 return (PackageSymbol) sym;
306 }
308 /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
309 */
310 public boolean isSubClass(Symbol base, Types types) {
311 throw new AssertionError("isSubClass " + this);
312 }
314 /** Fully check membership: hierarchy, protection, and hiding.
315 * Does not exclude methods not inherited due to overriding.
316 */
317 public boolean isMemberOf(TypeSymbol clazz, Types types) {
318 return
319 owner == clazz ||
320 clazz.isSubClass(owner, types) &&
321 isInheritedIn(clazz, types) &&
322 !hiddenIn((ClassSymbol)clazz, types);
323 }
325 /** Is this symbol the same as or enclosed by the given class? */
326 public boolean isEnclosedBy(ClassSymbol clazz) {
327 for (Symbol sym = this; sym.kind != PCK; sym = sym.owner)
328 if (sym == clazz) return true;
329 return false;
330 }
332 /** Check for hiding. Note that this doesn't handle multiple
333 * (interface) inheritance. */
334 private boolean hiddenIn(ClassSymbol clazz, Types types) {
335 if (kind == MTH && (flags() & STATIC) == 0) return false;
336 while (true) {
337 if (owner == clazz) return false;
338 Scope.Entry e = clazz.members().lookup(name);
339 while (e.scope != null) {
340 if (e.sym == this) return false;
341 if (e.sym.kind == kind &&
342 (kind != MTH ||
343 (e.sym.flags() & STATIC) != 0 &&
344 types.isSubSignature(e.sym.type, type)))
345 return true;
346 e = e.next();
347 }
348 Type superType = types.supertype(clazz.type);
349 if (superType.tag != TypeTags.CLASS) return false;
350 clazz = (ClassSymbol)superType.tsym;
351 }
352 }
354 /** Is this symbol inherited into a given class?
355 * PRE: If symbol's owner is a interface,
356 * it is already assumed that the interface is a superinterface
357 * of given class.
358 * @param clazz The class for which we want to establish membership.
359 * This must be a subclass of the member's owner.
360 */
361 public boolean isInheritedIn(Symbol clazz, Types types) {
362 switch ((int)(flags_field & Flags.AccessFlags)) {
363 default: // error recovery
364 case PUBLIC:
365 return true;
366 case PRIVATE:
367 return this.owner == clazz;
368 case PROTECTED:
369 // we model interfaces as extending Object
370 return (clazz.flags() & INTERFACE) == 0;
371 case 0:
372 PackageSymbol thisPackage = this.packge();
373 for (Symbol sup = clazz;
374 sup != null && sup != this.owner;
375 sup = types.supertype(sup.type).tsym) {
376 while (sup.type.tag == TYPEVAR)
377 sup = sup.type.getUpperBound().tsym;
378 if (sup.type.isErroneous())
379 return true; // error recovery
380 if ((sup.flags() & COMPOUND) != 0)
381 continue;
382 if (sup.packge() != thisPackage)
383 return false;
384 }
385 return (clazz.flags() & INTERFACE) == 0;
386 }
387 }
389 /** The (variable or method) symbol seen as a member of given
390 * class type`site' (this might change the symbol's type).
391 * This is used exclusively for producing diagnostics.
392 */
393 public Symbol asMemberOf(Type site, Types types) {
394 throw new AssertionError();
395 }
397 /** Does this method symbol override `other' symbol, when both are seen as
398 * members of class `origin'? It is assumed that _other is a member
399 * of origin.
400 *
401 * It is assumed that both symbols have the same name. The static
402 * modifier is ignored for this test.
403 *
404 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
405 */
406 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
407 return false;
408 }
410 /** Complete the elaboration of this symbol's definition.
411 */
412 public void complete() throws CompletionFailure {
413 if (completer != null) {
414 Completer c = completer;
415 completer = null;
416 c.complete(this);
417 }
418 }
420 /** True if the symbol represents an entity that exists.
421 */
422 public boolean exists() {
423 return true;
424 }
426 public Type asType() {
427 return type;
428 }
430 public Symbol getEnclosingElement() {
431 return owner;
432 }
434 public ElementKind getKind() {
435 return ElementKind.OTHER; // most unkind
436 }
438 public Set<Modifier> getModifiers() {
439 return Flags.asModifierSet(flags());
440 }
442 public Name getSimpleName() {
443 return name;
444 }
446 /**
447 * @deprecated this method should never be used by javac internally.
448 */
449 @Deprecated
450 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
451 return JavacElements.getAnnotation(this, annoType);
452 }
454 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
455 public java.util.List<Symbol> getEnclosedElements() {
456 return List.nil();
457 }
459 public List<TypeSymbol> getTypeParameters() {
460 ListBuffer<TypeSymbol> l = ListBuffer.lb();
461 for (Type t : type.getTypeArguments()) {
462 l.append(t.tsym);
463 }
464 return l.toList();
465 }
467 public static class DelegatedSymbol extends Symbol {
468 protected Symbol other;
469 public DelegatedSymbol(Symbol other) {
470 super(other.kind, other.flags_field, other.name, other.type, other.owner);
471 this.other = other;
472 }
473 public String toString() { return other.toString(); }
474 public Symbol location() { return other.location(); }
475 public Symbol location(Type site, Types types) { return other.location(site, types); }
476 public Type erasure(Types types) { return other.erasure(types); }
477 public Type externalType(Types types) { return other.externalType(types); }
478 public boolean isLocal() { return other.isLocal(); }
479 public boolean isConstructor() { return other.isConstructor(); }
480 public Name getQualifiedName() { return other.getQualifiedName(); }
481 public Name flatName() { return other.flatName(); }
482 public Scope members() { return other.members(); }
483 public boolean isInner() { return other.isInner(); }
484 public boolean hasOuterInstance() { return other.hasOuterInstance(); }
485 public ClassSymbol enclClass() { return other.enclClass(); }
486 public ClassSymbol outermostClass() { return other.outermostClass(); }
487 public PackageSymbol packge() { return other.packge(); }
488 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
489 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
490 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
491 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
492 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
493 public void complete() throws CompletionFailure { other.complete(); }
495 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
496 return other.accept(v, p);
497 }
499 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
500 return v.visitSymbol(other, p);
501 }
502 }
504 /** A class for type symbols. Type variables are represented by instances
505 * of this class, classes and packages by instances of subclasses.
506 */
507 public static class TypeSymbol
508 extends Symbol implements TypeParameterElement {
509 // Implements TypeParameterElement because type parameters don't
510 // have their own TypeSymbol subclass.
511 // TODO: type parameters should have their own TypeSymbol subclass
513 public TypeSymbol(long flags, Name name, Type type, Symbol owner) {
514 super(TYP, flags, name, type, owner);
515 }
517 /** form a fully qualified name from a name and an owner
518 */
519 static public Name formFullName(Name name, Symbol owner) {
520 if (owner == null) return name;
521 if (((owner.kind != ERR)) &&
522 ((owner.kind & (VAR | MTH)) != 0
523 || (owner.kind == TYP && owner.type.tag == TYPEVAR)
524 )) return name;
525 Name prefix = owner.getQualifiedName();
526 if (prefix == null || prefix == prefix.table.names.empty)
527 return name;
528 else return prefix.append('.', name);
529 }
531 /** form a fully qualified name from a name and an owner, after
532 * converting to flat representation
533 */
534 static public Name formFlatName(Name name, Symbol owner) {
535 if (owner == null ||
536 (owner.kind & (VAR | MTH)) != 0
537 || (owner.kind == TYP && owner.type.tag == TYPEVAR)
538 ) return name;
539 char sep = owner.kind == TYP ? '$' : '.';
540 Name prefix = owner.flatName();
541 if (prefix == null || prefix == prefix.table.names.empty)
542 return name;
543 else return prefix.append(sep, name);
544 }
546 /**
547 * A total ordering between type symbols that refines the
548 * class inheritance graph.
549 *
550 * Typevariables always precede other kinds of symbols.
551 */
552 public final boolean precedes(TypeSymbol that, Types types) {
553 if (this == that)
554 return false;
555 if (this.type.tag == that.type.tag) {
556 if (this.type.tag == CLASS) {
557 return
558 types.rank(that.type) < types.rank(this.type) ||
559 types.rank(that.type) == types.rank(this.type) &&
560 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
561 } else if (this.type.tag == TYPEVAR) {
562 return types.isSubtype(this.type, that.type);
563 }
564 }
565 return this.type.tag == TYPEVAR;
566 }
568 // For type params; overridden in subclasses.
569 public ElementKind getKind() {
570 return ElementKind.TYPE_PARAMETER;
571 }
573 public java.util.List<Symbol> getEnclosedElements() {
574 List<Symbol> list = List.nil();
575 if (kind == TYP && type.tag == TYPEVAR) {
576 return list;
577 }
578 for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
579 if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this)
580 list = list.prepend(e.sym);
581 }
582 return list;
583 }
585 // For type params.
586 // Perhaps not needed if getEnclosingElement can be spec'ed
587 // to do the same thing.
588 // TODO: getGenericElement() might not be needed
589 public Symbol getGenericElement() {
590 return owner;
591 }
593 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
594 Assert.check(type.tag == TYPEVAR); // else override will be invoked
595 return v.visitTypeParameter(this, p);
596 }
598 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
599 return v.visitTypeSymbol(this, p);
600 }
602 public List<Type> getBounds() {
603 TypeVar t = (TypeVar)type;
604 Type bound = t.getUpperBound();
605 if (!bound.isCompound())
606 return List.of(bound);
607 ClassType ct = (ClassType)bound;
608 if (!ct.tsym.erasure_field.isInterface()) {
609 return ct.interfaces_field.prepend(ct.supertype_field);
610 } else {
611 // No superclass was given in bounds.
612 // In this case, supertype is Object, erasure is first interface.
613 return ct.interfaces_field;
614 }
615 }
616 }
618 /** A class for package symbols
619 */
620 public static class PackageSymbol extends TypeSymbol
621 implements PackageElement {
623 public Scope members_field;
624 public Name fullname;
625 public ClassSymbol package_info; // see bug 6443073
627 public PackageSymbol(Name name, Type type, Symbol owner) {
628 super(0, name, type, owner);
629 this.kind = PCK;
630 this.members_field = null;
631 this.fullname = formFullName(name, owner);
632 }
634 public PackageSymbol(Name name, Symbol owner) {
635 this(name, null, owner);
636 this.type = new PackageType(this);
637 }
639 public String toString() {
640 return fullname.toString();
641 }
643 public Name getQualifiedName() {
644 return fullname;
645 }
647 public boolean isUnnamed() {
648 return name.isEmpty() && owner != null;
649 }
651 public Scope members() {
652 if (completer != null) complete();
653 return members_field;
654 }
656 public long flags() {
657 if (completer != null) complete();
658 return flags_field;
659 }
661 public List<Attribute.Compound> getAnnotationMirrors() {
662 if (completer != null) complete();
663 if (package_info != null && package_info.completer != null) {
664 package_info.complete();
665 if (annotations.isEmpty()) {
666 annotations.setAttributes(package_info.annotations);
667 }
668 }
669 return Assert.checkNonNull(annotations.getAttributes());
670 }
672 /** A package "exists" if a type or package that exists has
673 * been seen within it.
674 */
675 public boolean exists() {
676 return (flags_field & EXISTS) != 0;
677 }
679 public ElementKind getKind() {
680 return ElementKind.PACKAGE;
681 }
683 public Symbol getEnclosingElement() {
684 return null;
685 }
687 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
688 return v.visitPackage(this, p);
689 }
691 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
692 return v.visitPackageSymbol(this, p);
693 }
694 }
696 /** A class for class symbols
697 */
698 public static class ClassSymbol extends TypeSymbol implements TypeElement {
700 /** a scope for all class members; variables, methods and inner classes
701 * type parameters are not part of this scope
702 */
703 public Scope members_field;
705 /** the fully qualified name of the class, i.e. pck.outer.inner.
706 * null for anonymous classes
707 */
708 public Name fullname;
710 /** the fully qualified name of the class after converting to flat
711 * representation, i.e. pck.outer$inner,
712 * set externally for local and anonymous classes
713 */
714 public Name flatname;
716 /** the sourcefile where the class came from
717 */
718 public JavaFileObject sourcefile;
720 /** the classfile from where to load this class
721 * this will have extension .class or .java
722 */
723 public JavaFileObject classfile;
725 /** the list of translated local classes (used for generating
726 * InnerClasses attribute)
727 */
728 public List<ClassSymbol> trans_local;
730 /** the constant pool of the class
731 */
732 public Pool pool;
734 public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
735 super(flags, name, type, owner);
736 this.members_field = null;
737 this.fullname = formFullName(name, owner);
738 this.flatname = formFlatName(name, owner);
739 this.sourcefile = null;
740 this.classfile = null;
741 this.pool = null;
742 }
744 public ClassSymbol(long flags, Name name, Symbol owner) {
745 this(
746 flags,
747 name,
748 new ClassType(Type.noType, null, null),
749 owner);
750 this.type.tsym = this;
751 }
753 /** The Java source which this symbol represents.
754 */
755 public String toString() {
756 return className();
757 }
759 public long flags() {
760 if (completer != null) complete();
761 return flags_field;
762 }
764 public Scope members() {
765 if (completer != null) complete();
766 return members_field;
767 }
769 public List<Attribute.Compound> getAnnotationMirrors() {
770 if (completer != null) complete();
771 return Assert.checkNonNull(annotations.getAttributes());
772 }
774 public Type erasure(Types types) {
775 if (erasure_field == null)
776 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
777 List.<Type>nil(), this);
778 return erasure_field;
779 }
781 public String className() {
782 if (name.isEmpty())
783 return
784 Log.getLocalizedString("anonymous.class", flatname);
785 else
786 return fullname.toString();
787 }
789 public Name getQualifiedName() {
790 return fullname;
791 }
793 public Name flatName() {
794 return flatname;
795 }
797 public boolean isSubClass(Symbol base, Types types) {
798 if (this == base) {
799 return true;
800 } else if ((base.flags() & INTERFACE) != 0) {
801 for (Type t = type; t.tag == CLASS; t = types.supertype(t))
802 for (List<Type> is = types.interfaces(t);
803 is.nonEmpty();
804 is = is.tail)
805 if (is.head.tsym.isSubClass(base, types)) return true;
806 } else {
807 for (Type t = type; t.tag == CLASS; t = types.supertype(t))
808 if (t.tsym == base) return true;
809 }
810 return false;
811 }
813 /** Complete the elaboration of this symbol's definition.
814 */
815 public void complete() throws CompletionFailure {
816 try {
817 super.complete();
818 } catch (CompletionFailure ex) {
819 // quiet error recovery
820 flags_field |= (PUBLIC|STATIC);
821 this.type = new ErrorType(this, Type.noType);
822 throw ex;
823 }
824 }
826 public List<Type> getInterfaces() {
827 complete();
828 if (type instanceof ClassType) {
829 ClassType t = (ClassType)type;
830 if (t.interfaces_field == null) // FIXME: shouldn't be null
831 t.interfaces_field = List.nil();
832 if (t.all_interfaces_field != null)
833 return Type.getModelTypes(t.all_interfaces_field);
834 return t.interfaces_field;
835 } else {
836 return List.nil();
837 }
838 }
840 public Type getSuperclass() {
841 complete();
842 if (type instanceof ClassType) {
843 ClassType t = (ClassType)type;
844 if (t.supertype_field == null) // FIXME: shouldn't be null
845 t.supertype_field = Type.noType;
846 // An interface has no superclass; its supertype is Object.
847 return t.isInterface()
848 ? Type.noType
849 : t.supertype_field.getModelType();
850 } else {
851 return Type.noType;
852 }
853 }
855 public ElementKind getKind() {
856 long flags = flags();
857 if ((flags & ANNOTATION) != 0)
858 return ElementKind.ANNOTATION_TYPE;
859 else if ((flags & INTERFACE) != 0)
860 return ElementKind.INTERFACE;
861 else if ((flags & ENUM) != 0)
862 return ElementKind.ENUM;
863 else
864 return ElementKind.CLASS;
865 }
867 public NestingKind getNestingKind() {
868 complete();
869 if (owner.kind == PCK)
870 return NestingKind.TOP_LEVEL;
871 else if (name.isEmpty())
872 return NestingKind.ANONYMOUS;
873 else if (owner.kind == MTH)
874 return NestingKind.LOCAL;
875 else
876 return NestingKind.MEMBER;
877 }
879 /**
880 * @deprecated this method should never be used by javac internally.
881 */
882 @Override @Deprecated
883 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
884 return JavacElements.getAnnotation(this, annoType);
885 }
887 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
888 return v.visitType(this, p);
889 }
891 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
892 return v.visitClassSymbol(this, p);
893 }
894 }
897 /** A class for variable symbols
898 */
899 public static class VarSymbol extends Symbol implements VariableElement {
901 /** The variable's declaration position.
902 */
903 public int pos = Position.NOPOS;
905 /** The variable's address. Used for different purposes during
906 * flow analysis, translation and code generation.
907 * Flow analysis:
908 * If this is a blank final or local variable, its sequence number.
909 * Translation:
910 * If this is a private field, its access number.
911 * Code generation:
912 * If this is a local variable, its logical slot number.
913 */
914 public int adr = -1;
916 /** Construct a variable symbol, given its flags, name, type and owner.
917 */
918 public VarSymbol(long flags, Name name, Type type, Symbol owner) {
919 super(VAR, flags, name, type, owner);
920 }
922 /** Clone this symbol with new owner.
923 */
924 public VarSymbol clone(Symbol newOwner) {
925 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) {
926 @Override
927 public Symbol baseSymbol() {
928 return VarSymbol.this;
929 }
930 };
931 v.pos = pos;
932 v.adr = adr;
933 v.data = data;
934 // System.out.println("clone " + v + " in " + newOwner);//DEBUG
935 return v;
936 }
938 public String toString() {
939 return name.toString();
940 }
942 public Symbol asMemberOf(Type site, Types types) {
943 return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
944 }
946 public ElementKind getKind() {
947 long flags = flags();
948 if ((flags & PARAMETER) != 0) {
949 if (isExceptionParameter())
950 return ElementKind.EXCEPTION_PARAMETER;
951 else
952 return ElementKind.PARAMETER;
953 } else if ((flags & ENUM) != 0) {
954 return ElementKind.ENUM_CONSTANT;
955 } else if (owner.kind == TYP || owner.kind == ERR) {
956 return ElementKind.FIELD;
957 } else if (isResourceVariable()) {
958 return ElementKind.RESOURCE_VARIABLE;
959 } else {
960 return ElementKind.LOCAL_VARIABLE;
961 }
962 }
964 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
965 return v.visitVariable(this, p);
966 }
968 public Object getConstantValue() { // Mirror API
969 return Constants.decode(getConstValue(), type);
970 }
972 public void setLazyConstValue(final Env<AttrContext> env,
973 final Attr attr,
974 final JCTree.JCExpression initializer)
975 {
976 setData(new Callable<Object>() {
977 public Object call() {
978 return attr.attribLazyConstantValue(env, initializer, type);
979 }
980 });
981 }
983 /**
984 * The variable's constant value, if this is a constant.
985 * Before the constant value is evaluated, it points to an
986 * initalizer environment. If this is not a constant, it can
987 * be used for other stuff.
988 */
989 private Object data;
991 public boolean isExceptionParameter() {
992 return data == ElementKind.EXCEPTION_PARAMETER;
993 }
995 public boolean isResourceVariable() {
996 return data == ElementKind.RESOURCE_VARIABLE;
997 }
999 public Object getConstValue() {
1000 // TODO: Consider if getConstValue and getConstantValue can be collapsed
1001 if (data == ElementKind.EXCEPTION_PARAMETER ||
1002 data == ElementKind.RESOURCE_VARIABLE) {
1003 return null;
1004 } else if (data instanceof Callable<?>) {
1005 // In this case, this is a final variable, with an as
1006 // yet unevaluated initializer.
1007 Callable<?> eval = (Callable<?>)data;
1008 data = null; // to make sure we don't evaluate this twice.
1009 try {
1010 data = eval.call();
1011 } catch (Exception ex) {
1012 throw new AssertionError(ex);
1013 }
1014 }
1015 return data;
1016 }
1018 public void setData(Object data) {
1019 Assert.check(!(data instanceof Env<?>), this);
1020 this.data = data;
1021 }
1023 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1024 return v.visitVarSymbol(this, p);
1025 }
1026 }
1028 /** A class for method symbols.
1029 */
1030 public static class MethodSymbol extends Symbol implements ExecutableElement {
1032 /** The code of the method. */
1033 public Code code = null;
1035 /** The parameters of the method. */
1036 public List<VarSymbol> params = null;
1038 /** The names of the parameters */
1039 public List<Name> savedParameterNames;
1041 /** For an attribute field accessor, its default value if any.
1042 * The value is null if none appeared in the method
1043 * declaration.
1044 */
1045 public Attribute defaultValue = null;
1047 /** Construct a method symbol, given its flags, name, type and owner.
1048 */
1049 public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1050 super(MTH, flags, name, type, owner);
1051 if (owner.type.tag == TYPEVAR) Assert.error(owner + "." + name);
1052 }
1054 /** Clone this symbol with new owner.
1055 */
1056 public MethodSymbol clone(Symbol newOwner) {
1057 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) {
1058 @Override
1059 public Symbol baseSymbol() {
1060 return MethodSymbol.this;
1061 }
1062 };
1063 m.code = code;
1064 return m;
1065 }
1067 /** The Java source which this symbol represents.
1068 */
1069 public String toString() {
1070 if ((flags() & BLOCK) != 0) {
1071 return owner.name.toString();
1072 } else {
1073 String s = (name == name.table.names.init)
1074 ? owner.name.toString()
1075 : name.toString();
1076 if (type != null) {
1077 if (type.tag == FORALL)
1078 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1079 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1080 }
1081 return s;
1082 }
1083 }
1085 public boolean isDynamic() {
1086 return false;
1087 }
1089 /** find a symbol that this (proxy method) symbol implements.
1090 * @param c The class whose members are searched for
1091 * implementations
1092 */
1093 public Symbol implemented(TypeSymbol c, Types types) {
1094 Symbol impl = null;
1095 for (List<Type> is = types.interfaces(c.type);
1096 impl == null && is.nonEmpty();
1097 is = is.tail) {
1098 TypeSymbol i = is.head.tsym;
1099 impl = implementedIn(i, types);
1100 if (impl == null)
1101 impl = implemented(i, types);
1102 }
1103 return impl;
1104 }
1106 public Symbol implementedIn(TypeSymbol c, Types types) {
1107 Symbol impl = null;
1108 for (Scope.Entry e = c.members().lookup(name);
1109 impl == null && e.scope != null;
1110 e = e.next()) {
1111 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
1112 // FIXME: I suspect the following requires a
1113 // subst() for a parametric return type.
1114 types.isSameType(type.getReturnType(),
1115 types.memberType(owner.type, e.sym).getReturnType())) {
1116 impl = e.sym;
1117 }
1118 }
1119 return impl;
1120 }
1122 /** Will the erasure of this method be considered by the VM to
1123 * override the erasure of the other when seen from class `origin'?
1124 */
1125 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1126 if (isConstructor() || _other.kind != MTH) return false;
1128 if (this == _other) return true;
1129 MethodSymbol other = (MethodSymbol)_other;
1131 // check for a direct implementation
1132 if (other.isOverridableIn((TypeSymbol)owner) &&
1133 types.asSuper(owner.type, other.owner) != null &&
1134 types.isSameType(erasure(types), other.erasure(types)))
1135 return true;
1137 // check for an inherited implementation
1138 return
1139 (flags() & ABSTRACT) == 0 &&
1140 other.isOverridableIn(origin) &&
1141 this.isMemberOf(origin, types) &&
1142 types.isSameType(erasure(types), other.erasure(types));
1143 }
1145 /** The implementation of this (abstract) symbol in class origin,
1146 * from the VM's point of view, null if method does not have an
1147 * implementation in class.
1148 * @param origin The class of which the implementation is a member.
1149 */
1150 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1151 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1152 for (Scope.Entry e = c.members().lookup(name);
1153 e.scope != null;
1154 e = e.next()) {
1155 if (e.sym.kind == MTH &&
1156 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
1157 return (MethodSymbol)e.sym;
1158 }
1159 }
1160 return null;
1161 }
1163 /** Does this symbol override `other' symbol, when both are seen as
1164 * members of class `origin'? It is assumed that _other is a member
1165 * of origin.
1166 *
1167 * It is assumed that both symbols have the same name. The static
1168 * modifier is ignored for this test.
1169 *
1170 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1171 */
1172 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1173 if (isConstructor() || _other.kind != MTH) return false;
1175 if (this == _other) return true;
1176 MethodSymbol other = (MethodSymbol)_other;
1178 // check for a direct implementation
1179 if (other.isOverridableIn((TypeSymbol)owner) &&
1180 types.asSuper(owner.type, other.owner) != null) {
1181 Type mt = types.memberType(owner.type, this);
1182 Type ot = types.memberType(owner.type, other);
1183 if (types.isSubSignature(mt, ot)) {
1184 if (!checkResult)
1185 return true;
1186 if (types.returnTypeSubstitutable(mt, ot))
1187 return true;
1188 }
1189 }
1191 // check for an inherited implementation
1192 if ((flags() & ABSTRACT) != 0 ||
1193 (other.flags() & ABSTRACT) == 0 ||
1194 !other.isOverridableIn(origin) ||
1195 !this.isMemberOf(origin, types))
1196 return false;
1198 // assert types.asSuper(origin.type, other.owner) != null;
1199 Type mt = types.memberType(origin.type, this);
1200 Type ot = types.memberType(origin.type, other);
1201 return
1202 types.isSubSignature(mt, ot) &&
1203 (!checkResult || types.resultSubtype(mt, ot, Warner.noWarnings));
1204 }
1206 private boolean isOverridableIn(TypeSymbol origin) {
1207 // JLS 8.4.6.1
1208 switch ((int)(flags_field & Flags.AccessFlags)) {
1209 case Flags.PRIVATE:
1210 return false;
1211 case Flags.PUBLIC:
1212 return true;
1213 case Flags.PROTECTED:
1214 return (origin.flags() & INTERFACE) == 0;
1215 case 0:
1216 // for package private: can only override in the same
1217 // package
1218 return
1219 this.packge() == origin.packge() &&
1220 (origin.flags() & INTERFACE) == 0;
1221 default:
1222 return false;
1223 }
1224 }
1226 /** The implementation of this (abstract) symbol in class origin;
1227 * null if none exists. Synthetic methods are not considered
1228 * as possible implementations.
1229 */
1230 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1231 return implementation(origin, types, checkResult, implementation_filter);
1232 }
1233 // where
1234 private static final Filter<Symbol> implementation_filter = new Filter<Symbol>() {
1235 public boolean accepts(Symbol s) {
1236 return s.kind == Kinds.MTH &&
1237 (s.flags() & SYNTHETIC) == 0;
1238 }
1239 };
1241 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
1242 MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
1243 if (res != null)
1244 return res;
1245 // if origin is derived from a raw type, we might have missed
1246 // an implementation because we do not know enough about instantiations.
1247 // in this case continue with the supertype as origin.
1248 if (types.isDerivedRaw(origin.type) && !origin.isInterface())
1249 return implementation(types.supertype(origin.type).tsym, types, checkResult);
1250 else
1251 return null;
1252 }
1254 public List<VarSymbol> params() {
1255 owner.complete();
1256 if (params == null) {
1257 // If ClassReader.saveParameterNames has been set true, then
1258 // savedParameterNames will be set to a list of names that
1259 // matches the types in type.getParameterTypes(). If any names
1260 // were not found in the class file, those names in the list will
1261 // be set to the empty name.
1262 // If ClassReader.saveParameterNames has been set false, then
1263 // savedParameterNames will be null.
1264 List<Name> paramNames = savedParameterNames;
1265 savedParameterNames = null;
1266 // discard the provided names if the list of names is the wrong size.
1267 if (paramNames == null || paramNames.size() != type.getParameterTypes().size())
1268 paramNames = List.nil();
1269 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
1270 List<Name> remaining = paramNames;
1271 // assert: remaining and paramNames are both empty or both
1272 // have same cardinality as type.getParameterTypes()
1273 int i = 0;
1274 for (Type t : type.getParameterTypes()) {
1275 Name paramName;
1276 if (remaining.isEmpty()) {
1277 // no names for any parameters available
1278 paramName = createArgName(i, paramNames);
1279 } else {
1280 paramName = remaining.head;
1281 remaining = remaining.tail;
1282 if (paramName.isEmpty()) {
1283 // no name for this specific parameter
1284 paramName = createArgName(i, paramNames);
1285 }
1286 }
1287 buf.append(new VarSymbol(PARAMETER, paramName, t, this));
1288 i++;
1289 }
1290 params = buf.toList();
1291 }
1292 return params;
1293 }
1295 // Create a name for the argument at position 'index' that is not in
1296 // the exclude list. In normal use, either no names will have been
1297 // provided, in which case the exclude list is empty, or all the names
1298 // will have been provided, in which case this method will not be called.
1299 private Name createArgName(int index, List<Name> exclude) {
1300 String prefix = "arg";
1301 while (true) {
1302 Name argName = name.table.fromString(prefix + index);
1303 if (!exclude.contains(argName))
1304 return argName;
1305 prefix += "$";
1306 }
1307 }
1309 public Symbol asMemberOf(Type site, Types types) {
1310 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1311 }
1313 public ElementKind getKind() {
1314 if (name == name.table.names.init)
1315 return ElementKind.CONSTRUCTOR;
1316 else if (name == name.table.names.clinit)
1317 return ElementKind.STATIC_INIT;
1318 else if ((flags() & BLOCK) != 0)
1319 return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT;
1320 else
1321 return ElementKind.METHOD;
1322 }
1324 public boolean isStaticOrInstanceInit() {
1325 return getKind() == ElementKind.STATIC_INIT ||
1326 getKind() == ElementKind.INSTANCE_INIT;
1327 }
1329 /**
1330 * A polymorphic signature method (JLS SE 7, 8.4.1) is a method that
1331 * (i) is declared in the java.lang.invoke.MethodHandle class, (ii) takes
1332 * a single variable arity parameter (iii) whose declared type is Object[],
1333 * (iv) has a return type of Object and (v) is native.
1334 */
1335 public boolean isSignaturePolymorphic(Types types) {
1336 List<Type> argtypes = type.getParameterTypes();
1337 Type firstElemType = argtypes.nonEmpty() ?
1338 types.elemtype(argtypes.head) :
1339 null;
1340 return owner == types.syms.methodHandleType.tsym &&
1341 argtypes.length() == 1 &&
1342 firstElemType != null &&
1343 types.isSameType(firstElemType, types.syms.objectType) &&
1344 types.isSameType(type.getReturnType(), types.syms.objectType) &&
1345 (flags() & NATIVE) != 0;
1346 }
1348 public Attribute getDefaultValue() {
1349 return defaultValue;
1350 }
1352 public List<VarSymbol> getParameters() {
1353 return params();
1354 }
1356 public boolean isVarArgs() {
1357 return (flags() & VARARGS) != 0;
1358 }
1360 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1361 return v.visitExecutable(this, p);
1362 }
1364 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1365 return v.visitMethodSymbol(this, p);
1366 }
1368 public Type getReturnType() {
1369 return asType().getReturnType();
1370 }
1372 public List<Type> getThrownTypes() {
1373 return asType().getThrownTypes();
1374 }
1375 }
1377 /** A class for invokedynamic method calls.
1378 */
1379 public static class DynamicMethodSymbol extends MethodSymbol {
1381 public Object[] staticArgs;
1382 public Symbol bsm;
1383 public int bsmKind;
1385 public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
1386 super(0, name, type, owner);
1387 this.bsm = bsm;
1388 this.bsmKind = bsmKind;
1389 this.staticArgs = staticArgs;
1390 }
1392 @Override
1393 public boolean isDynamic() {
1394 return true;
1395 }
1396 }
1398 /** A class for predefined operators.
1399 */
1400 public static class OperatorSymbol extends MethodSymbol {
1402 public int opcode;
1404 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1405 super(PUBLIC | STATIC, name, type, owner);
1406 this.opcode = opcode;
1407 }
1409 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1410 return v.visitOperatorSymbol(this, p);
1411 }
1412 }
1414 /** Symbol completer interface.
1415 */
1416 public static interface Completer {
1417 void complete(Symbol sym) throws CompletionFailure;
1418 }
1420 public static class CompletionFailure extends RuntimeException {
1421 private static final long serialVersionUID = 0;
1422 public Symbol sym;
1424 /** A diagnostic object describing the failure
1425 */
1426 public JCDiagnostic diag;
1428 /** A localized string describing the failure.
1429 * @deprecated Use {@code getDetail()} or {@code getMessage()}
1430 */
1431 @Deprecated
1432 public String errmsg;
1434 public CompletionFailure(Symbol sym, String errmsg) {
1435 this.sym = sym;
1436 this.errmsg = errmsg;
1437 // this.printStackTrace();//DEBUG
1438 }
1440 public CompletionFailure(Symbol sym, JCDiagnostic diag) {
1441 this.sym = sym;
1442 this.diag = diag;
1443 // this.printStackTrace();//DEBUG
1444 }
1446 public JCDiagnostic getDiagnostic() {
1447 return diag;
1448 }
1450 @Override
1451 public String getMessage() {
1452 if (diag != null)
1453 return diag.getMessage(null);
1454 else
1455 return errmsg;
1456 }
1458 public Object getDetailValue() {
1459 return (diag != null ? diag : errmsg);
1460 }
1462 @Override
1463 public CompletionFailure initCause(Throwable cause) {
1464 super.initCause(cause);
1465 return this;
1466 }
1468 }
1470 /**
1471 * A visitor for symbols. A visitor is used to implement operations
1472 * (or relations) on symbols. Most common operations on types are
1473 * binary relations and this interface is designed for binary
1474 * relations, that is, operations on the form
1475 * Symbol × P → R.
1476 * <!-- In plain text: Type x P -> R -->
1477 *
1478 * @param <R> the return type of the operation implemented by this
1479 * visitor; use Void if no return type is needed.
1480 * @param <P> the type of the second argument (the first being the
1481 * symbol itself) of the operation implemented by this visitor; use
1482 * Void if a second argument is not needed.
1483 */
1484 public interface Visitor<R,P> {
1485 R visitClassSymbol(ClassSymbol s, P arg);
1486 R visitMethodSymbol(MethodSymbol s, P arg);
1487 R visitPackageSymbol(PackageSymbol s, P arg);
1488 R visitOperatorSymbol(OperatorSymbol s, P arg);
1489 R visitVarSymbol(VarSymbol s, P arg);
1490 R visitTypeSymbol(TypeSymbol s, P arg);
1491 R visitSymbol(Symbol s, P arg);
1492 }
1493 }