Thu, 04 Oct 2012 13:04:53 +0100
7177387: Add target-typing support in method context
Summary: Add support for deferred types and speculative attribution
Reviewed-by: jjg, dlsmith
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;
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 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 v.pos = pos;
927 v.adr = adr;
928 v.data = data;
929 // System.out.println("clone " + v + " in " + newOwner);//DEBUG
930 return v;
931 }
933 public String toString() {
934 return name.toString();
935 }
937 public Symbol asMemberOf(Type site, Types types) {
938 return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
939 }
941 public ElementKind getKind() {
942 long flags = flags();
943 if ((flags & PARAMETER) != 0) {
944 if (isExceptionParameter())
945 return ElementKind.EXCEPTION_PARAMETER;
946 else
947 return ElementKind.PARAMETER;
948 } else if ((flags & ENUM) != 0) {
949 return ElementKind.ENUM_CONSTANT;
950 } else if (owner.kind == TYP || owner.kind == ERR) {
951 return ElementKind.FIELD;
952 } else if (isResourceVariable()) {
953 return ElementKind.RESOURCE_VARIABLE;
954 } else {
955 return ElementKind.LOCAL_VARIABLE;
956 }
957 }
959 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
960 return v.visitVariable(this, p);
961 }
963 public Object getConstantValue() { // Mirror API
964 return Constants.decode(getConstValue(), type);
965 }
967 public void setLazyConstValue(final Env<AttrContext> env,
968 final Attr attr,
969 final JCTree.JCExpression initializer)
970 {
971 setData(new Callable<Object>() {
972 public Object call() {
973 return attr.attribLazyConstantValue(env, initializer, type);
974 }
975 });
976 }
978 /**
979 * The variable's constant value, if this is a constant.
980 * Before the constant value is evaluated, it points to an
981 * initalizer environment. If this is not a constant, it can
982 * be used for other stuff.
983 */
984 private Object data;
986 public boolean isExceptionParameter() {
987 return data == ElementKind.EXCEPTION_PARAMETER;
988 }
990 public boolean isResourceVariable() {
991 return data == ElementKind.RESOURCE_VARIABLE;
992 }
994 public Object getConstValue() {
995 // TODO: Consider if getConstValue and getConstantValue can be collapsed
996 if (data == ElementKind.EXCEPTION_PARAMETER ||
997 data == ElementKind.RESOURCE_VARIABLE) {
998 return null;
999 } else if (data instanceof Callable<?>) {
1000 // In this case, this is a final variable, with an as
1001 // yet unevaluated initializer.
1002 Callable<?> eval = (Callable<?>)data;
1003 data = null; // to make sure we don't evaluate this twice.
1004 try {
1005 data = eval.call();
1006 } catch (Exception ex) {
1007 throw new AssertionError(ex);
1008 }
1009 }
1010 return data;
1011 }
1013 public void setData(Object data) {
1014 Assert.check(!(data instanceof Env<?>), this);
1015 this.data = data;
1016 }
1018 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1019 return v.visitVarSymbol(this, p);
1020 }
1021 }
1023 /** A class for method symbols.
1024 */
1025 public static class MethodSymbol extends Symbol implements ExecutableElement {
1027 /** The code of the method. */
1028 public Code code = null;
1030 /** The parameters of the method. */
1031 public List<VarSymbol> params = null;
1033 /** The names of the parameters */
1034 public List<Name> savedParameterNames;
1036 /** For an attribute field accessor, its default value if any.
1037 * The value is null if none appeared in the method
1038 * declaration.
1039 */
1040 public Attribute defaultValue = null;
1042 /** Construct a method symbol, given its flags, name, type and owner.
1043 */
1044 public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1045 super(MTH, flags, name, type, owner);
1046 if (owner.type.tag == TYPEVAR) Assert.error(owner + "." + name);
1047 }
1049 /** Clone this symbol with new owner.
1050 */
1051 public MethodSymbol clone(Symbol newOwner) {
1052 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner);
1053 m.code = code;
1054 return m;
1055 }
1057 /** The Java source which this symbol represents.
1058 */
1059 public String toString() {
1060 if ((flags() & BLOCK) != 0) {
1061 return owner.name.toString();
1062 } else {
1063 String s = (name == name.table.names.init)
1064 ? owner.name.toString()
1065 : name.toString();
1066 if (type != null) {
1067 if (type.tag == FORALL)
1068 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1069 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1070 }
1071 return s;
1072 }
1073 }
1075 public boolean isDynamic() {
1076 return false;
1077 }
1079 /** find a symbol that this (proxy method) symbol implements.
1080 * @param c The class whose members are searched for
1081 * implementations
1082 */
1083 public Symbol implemented(TypeSymbol c, Types types) {
1084 Symbol impl = null;
1085 for (List<Type> is = types.interfaces(c.type);
1086 impl == null && is.nonEmpty();
1087 is = is.tail) {
1088 TypeSymbol i = is.head.tsym;
1089 impl = implementedIn(i, types);
1090 if (impl == null)
1091 impl = implemented(i, types);
1092 }
1093 return impl;
1094 }
1096 public Symbol implementedIn(TypeSymbol c, Types types) {
1097 Symbol impl = null;
1098 for (Scope.Entry e = c.members().lookup(name);
1099 impl == null && e.scope != null;
1100 e = e.next()) {
1101 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
1102 // FIXME: I suspect the following requires a
1103 // subst() for a parametric return type.
1104 types.isSameType(type.getReturnType(),
1105 types.memberType(owner.type, e.sym).getReturnType())) {
1106 impl = e.sym;
1107 }
1108 }
1109 return impl;
1110 }
1112 /** Will the erasure of this method be considered by the VM to
1113 * override the erasure of the other when seen from class `origin'?
1114 */
1115 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1116 if (isConstructor() || _other.kind != MTH) return false;
1118 if (this == _other) return true;
1119 MethodSymbol other = (MethodSymbol)_other;
1121 // check for a direct implementation
1122 if (other.isOverridableIn((TypeSymbol)owner) &&
1123 types.asSuper(owner.type, other.owner) != null &&
1124 types.isSameType(erasure(types), other.erasure(types)))
1125 return true;
1127 // check for an inherited implementation
1128 return
1129 (flags() & ABSTRACT) == 0 &&
1130 other.isOverridableIn(origin) &&
1131 this.isMemberOf(origin, types) &&
1132 types.isSameType(erasure(types), other.erasure(types));
1133 }
1135 /** The implementation of this (abstract) symbol in class origin,
1136 * from the VM's point of view, null if method does not have an
1137 * implementation in class.
1138 * @param origin The class of which the implementation is a member.
1139 */
1140 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1141 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1142 for (Scope.Entry e = c.members().lookup(name);
1143 e.scope != null;
1144 e = e.next()) {
1145 if (e.sym.kind == MTH &&
1146 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
1147 return (MethodSymbol)e.sym;
1148 }
1149 }
1150 return null;
1151 }
1153 /** Does this symbol override `other' symbol, when both are seen as
1154 * members of class `origin'? It is assumed that _other is a member
1155 * of origin.
1156 *
1157 * It is assumed that both symbols have the same name. The static
1158 * modifier is ignored for this test.
1159 *
1160 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1161 */
1162 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1163 if (isConstructor() || _other.kind != MTH) return false;
1165 if (this == _other) return true;
1166 MethodSymbol other = (MethodSymbol)_other;
1168 // check for a direct implementation
1169 if (other.isOverridableIn((TypeSymbol)owner) &&
1170 types.asSuper(owner.type, other.owner) != null) {
1171 Type mt = types.memberType(owner.type, this);
1172 Type ot = types.memberType(owner.type, other);
1173 if (types.isSubSignature(mt, ot)) {
1174 if (!checkResult)
1175 return true;
1176 if (types.returnTypeSubstitutable(mt, ot))
1177 return true;
1178 }
1179 }
1181 // check for an inherited implementation
1182 if ((flags() & ABSTRACT) != 0 ||
1183 (other.flags() & ABSTRACT) == 0 ||
1184 !other.isOverridableIn(origin) ||
1185 !this.isMemberOf(origin, types))
1186 return false;
1188 // assert types.asSuper(origin.type, other.owner) != null;
1189 Type mt = types.memberType(origin.type, this);
1190 Type ot = types.memberType(origin.type, other);
1191 return
1192 types.isSubSignature(mt, ot) &&
1193 (!checkResult || types.resultSubtype(mt, ot, Warner.noWarnings));
1194 }
1196 private boolean isOverridableIn(TypeSymbol origin) {
1197 // JLS 8.4.6.1
1198 switch ((int)(flags_field & Flags.AccessFlags)) {
1199 case Flags.PRIVATE:
1200 return false;
1201 case Flags.PUBLIC:
1202 return true;
1203 case Flags.PROTECTED:
1204 return (origin.flags() & INTERFACE) == 0;
1205 case 0:
1206 // for package private: can only override in the same
1207 // package
1208 return
1209 this.packge() == origin.packge() &&
1210 (origin.flags() & INTERFACE) == 0;
1211 default:
1212 return false;
1213 }
1214 }
1216 /** The implementation of this (abstract) symbol in class origin;
1217 * null if none exists. Synthetic methods are not considered
1218 * as possible implementations.
1219 */
1220 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1221 return implementation(origin, types, checkResult, implementation_filter);
1222 }
1223 // where
1224 private static final Filter<Symbol> implementation_filter = new Filter<Symbol>() {
1225 public boolean accepts(Symbol s) {
1226 return s.kind == Kinds.MTH &&
1227 (s.flags() & SYNTHETIC) == 0;
1228 }
1229 };
1231 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
1232 MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
1233 if (res != null)
1234 return res;
1235 // if origin is derived from a raw type, we might have missed
1236 // an implementation because we do not know enough about instantiations.
1237 // in this case continue with the supertype as origin.
1238 if (types.isDerivedRaw(origin.type) && !origin.isInterface())
1239 return implementation(types.supertype(origin.type).tsym, types, checkResult);
1240 else
1241 return null;
1242 }
1244 public List<VarSymbol> params() {
1245 owner.complete();
1246 if (params == null) {
1247 // If ClassReader.saveParameterNames has been set true, then
1248 // savedParameterNames will be set to a list of names that
1249 // matches the types in type.getParameterTypes(). If any names
1250 // were not found in the class file, those names in the list will
1251 // be set to the empty name.
1252 // If ClassReader.saveParameterNames has been set false, then
1253 // savedParameterNames will be null.
1254 List<Name> paramNames = savedParameterNames;
1255 savedParameterNames = null;
1256 // discard the provided names if the list of names is the wrong size.
1257 if (paramNames == null || paramNames.size() != type.getParameterTypes().size())
1258 paramNames = List.nil();
1259 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
1260 List<Name> remaining = paramNames;
1261 // assert: remaining and paramNames are both empty or both
1262 // have same cardinality as type.getParameterTypes()
1263 int i = 0;
1264 for (Type t : type.getParameterTypes()) {
1265 Name paramName;
1266 if (remaining.isEmpty()) {
1267 // no names for any parameters available
1268 paramName = createArgName(i, paramNames);
1269 } else {
1270 paramName = remaining.head;
1271 remaining = remaining.tail;
1272 if (paramName.isEmpty()) {
1273 // no name for this specific parameter
1274 paramName = createArgName(i, paramNames);
1275 }
1276 }
1277 buf.append(new VarSymbol(PARAMETER, paramName, t, this));
1278 i++;
1279 }
1280 params = buf.toList();
1281 }
1282 return params;
1283 }
1285 // Create a name for the argument at position 'index' that is not in
1286 // the exclude list. In normal use, either no names will have been
1287 // provided, in which case the exclude list is empty, or all the names
1288 // will have been provided, in which case this method will not be called.
1289 private Name createArgName(int index, List<Name> exclude) {
1290 String prefix = "arg";
1291 while (true) {
1292 Name argName = name.table.fromString(prefix + index);
1293 if (!exclude.contains(argName))
1294 return argName;
1295 prefix += "$";
1296 }
1297 }
1299 public Symbol asMemberOf(Type site, Types types) {
1300 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1301 }
1303 public ElementKind getKind() {
1304 if (name == name.table.names.init)
1305 return ElementKind.CONSTRUCTOR;
1306 else if (name == name.table.names.clinit)
1307 return ElementKind.STATIC_INIT;
1308 else if ((flags() & BLOCK) != 0)
1309 return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT;
1310 else
1311 return ElementKind.METHOD;
1312 }
1314 public boolean isStaticOrInstanceInit() {
1315 return getKind() == ElementKind.STATIC_INIT ||
1316 getKind() == ElementKind.INSTANCE_INIT;
1317 }
1319 /**
1320 * A polymorphic signature method (JLS SE 7, 8.4.1) is a method that
1321 * (i) is declared in the java.lang.invoke.MethodHandle class, (ii) takes
1322 * a single variable arity parameter (iii) whose declared type is Object[],
1323 * (iv) has a return type of Object and (v) is native.
1324 */
1325 public boolean isSignaturePolymorphic(Types types) {
1326 List<Type> argtypes = type.getParameterTypes();
1327 Type firstElemType = argtypes.nonEmpty() ?
1328 types.elemtype(argtypes.head) :
1329 null;
1330 return owner == types.syms.methodHandleType.tsym &&
1331 argtypes.length() == 1 &&
1332 firstElemType != null &&
1333 types.isSameType(firstElemType, types.syms.objectType) &&
1334 types.isSameType(type.getReturnType(), types.syms.objectType) &&
1335 (flags() & NATIVE) != 0;
1336 }
1338 public Attribute getDefaultValue() {
1339 return defaultValue;
1340 }
1342 public List<VarSymbol> getParameters() {
1343 return params();
1344 }
1346 public boolean isVarArgs() {
1347 return (flags() & VARARGS) != 0;
1348 }
1350 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1351 return v.visitExecutable(this, p);
1352 }
1354 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1355 return v.visitMethodSymbol(this, p);
1356 }
1358 public Type getReturnType() {
1359 return asType().getReturnType();
1360 }
1362 public List<Type> getThrownTypes() {
1363 return asType().getThrownTypes();
1364 }
1365 }
1367 /** A class for invokedynamic method calls.
1368 */
1369 public static class DynamicMethodSymbol extends MethodSymbol {
1371 public Object[] staticArgs;
1372 public Symbol bsm;
1373 public int bsmKind;
1375 public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
1376 super(0, name, type, owner);
1377 this.bsm = bsm;
1378 this.bsmKind = bsmKind;
1379 this.staticArgs = staticArgs;
1380 }
1382 @Override
1383 public boolean isDynamic() {
1384 return true;
1385 }
1386 }
1388 /** A class for predefined operators.
1389 */
1390 public static class OperatorSymbol extends MethodSymbol {
1392 public int opcode;
1394 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1395 super(PUBLIC | STATIC, name, type, owner);
1396 this.opcode = opcode;
1397 }
1399 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1400 return v.visitOperatorSymbol(this, p);
1401 }
1402 }
1404 /** Symbol completer interface.
1405 */
1406 public static interface Completer {
1407 void complete(Symbol sym) throws CompletionFailure;
1408 }
1410 public static class CompletionFailure extends RuntimeException {
1411 private static final long serialVersionUID = 0;
1412 public Symbol sym;
1414 /** A diagnostic object describing the failure
1415 */
1416 public JCDiagnostic diag;
1418 /** A localized string describing the failure.
1419 * @deprecated Use {@code getDetail()} or {@code getMessage()}
1420 */
1421 @Deprecated
1422 public String errmsg;
1424 public CompletionFailure(Symbol sym, String errmsg) {
1425 this.sym = sym;
1426 this.errmsg = errmsg;
1427 // this.printStackTrace();//DEBUG
1428 }
1430 public CompletionFailure(Symbol sym, JCDiagnostic diag) {
1431 this.sym = sym;
1432 this.diag = diag;
1433 // this.printStackTrace();//DEBUG
1434 }
1436 public JCDiagnostic getDiagnostic() {
1437 return diag;
1438 }
1440 @Override
1441 public String getMessage() {
1442 if (diag != null)
1443 return diag.getMessage(null);
1444 else
1445 return errmsg;
1446 }
1448 public Object getDetailValue() {
1449 return (diag != null ? diag : errmsg);
1450 }
1452 @Override
1453 public CompletionFailure initCause(Throwable cause) {
1454 super.initCause(cause);
1455 return this;
1456 }
1458 }
1460 /**
1461 * A visitor for symbols. A visitor is used to implement operations
1462 * (or relations) on symbols. Most common operations on types are
1463 * binary relations and this interface is designed for binary
1464 * relations, that is, operations on the form
1465 * Symbol × P → R.
1466 * <!-- In plain text: Type x P -> R -->
1467 *
1468 * @param <R> the return type of the operation implemented by this
1469 * visitor; use Void if no return type is needed.
1470 * @param <P> the type of the second argument (the first being the
1471 * symbol itself) of the operation implemented by this visitor; use
1472 * Void if a second argument is not needed.
1473 */
1474 public interface Visitor<R,P> {
1475 R visitClassSymbol(ClassSymbol s, P arg);
1476 R visitMethodSymbol(MethodSymbol s, P arg);
1477 R visitPackageSymbol(PackageSymbol s, P arg);
1478 R visitOperatorSymbol(OperatorSymbol s, P arg);
1479 R visitVarSymbol(VarSymbol s, P arg);
1480 R visitTypeSymbol(TypeSymbol s, P arg);
1481 R visitSymbol(Symbol s, P arg);
1482 }
1483 }