Wed, 17 Jul 2013 14:11:41 +0100
8012238: Nested method capture and inference
8008200: java/lang/Class/asSubclass/BasicUnit.java fails to compile
Summary: Inference support should be more flexible w.r.t. nested method calls returning captured types
Reviewed-by: jjg, vromero
1 /*
2 * Copyright (c) 1999, 2013, 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.Annotate;
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;
42 import com.sun.tools.javac.util.*;
43 import com.sun.tools.javac.util.Name;
44 import static com.sun.tools.javac.code.Flags.*;
45 import static com.sun.tools.javac.code.Kinds.*;
46 import static com.sun.tools.javac.code.TypeTag.CLASS;
47 import static com.sun.tools.javac.code.TypeTag.FORALL;
48 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
50 /** Root class for Java symbols. It contains subclasses
51 * for specific sorts of symbols, such as variables, methods and operators,
52 * types, packages. Each subclass is represented as a static inner class
53 * inside Symbol.
54 *
55 * <p><b>This is NOT part of any supported API.
56 * If you write code that depends on this, you do so at your own risk.
57 * This code and its internal interfaces are subject to change or
58 * deletion without notice.</b>
59 */
60 public abstract class Symbol implements Element {
61 // public Throwable debug = new Throwable();
63 /** The kind of this symbol.
64 * @see Kinds
65 */
66 public int kind;
68 /** The flags of this symbol.
69 */
70 public long flags_field;
72 /** An accessor method for the flags of this symbol.
73 * Flags of class symbols should be accessed through the accessor
74 * method to make sure that the class symbol is loaded.
75 */
76 public long flags() { return flags_field; }
78 /** The name of this symbol in Utf8 representation.
79 */
80 public Name name;
82 /** The type of this symbol.
83 */
84 public Type type;
86 /** The owner of this symbol.
87 */
88 public Symbol owner;
90 /** The completer of this symbol.
91 */
92 public Completer completer;
94 /** A cache for the type erasure of this symbol.
95 */
96 public Type erasure_field;
98 // <editor-fold defaultstate="collapsed" desc="annotations">
100 /** The attributes of this symbol are contained in this
101 * Annotations. The Annotations instance is NOT immutable.
102 */
103 protected Annotations annotations;
105 /** An accessor method for the attributes of this symbol.
106 * Attributes of class symbols should be accessed through the accessor
107 * method to make sure that the class symbol is loaded.
108 */
109 public List<Attribute.Compound> getRawAttributes() {
110 return (annotations == null)
111 ? List.<Attribute.Compound>nil()
112 : annotations.getDeclarationAttributes();
113 }
115 /** An accessor method for the type attributes of this symbol.
116 * Attributes of class symbols should be accessed through the accessor
117 * method to make sure that the class symbol is loaded.
118 */
119 public List<Attribute.TypeCompound> getRawTypeAttributes() {
120 return (annotations == null)
121 ? List.<Attribute.TypeCompound>nil()
122 : annotations.getTypeAttributes();
123 }
125 /** Fetch a particular annotation from a symbol. */
126 public Attribute.Compound attribute(Symbol anno) {
127 for (Attribute.Compound a : getRawAttributes()) {
128 if (a.type.tsym == anno) return a;
129 }
130 return null;
131 }
133 public boolean annotationsPendingCompletion() {
134 return annotations == null ? false : annotations.pendingCompletion();
135 }
137 public void appendAttributes(List<Attribute.Compound> l) {
138 if (l.nonEmpty()) {
139 initedAnnos().append(l);
140 }
141 }
143 public void appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
144 if (l.nonEmpty()) {
145 initedAnnos().appendClassInitTypeAttributes(l);
146 }
147 }
149 public void appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
150 if (l.nonEmpty()) {
151 initedAnnos().appendInitTypeAttributes(l);
152 }
153 }
155 public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) {
156 initedAnnos().appendTypeAttributesWithCompletion(ctx);
157 }
159 public void appendUniqueTypeAttributes(List<Attribute.TypeCompound> l) {
160 if (l.nonEmpty()) {
161 initedAnnos().appendUniqueTypes(l);
162 }
163 }
165 public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
166 return (annotations == null)
167 ? List.<Attribute.TypeCompound>nil()
168 : annotations.getClassInitTypeAttributes();
169 }
171 public List<Attribute.TypeCompound> getInitTypeAttributes() {
172 return (annotations == null)
173 ? List.<Attribute.TypeCompound>nil()
174 : annotations.getInitTypeAttributes();
175 }
177 public List<Attribute.Compound> getDeclarationAttributes() {
178 return (annotations == null)
179 ? List.<Attribute.Compound>nil()
180 : annotations.getDeclarationAttributes();
181 }
183 public boolean hasAnnotations() {
184 return (annotations != null && !annotations.isEmpty());
185 }
187 public boolean hasTypeAnnotations() {
188 return (annotations != null && !annotations.isTypesEmpty());
189 }
191 public void prependAttributes(List<Attribute.Compound> l) {
192 if (l.nonEmpty()) {
193 initedAnnos().prepend(l);
194 }
195 }
197 public void resetAnnotations() {
198 initedAnnos().reset();
199 }
201 public void setAttributes(Symbol other) {
202 if (annotations != null || other.annotations != null) {
203 initedAnnos().setAttributes(other.annotations);
204 }
205 }
207 public void setDeclarationAttributes(List<Attribute.Compound> a) {
208 if (annotations != null || a.nonEmpty()) {
209 initedAnnos().setDeclarationAttributes(a);
210 }
211 }
213 public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
214 initedAnnos().setDeclarationAttributesWithCompletion(ctx);
215 }
217 public void setTypeAttributes(List<Attribute.TypeCompound> a) {
218 if (annotations != null || a.nonEmpty()) {
219 if (annotations == null)
220 annotations = new Annotations(this);
221 annotations.setTypeAttributes(a);
222 }
223 }
225 private Annotations initedAnnos() {
226 if (annotations == null)
227 annotations = new Annotations(this);
228 return annotations;
229 }
231 /** This method is intended for debugging only. */
232 public Annotations getAnnotations() {
233 return annotations;
234 }
236 // </editor-fold>
238 /** Construct a symbol with given kind, flags, name, type and owner.
239 */
240 public Symbol(int kind, long flags, Name name, Type type, Symbol owner) {
241 this.kind = kind;
242 this.flags_field = flags;
243 this.type = type;
244 this.owner = owner;
245 this.completer = null;
246 this.erasure_field = null;
247 this.name = name;
248 }
250 /** Clone this symbol with new owner.
251 * Legal only for fields and methods.
252 */
253 public Symbol clone(Symbol newOwner) {
254 throw new AssertionError();
255 }
257 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
258 return v.visitSymbol(this, p);
259 }
261 /** The Java source which this symbol represents.
262 * A description of this symbol; overrides Object.
263 */
264 public String toString() {
265 return name.toString();
266 }
268 /** A Java source description of the location of this symbol; used for
269 * error reporting.
270 *
271 * @return null if the symbol is a package or a toplevel class defined in
272 * the default package; otherwise, the owner symbol is returned
273 */
274 public Symbol location() {
275 if (owner.name == null || (owner.name.isEmpty() &&
276 (owner.flags() & BLOCK) == 0 && owner.kind != PCK && owner.kind != TYP)) {
277 return null;
278 }
279 return owner;
280 }
282 public Symbol location(Type site, Types types) {
283 if (owner.name == null || owner.name.isEmpty()) {
284 return location();
285 }
286 if (owner.type.hasTag(CLASS)) {
287 Type ownertype = types.asOuterSuper(site, owner);
288 if (ownertype != null) return ownertype.tsym;
289 }
290 return owner;
291 }
293 public Symbol baseSymbol() {
294 return this;
295 }
297 /** The symbol's erased type.
298 */
299 public Type erasure(Types types) {
300 if (erasure_field == null)
301 erasure_field = types.erasure(type);
302 return erasure_field;
303 }
305 /** The external type of a symbol. This is the symbol's erased type
306 * except for constructors of inner classes which get the enclosing
307 * instance class added as first argument.
308 */
309 public Type externalType(Types types) {
310 Type t = erasure(types);
311 if (name == name.table.names.init && owner.hasOuterInstance()) {
312 Type outerThisType = types.erasure(owner.type.getEnclosingType());
313 return new MethodType(t.getParameterTypes().prepend(outerThisType),
314 t.getReturnType(),
315 t.getThrownTypes(),
316 t.tsym);
317 } else {
318 return t;
319 }
320 }
322 public boolean isDeprecated() {
323 return (flags_field & DEPRECATED) != 0;
324 }
326 public boolean isStatic() {
327 return
328 (flags() & STATIC) != 0 ||
329 (owner.flags() & INTERFACE) != 0 && kind != MTH;
330 }
332 public boolean isInterface() {
333 return (flags() & INTERFACE) != 0;
334 }
336 public boolean isPrivate() {
337 return (flags_field & Flags.AccessFlags) == PRIVATE;
338 }
340 public boolean isEnum() {
341 return (flags() & ENUM) != 0;
342 }
344 /** Is this symbol declared (directly or indirectly) local
345 * to a method or variable initializer?
346 * Also includes fields of inner classes which are in
347 * turn local to a method or variable initializer.
348 */
349 public boolean isLocal() {
350 return
351 (owner.kind & (VAR | MTH)) != 0 ||
352 (owner.kind == TYP && owner.isLocal());
353 }
355 /** Has this symbol an empty name? This includes anonymous
356 * inner classes.
357 */
358 public boolean isAnonymous() {
359 return name.isEmpty();
360 }
362 /** Is this symbol a constructor?
363 */
364 public boolean isConstructor() {
365 return name == name.table.names.init;
366 }
368 /** The fully qualified name of this symbol.
369 * This is the same as the symbol's name except for class symbols,
370 * which are handled separately.
371 */
372 public Name getQualifiedName() {
373 return name;
374 }
376 /** The fully qualified name of this symbol after converting to flat
377 * representation. This is the same as the symbol's name except for
378 * class symbols, which are handled separately.
379 */
380 public Name flatName() {
381 return getQualifiedName();
382 }
384 /** If this is a class or package, its members, otherwise null.
385 */
386 public Scope members() {
387 return null;
388 }
390 /** A class is an inner class if it it has an enclosing instance class.
391 */
392 public boolean isInner() {
393 return type.getEnclosingType().hasTag(CLASS);
394 }
396 /** An inner class has an outer instance if it is not an interface
397 * it has an enclosing instance class which might be referenced from the class.
398 * Nested classes can see instance members of their enclosing class.
399 * Their constructors carry an additional this$n parameter, inserted
400 * implicitly by the compiler.
401 *
402 * @see #isInner
403 */
404 public boolean hasOuterInstance() {
405 return
406 type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
407 }
409 /** The closest enclosing class of this symbol's declaration.
410 */
411 public ClassSymbol enclClass() {
412 Symbol c = this;
413 while (c != null &&
414 ((c.kind & TYP) == 0 || !c.type.hasTag(CLASS))) {
415 c = c.owner;
416 }
417 return (ClassSymbol)c;
418 }
420 /** The outermost class which indirectly owns this symbol.
421 */
422 public ClassSymbol outermostClass() {
423 Symbol sym = this;
424 Symbol prev = null;
425 while (sym.kind != PCK) {
426 prev = sym;
427 sym = sym.owner;
428 }
429 return (ClassSymbol) prev;
430 }
432 /** The package which indirectly owns this symbol.
433 */
434 public PackageSymbol packge() {
435 Symbol sym = this;
436 while (sym.kind != PCK) {
437 sym = sym.owner;
438 }
439 return (PackageSymbol) sym;
440 }
442 /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
443 */
444 public boolean isSubClass(Symbol base, Types types) {
445 throw new AssertionError("isSubClass " + this);
446 }
448 /** Fully check membership: hierarchy, protection, and hiding.
449 * Does not exclude methods not inherited due to overriding.
450 */
451 public boolean isMemberOf(TypeSymbol clazz, Types types) {
452 return
453 owner == clazz ||
454 clazz.isSubClass(owner, types) &&
455 isInheritedIn(clazz, types) &&
456 !hiddenIn((ClassSymbol)clazz, types);
457 }
459 /** Is this symbol the same as or enclosed by the given class? */
460 public boolean isEnclosedBy(ClassSymbol clazz) {
461 for (Symbol sym = this; sym.kind != PCK; sym = sym.owner)
462 if (sym == clazz) return true;
463 return false;
464 }
466 /** Check for hiding. Note that this doesn't handle multiple
467 * (interface) inheritance. */
468 private boolean hiddenIn(ClassSymbol clazz, Types types) {
469 if (kind == MTH && (flags() & STATIC) == 0) return false;
470 while (true) {
471 if (owner == clazz) return false;
472 Scope.Entry e = clazz.members().lookup(name);
473 while (e.scope != null) {
474 if (e.sym == this) return false;
475 if (e.sym.kind == kind &&
476 (kind != MTH ||
477 (e.sym.flags() & STATIC) != 0 &&
478 types.isSubSignature(e.sym.type, type)))
479 return true;
480 e = e.next();
481 }
482 Type superType = types.supertype(clazz.type);
483 if (!superType.hasTag(CLASS)) return false;
484 clazz = (ClassSymbol)superType.tsym;
485 }
486 }
488 /** Is this symbol inherited into a given class?
489 * PRE: If symbol's owner is a interface,
490 * it is already assumed that the interface is a superinterface
491 * of given class.
492 * @param clazz The class for which we want to establish membership.
493 * This must be a subclass of the member's owner.
494 */
495 public boolean isInheritedIn(Symbol clazz, Types types) {
496 switch ((int)(flags_field & Flags.AccessFlags)) {
497 default: // error recovery
498 case PUBLIC:
499 return true;
500 case PRIVATE:
501 return this.owner == clazz;
502 case PROTECTED:
503 // we model interfaces as extending Object
504 return (clazz.flags() & INTERFACE) == 0;
505 case 0:
506 PackageSymbol thisPackage = this.packge();
507 for (Symbol sup = clazz;
508 sup != null && sup != this.owner;
509 sup = types.supertype(sup.type).tsym) {
510 while (sup.type.hasTag(TYPEVAR))
511 sup = sup.type.getUpperBound().tsym;
512 if (sup.type.isErroneous())
513 return true; // error recovery
514 if ((sup.flags() & COMPOUND) != 0)
515 continue;
516 if (sup.packge() != thisPackage)
517 return false;
518 }
519 return (clazz.flags() & INTERFACE) == 0;
520 }
521 }
523 /** The (variable or method) symbol seen as a member of given
524 * class type`site' (this might change the symbol's type).
525 * This is used exclusively for producing diagnostics.
526 */
527 public Symbol asMemberOf(Type site, Types types) {
528 throw new AssertionError();
529 }
531 /** Does this method symbol override `other' symbol, when both are seen as
532 * members of class `origin'? It is assumed that _other is a member
533 * of origin.
534 *
535 * It is assumed that both symbols have the same name. The static
536 * modifier is ignored for this test.
537 *
538 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
539 */
540 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
541 return false;
542 }
544 /** Complete the elaboration of this symbol's definition.
545 */
546 public void complete() throws CompletionFailure {
547 if (completer != null) {
548 Completer c = completer;
549 completer = null;
550 c.complete(this);
551 }
552 }
554 /** True if the symbol represents an entity that exists.
555 */
556 public boolean exists() {
557 return true;
558 }
560 public Type asType() {
561 return type;
562 }
564 public Symbol getEnclosingElement() {
565 return owner;
566 }
568 public ElementKind getKind() {
569 return ElementKind.OTHER; // most unkind
570 }
572 public Set<Modifier> getModifiers() {
573 return Flags.asModifierSet(flags());
574 }
576 public Name getSimpleName() {
577 return name;
578 }
580 /**
581 * This is the implementation for {@code
582 * javax.lang.model.element.Element.getAnnotationMirrors()}.
583 */
584 @Override
585 public List<Attribute.Compound> getAnnotationMirrors() {
586 return getRawAttributes();
587 }
589 /**
590 * @deprecated this method should never be used by javac internally.
591 */
592 @Deprecated
593 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
594 return JavacAnnoConstructs.getAnnotation(this, annoType);
595 }
597 // This method is part of the javax.lang.model API, do not use this in javac code.
598 public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(Class<A> annoType) {
599 return JavacAnnoConstructs.getAnnotations(this, annoType);
600 }
602 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
603 public java.util.List<Symbol> getEnclosedElements() {
604 return List.nil();
605 }
607 public List<TypeVariableSymbol> getTypeParameters() {
608 ListBuffer<TypeVariableSymbol> l = ListBuffer.lb();
609 for (Type t : type.getTypeArguments()) {
610 Assert.check(t.tsym.getKind() == ElementKind.TYPE_PARAMETER);
611 l.append((TypeVariableSymbol)t.tsym);
612 }
613 return l.toList();
614 }
616 public static class DelegatedSymbol<T extends Symbol> extends Symbol {
617 protected T other;
618 public DelegatedSymbol(T other) {
619 super(other.kind, other.flags_field, other.name, other.type, other.owner);
620 this.other = other;
621 }
622 public String toString() { return other.toString(); }
623 public Symbol location() { return other.location(); }
624 public Symbol location(Type site, Types types) { return other.location(site, types); }
625 public Symbol baseSymbol() { return other; }
626 public Type erasure(Types types) { return other.erasure(types); }
627 public Type externalType(Types types) { return other.externalType(types); }
628 public boolean isLocal() { return other.isLocal(); }
629 public boolean isConstructor() { return other.isConstructor(); }
630 public Name getQualifiedName() { return other.getQualifiedName(); }
631 public Name flatName() { return other.flatName(); }
632 public Scope members() { return other.members(); }
633 public boolean isInner() { return other.isInner(); }
634 public boolean hasOuterInstance() { return other.hasOuterInstance(); }
635 public ClassSymbol enclClass() { return other.enclClass(); }
636 public ClassSymbol outermostClass() { return other.outermostClass(); }
637 public PackageSymbol packge() { return other.packge(); }
638 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
639 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
640 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
641 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
642 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
643 public void complete() throws CompletionFailure { other.complete(); }
645 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
646 return other.accept(v, p);
647 }
649 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
650 return v.visitSymbol(other, p);
651 }
653 public T getUnderlyingSymbol() {
654 return other;
655 }
656 }
658 /** A base class for Symbols representing types.
659 */
660 public static abstract class TypeSymbol extends Symbol {
661 public TypeSymbol(int kind, long flags, Name name, Type type, Symbol owner) {
662 super(kind, flags, name, type, owner);
663 }
664 /** form a fully qualified name from a name and an owner
665 */
666 static public Name formFullName(Name name, Symbol owner) {
667 if (owner == null) return name;
668 if (((owner.kind != ERR)) &&
669 ((owner.kind & (VAR | MTH)) != 0
670 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
671 )) return name;
672 Name prefix = owner.getQualifiedName();
673 if (prefix == null || prefix == prefix.table.names.empty)
674 return name;
675 else return prefix.append('.', name);
676 }
678 /** form a fully qualified name from a name and an owner, after
679 * converting to flat representation
680 */
681 static public Name formFlatName(Name name, Symbol owner) {
682 if (owner == null ||
683 (owner.kind & (VAR | MTH)) != 0
684 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
685 ) return name;
686 char sep = owner.kind == TYP ? '$' : '.';
687 Name prefix = owner.flatName();
688 if (prefix == null || prefix == prefix.table.names.empty)
689 return name;
690 else return prefix.append(sep, name);
691 }
693 /**
694 * A total ordering between type symbols that refines the
695 * class inheritance graph.
696 *
697 * Typevariables always precede other kinds of symbols.
698 */
699 public final boolean precedes(TypeSymbol that, Types types) {
700 if (this == that)
701 return false;
702 if (type.hasTag(that.type.getTag())) {
703 if (type.hasTag(CLASS)) {
704 return
705 types.rank(that.type) < types.rank(this.type) ||
706 types.rank(that.type) == types.rank(this.type) &&
707 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
708 } else if (type.hasTag(TYPEVAR)) {
709 return types.isSubtype(this.type, that.type);
710 }
711 }
712 return type.hasTag(TYPEVAR);
713 }
715 @Override
716 public java.util.List<Symbol> getEnclosedElements() {
717 List<Symbol> list = List.nil();
718 if (kind == TYP && type.hasTag(TYPEVAR)) {
719 return list;
720 }
721 for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
722 if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this)
723 list = list.prepend(e.sym);
724 }
725 return list;
726 }
728 @Override
729 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
730 return v.visitTypeSymbol(this, p);
731 }
732 }
734 /**
735 * Type variables are represented by instances of this class.
736 */
737 public static class TypeVariableSymbol
738 extends TypeSymbol implements TypeParameterElement {
740 public TypeVariableSymbol(long flags, Name name, Type type, Symbol owner) {
741 super(TYP, flags, name, type, owner);
742 }
744 public ElementKind getKind() {
745 return ElementKind.TYPE_PARAMETER;
746 }
748 @Override
749 public Symbol getGenericElement() {
750 return owner;
751 }
753 public List<Type> getBounds() {
754 TypeVar t = (TypeVar)type;
755 Type bound = t.getUpperBound();
756 if (!bound.isCompound())
757 return List.of(bound);
758 ClassType ct = (ClassType)bound;
759 if (!ct.tsym.erasure_field.isInterface()) {
760 return ct.interfaces_field.prepend(ct.supertype_field);
761 } else {
762 // No superclass was given in bounds.
763 // In this case, supertype is Object, erasure is first interface.
764 return ct.interfaces_field;
765 }
766 }
768 @Override
769 public List<Attribute.Compound> getAnnotationMirrors() {
770 return onlyTypeVariableAnnotations(owner.getRawTypeAttributes());
771 }
773 private List<Attribute.Compound> onlyTypeVariableAnnotations(
774 List<Attribute.TypeCompound> candidates) {
775 // Declaration annotations on TypeParameters are stored in type attributes
776 List<Attribute.Compound> res = List.nil();
777 for (Attribute.TypeCompound a : candidates) {
778 if (a.position.type == TargetType.CLASS_TYPE_PARAMETER ||
779 a.position.type == TargetType.METHOD_TYPE_PARAMETER)
780 res = res.prepend(a);
781 }
783 return res = res.reverse();
784 }
786 @Override
787 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
788 return v.visitTypeParameter(this, p);
789 }
790 }
792 /** A class for package symbols
793 */
794 public static class PackageSymbol extends TypeSymbol
795 implements PackageElement {
797 public Scope members_field;
798 public Name fullname;
799 public ClassSymbol package_info; // see bug 6443073
801 public PackageSymbol(Name name, Type type, Symbol owner) {
802 super(PCK, 0, name, type, owner);
803 this.members_field = null;
804 this.fullname = formFullName(name, owner);
805 }
807 public PackageSymbol(Name name, Symbol owner) {
808 this(name, null, owner);
809 this.type = new PackageType(this);
810 }
812 public String toString() {
813 return fullname.toString();
814 }
816 public Name getQualifiedName() {
817 return fullname;
818 }
820 public boolean isUnnamed() {
821 return name.isEmpty() && owner != null;
822 }
824 public Scope members() {
825 if (completer != null) complete();
826 return members_field;
827 }
829 public long flags() {
830 if (completer != null) complete();
831 return flags_field;
832 }
834 @Override
835 public List<Attribute.Compound> getRawAttributes() {
836 if (completer != null) complete();
837 if (package_info != null && package_info.completer != null) {
838 package_info.complete();
839 mergeAttributes();
840 }
841 return super.getRawAttributes();
842 }
844 private void mergeAttributes() {
845 if (annotations == null &&
846 package_info.annotations != null) {
847 annotations = new Annotations(this);
848 annotations.setAttributes(package_info.annotations);
849 }
850 }
852 /** A package "exists" if a type or package that exists has
853 * been seen within it.
854 */
855 public boolean exists() {
856 return (flags_field & EXISTS) != 0;
857 }
859 public ElementKind getKind() {
860 return ElementKind.PACKAGE;
861 }
863 public Symbol getEnclosingElement() {
864 return null;
865 }
867 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
868 return v.visitPackage(this, p);
869 }
871 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
872 return v.visitPackageSymbol(this, p);
873 }
874 }
876 /** A class for class symbols
877 */
878 public static class ClassSymbol extends TypeSymbol implements TypeElement {
880 /** a scope for all class members; variables, methods and inner classes
881 * type parameters are not part of this scope
882 */
883 public Scope members_field;
885 /** the fully qualified name of the class, i.e. pck.outer.inner.
886 * null for anonymous classes
887 */
888 public Name fullname;
890 /** the fully qualified name of the class after converting to flat
891 * representation, i.e. pck.outer$inner,
892 * set externally for local and anonymous classes
893 */
894 public Name flatname;
896 /** the sourcefile where the class came from
897 */
898 public JavaFileObject sourcefile;
900 /** the classfile from where to load this class
901 * this will have extension .class or .java
902 */
903 public JavaFileObject classfile;
905 /** the list of translated local classes (used for generating
906 * InnerClasses attribute)
907 */
908 public List<ClassSymbol> trans_local;
910 /** the constant pool of the class
911 */
912 public Pool pool;
914 public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
915 super(TYP, flags, name, type, owner);
916 this.members_field = null;
917 this.fullname = formFullName(name, owner);
918 this.flatname = formFlatName(name, owner);
919 this.sourcefile = null;
920 this.classfile = null;
921 this.pool = null;
922 }
924 public ClassSymbol(long flags, Name name, Symbol owner) {
925 this(
926 flags,
927 name,
928 new ClassType(Type.noType, null, null),
929 owner);
930 this.type.tsym = this;
931 }
933 /** The Java source which this symbol represents.
934 */
935 public String toString() {
936 return className();
937 }
939 public long flags() {
940 if (completer != null) complete();
941 return flags_field;
942 }
944 public Scope members() {
945 if (completer != null) complete();
946 return members_field;
947 }
949 @Override
950 public List<Attribute.Compound> getRawAttributes() {
951 if (completer != null) complete();
952 return super.getRawAttributes();
953 }
955 @Override
956 public List<Attribute.TypeCompound> getRawTypeAttributes() {
957 if (completer != null) complete();
958 return super.getRawTypeAttributes();
959 }
961 public Type erasure(Types types) {
962 if (erasure_field == null)
963 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
964 List.<Type>nil(), this);
965 return erasure_field;
966 }
968 public String className() {
969 if (name.isEmpty())
970 return
971 Log.getLocalizedString("anonymous.class", flatname);
972 else
973 return fullname.toString();
974 }
976 public Name getQualifiedName() {
977 return fullname;
978 }
980 public Name flatName() {
981 return flatname;
982 }
984 public boolean isSubClass(Symbol base, Types types) {
985 if (this == base) {
986 return true;
987 } else if ((base.flags() & INTERFACE) != 0) {
988 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
989 for (List<Type> is = types.interfaces(t);
990 is.nonEmpty();
991 is = is.tail)
992 if (is.head.tsym.isSubClass(base, types)) return true;
993 } else {
994 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
995 if (t.tsym == base) return true;
996 }
997 return false;
998 }
1000 /** Complete the elaboration of this symbol's definition.
1001 */
1002 public void complete() throws CompletionFailure {
1003 try {
1004 super.complete();
1005 } catch (CompletionFailure ex) {
1006 // quiet error recovery
1007 flags_field |= (PUBLIC|STATIC);
1008 this.type = new ErrorType(this, Type.noType);
1009 throw ex;
1010 }
1011 }
1013 public List<Type> getInterfaces() {
1014 complete();
1015 if (type instanceof ClassType) {
1016 ClassType t = (ClassType)type;
1017 if (t.interfaces_field == null) // FIXME: shouldn't be null
1018 t.interfaces_field = List.nil();
1019 if (t.all_interfaces_field != null)
1020 return Type.getModelTypes(t.all_interfaces_field);
1021 return t.interfaces_field;
1022 } else {
1023 return List.nil();
1024 }
1025 }
1027 public Type getSuperclass() {
1028 complete();
1029 if (type instanceof ClassType) {
1030 ClassType t = (ClassType)type;
1031 if (t.supertype_field == null) // FIXME: shouldn't be null
1032 t.supertype_field = Type.noType;
1033 // An interface has no superclass; its supertype is Object.
1034 return t.isInterface()
1035 ? Type.noType
1036 : t.supertype_field.getModelType();
1037 } else {
1038 return Type.noType;
1039 }
1040 }
1042 public ElementKind getKind() {
1043 long flags = flags();
1044 if ((flags & ANNOTATION) != 0)
1045 return ElementKind.ANNOTATION_TYPE;
1046 else if ((flags & INTERFACE) != 0)
1047 return ElementKind.INTERFACE;
1048 else if ((flags & ENUM) != 0)
1049 return ElementKind.ENUM;
1050 else
1051 return ElementKind.CLASS;
1052 }
1054 public NestingKind getNestingKind() {
1055 complete();
1056 if (owner.kind == PCK)
1057 return NestingKind.TOP_LEVEL;
1058 else if (name.isEmpty())
1059 return NestingKind.ANONYMOUS;
1060 else if (owner.kind == MTH)
1061 return NestingKind.LOCAL;
1062 else
1063 return NestingKind.MEMBER;
1064 }
1066 /**
1067 * Since this method works in terms of the runtime representation
1068 * of annotations, it should never be used by javac internally.
1069 */
1070 @Override
1071 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
1072 return JavacAnnoConstructs.getAnnotation(this, annoType);
1073 }
1075 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1076 return v.visitType(this, p);
1077 }
1079 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1080 return v.visitClassSymbol(this, p);
1081 }
1082 }
1085 /** A class for variable symbols
1086 */
1087 public static class VarSymbol extends Symbol implements VariableElement {
1089 /** The variable's declaration position.
1090 */
1091 public int pos = Position.NOPOS;
1093 /** The variable's address. Used for different purposes during
1094 * flow analysis, translation and code generation.
1095 * Flow analysis:
1096 * If this is a blank final or local variable, its sequence number.
1097 * Translation:
1098 * If this is a private field, its access number.
1099 * Code generation:
1100 * If this is a local variable, its logical slot number.
1101 */
1102 public int adr = -1;
1104 /** Construct a variable symbol, given its flags, name, type and owner.
1105 */
1106 public VarSymbol(long flags, Name name, Type type, Symbol owner) {
1107 super(VAR, flags, name, type, owner);
1108 }
1110 /** Clone this symbol with new owner.
1111 */
1112 public VarSymbol clone(Symbol newOwner) {
1113 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) {
1114 @Override
1115 public Symbol baseSymbol() {
1116 return VarSymbol.this;
1117 }
1118 };
1119 v.pos = pos;
1120 v.adr = adr;
1121 v.data = data;
1122 // System.out.println("clone " + v + " in " + newOwner);//DEBUG
1123 return v;
1124 }
1126 public String toString() {
1127 return name.toString();
1128 }
1130 public Symbol asMemberOf(Type site, Types types) {
1131 return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
1132 }
1134 public ElementKind getKind() {
1135 long flags = flags();
1136 if ((flags & PARAMETER) != 0) {
1137 if (isExceptionParameter())
1138 return ElementKind.EXCEPTION_PARAMETER;
1139 else
1140 return ElementKind.PARAMETER;
1141 } else if ((flags & ENUM) != 0) {
1142 return ElementKind.ENUM_CONSTANT;
1143 } else if (owner.kind == TYP || owner.kind == ERR) {
1144 return ElementKind.FIELD;
1145 } else if (isResourceVariable()) {
1146 return ElementKind.RESOURCE_VARIABLE;
1147 } else {
1148 return ElementKind.LOCAL_VARIABLE;
1149 }
1150 }
1152 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1153 return v.visitVariable(this, p);
1154 }
1156 public Object getConstantValue() { // Mirror API
1157 return Constants.decode(getConstValue(), type);
1158 }
1160 public void setLazyConstValue(final Env<AttrContext> env,
1161 final Attr attr,
1162 final JCTree.JCExpression initializer)
1163 {
1164 setData(new Callable<Object>() {
1165 public Object call() {
1166 return attr.attribLazyConstantValue(env, initializer, type);
1167 }
1168 });
1169 }
1171 /**
1172 * The variable's constant value, if this is a constant.
1173 * Before the constant value is evaluated, it points to an
1174 * initalizer environment. If this is not a constant, it can
1175 * be used for other stuff.
1176 */
1177 private Object data;
1179 public boolean isExceptionParameter() {
1180 return data == ElementKind.EXCEPTION_PARAMETER;
1181 }
1183 public boolean isResourceVariable() {
1184 return data == ElementKind.RESOURCE_VARIABLE;
1185 }
1187 public Object getConstValue() {
1188 // TODO: Consider if getConstValue and getConstantValue can be collapsed
1189 if (data == ElementKind.EXCEPTION_PARAMETER ||
1190 data == ElementKind.RESOURCE_VARIABLE) {
1191 return null;
1192 } else if (data instanceof Callable<?>) {
1193 // In this case, this is a final variable, with an as
1194 // yet unevaluated initializer.
1195 Callable<?> eval = (Callable<?>)data;
1196 data = null; // to make sure we don't evaluate this twice.
1197 try {
1198 data = eval.call();
1199 } catch (Exception ex) {
1200 throw new AssertionError(ex);
1201 }
1202 }
1203 return data;
1204 }
1206 public void setData(Object data) {
1207 Assert.check(!(data instanceof Env<?>), this);
1208 this.data = data;
1209 }
1211 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1212 return v.visitVarSymbol(this, p);
1213 }
1214 }
1216 /** A class for method symbols.
1217 */
1218 public static class MethodSymbol extends Symbol implements ExecutableElement {
1220 /** The code of the method. */
1221 public Code code = null;
1223 /** The extra (synthetic/mandated) parameters of the method. */
1224 public List<VarSymbol> extraParams = List.nil();
1226 /** The parameters of the method. */
1227 public List<VarSymbol> params = null;
1229 /** The names of the parameters */
1230 public List<Name> savedParameterNames;
1232 /** For an attribute field accessor, its default value if any.
1233 * The value is null if none appeared in the method
1234 * declaration.
1235 */
1236 public Attribute defaultValue = null;
1238 /** Construct a method symbol, given its flags, name, type and owner.
1239 */
1240 public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1241 super(MTH, flags, name, type, owner);
1242 if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name);
1243 }
1245 /** Clone this symbol with new owner.
1246 */
1247 public MethodSymbol clone(Symbol newOwner) {
1248 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) {
1249 @Override
1250 public Symbol baseSymbol() {
1251 return MethodSymbol.this;
1252 }
1253 };
1254 m.code = code;
1255 return m;
1256 }
1258 @Override
1259 public Set<Modifier> getModifiers() {
1260 long flags = flags();
1261 return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags);
1262 }
1264 /** The Java source which this symbol represents.
1265 */
1266 public String toString() {
1267 if ((flags() & BLOCK) != 0) {
1268 return owner.name.toString();
1269 } else {
1270 String s = (name == name.table.names.init)
1271 ? owner.name.toString()
1272 : name.toString();
1273 if (type != null) {
1274 if (type.hasTag(FORALL))
1275 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1276 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1277 }
1278 return s;
1279 }
1280 }
1282 public boolean isDynamic() {
1283 return false;
1284 }
1286 /** find a symbol that this (proxy method) symbol implements.
1287 * @param c The class whose members are searched for
1288 * implementations
1289 */
1290 public Symbol implemented(TypeSymbol c, Types types) {
1291 Symbol impl = null;
1292 for (List<Type> is = types.interfaces(c.type);
1293 impl == null && is.nonEmpty();
1294 is = is.tail) {
1295 TypeSymbol i = is.head.tsym;
1296 impl = implementedIn(i, types);
1297 if (impl == null)
1298 impl = implemented(i, types);
1299 }
1300 return impl;
1301 }
1303 public Symbol implementedIn(TypeSymbol c, Types types) {
1304 Symbol impl = null;
1305 for (Scope.Entry e = c.members().lookup(name);
1306 impl == null && e.scope != null;
1307 e = e.next()) {
1308 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
1309 // FIXME: I suspect the following requires a
1310 // subst() for a parametric return type.
1311 types.isSameType(type.getReturnType(),
1312 types.memberType(owner.type, e.sym).getReturnType())) {
1313 impl = e.sym;
1314 }
1315 }
1316 return impl;
1317 }
1319 /** Will the erasure of this method be considered by the VM to
1320 * override the erasure of the other when seen from class `origin'?
1321 */
1322 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1323 if (isConstructor() || _other.kind != MTH) return false;
1325 if (this == _other) return true;
1326 MethodSymbol other = (MethodSymbol)_other;
1328 // check for a direct implementation
1329 if (other.isOverridableIn((TypeSymbol)owner) &&
1330 types.asSuper(owner.type, other.owner) != null &&
1331 types.isSameType(erasure(types), other.erasure(types)))
1332 return true;
1334 // check for an inherited implementation
1335 return
1336 (flags() & ABSTRACT) == 0 &&
1337 other.isOverridableIn(origin) &&
1338 this.isMemberOf(origin, types) &&
1339 types.isSameType(erasure(types), other.erasure(types));
1340 }
1342 /** The implementation of this (abstract) symbol in class origin,
1343 * from the VM's point of view, null if method does not have an
1344 * implementation in class.
1345 * @param origin The class of which the implementation is a member.
1346 */
1347 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1348 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1349 for (Scope.Entry e = c.members().lookup(name);
1350 e.scope != null;
1351 e = e.next()) {
1352 if (e.sym.kind == MTH &&
1353 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
1354 return (MethodSymbol)e.sym;
1355 }
1356 }
1357 return null;
1358 }
1360 /** Does this symbol override `other' symbol, when both are seen as
1361 * members of class `origin'? It is assumed that _other is a member
1362 * of origin.
1363 *
1364 * It is assumed that both symbols have the same name. The static
1365 * modifier is ignored for this test.
1366 *
1367 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1368 */
1369 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1370 if (isConstructor() || _other.kind != MTH) return false;
1372 if (this == _other) return true;
1373 MethodSymbol other = (MethodSymbol)_other;
1375 // check for a direct implementation
1376 if (other.isOverridableIn((TypeSymbol)owner) &&
1377 types.asSuper(owner.type, other.owner) != null) {
1378 Type mt = types.memberType(owner.type, this);
1379 Type ot = types.memberType(owner.type, other);
1380 if (types.isSubSignature(mt, ot)) {
1381 if (!checkResult)
1382 return true;
1383 if (types.returnTypeSubstitutable(mt, ot))
1384 return true;
1385 }
1386 }
1388 // check for an inherited implementation
1389 if ((flags() & ABSTRACT) != 0 ||
1390 ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
1391 !other.isOverridableIn(origin) ||
1392 !this.isMemberOf(origin, types))
1393 return false;
1395 // assert types.asSuper(origin.type, other.owner) != null;
1396 Type mt = types.memberType(origin.type, this);
1397 Type ot = types.memberType(origin.type, other);
1398 return
1399 types.isSubSignature(mt, ot) &&
1400 (!checkResult || types.resultSubtype(mt, ot, types.noWarnings));
1401 }
1403 private boolean isOverridableIn(TypeSymbol origin) {
1404 // JLS 8.4.6.1
1405 switch ((int)(flags_field & Flags.AccessFlags)) {
1406 case Flags.PRIVATE:
1407 return false;
1408 case Flags.PUBLIC:
1409 return !this.owner.isInterface() ||
1410 (flags_field & STATIC) == 0;
1411 case Flags.PROTECTED:
1412 return (origin.flags() & INTERFACE) == 0;
1413 case 0:
1414 // for package private: can only override in the same
1415 // package
1416 return
1417 this.packge() == origin.packge() &&
1418 (origin.flags() & INTERFACE) == 0;
1419 default:
1420 return false;
1421 }
1422 }
1424 @Override
1425 public boolean isInheritedIn(Symbol clazz, Types types) {
1426 switch ((int)(flags_field & Flags.AccessFlags)) {
1427 case PUBLIC:
1428 return !this.owner.isInterface() ||
1429 clazz == owner ||
1430 (flags_field & STATIC) == 0;
1431 default:
1432 return super.isInheritedIn(clazz, types);
1433 }
1434 }
1436 /** The implementation of this (abstract) symbol in class origin;
1437 * null if none exists. Synthetic methods are not considered
1438 * as possible implementations.
1439 */
1440 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1441 return implementation(origin, types, checkResult, implementation_filter);
1442 }
1443 // where
1444 public static final Filter<Symbol> implementation_filter = new Filter<Symbol>() {
1445 public boolean accepts(Symbol s) {
1446 return s.kind == Kinds.MTH &&
1447 (s.flags() & SYNTHETIC) == 0;
1448 }
1449 };
1451 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
1452 MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
1453 if (res != null)
1454 return res;
1455 // if origin is derived from a raw type, we might have missed
1456 // an implementation because we do not know enough about instantiations.
1457 // in this case continue with the supertype as origin.
1458 if (types.isDerivedRaw(origin.type) && !origin.isInterface())
1459 return implementation(types.supertype(origin.type).tsym, types, checkResult);
1460 else
1461 return null;
1462 }
1464 public List<VarSymbol> params() {
1465 owner.complete();
1466 if (params == null) {
1467 // If ClassReader.saveParameterNames has been set true, then
1468 // savedParameterNames will be set to a list of names that
1469 // matches the types in type.getParameterTypes(). If any names
1470 // were not found in the class file, those names in the list will
1471 // be set to the empty name.
1472 // If ClassReader.saveParameterNames has been set false, then
1473 // savedParameterNames will be null.
1474 List<Name> paramNames = savedParameterNames;
1475 savedParameterNames = null;
1476 // discard the provided names if the list of names is the wrong size.
1477 if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) {
1478 paramNames = List.nil();
1479 }
1480 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
1481 List<Name> remaining = paramNames;
1482 // assert: remaining and paramNames are both empty or both
1483 // have same cardinality as type.getParameterTypes()
1484 int i = 0;
1485 for (Type t : type.getParameterTypes()) {
1486 Name paramName;
1487 if (remaining.isEmpty()) {
1488 // no names for any parameters available
1489 paramName = createArgName(i, paramNames);
1490 } else {
1491 paramName = remaining.head;
1492 remaining = remaining.tail;
1493 if (paramName.isEmpty()) {
1494 // no name for this specific parameter
1495 paramName = createArgName(i, paramNames);
1496 }
1497 }
1498 buf.append(new VarSymbol(PARAMETER, paramName, t, this));
1499 i++;
1500 }
1501 params = buf.toList();
1502 }
1503 return params;
1504 }
1506 // Create a name for the argument at position 'index' that is not in
1507 // the exclude list. In normal use, either no names will have been
1508 // provided, in which case the exclude list is empty, or all the names
1509 // will have been provided, in which case this method will not be called.
1510 private Name createArgName(int index, List<Name> exclude) {
1511 String prefix = "arg";
1512 while (true) {
1513 Name argName = name.table.fromString(prefix + index);
1514 if (!exclude.contains(argName))
1515 return argName;
1516 prefix += "$";
1517 }
1518 }
1520 public Symbol asMemberOf(Type site, Types types) {
1521 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1522 }
1524 public ElementKind getKind() {
1525 if (name == name.table.names.init)
1526 return ElementKind.CONSTRUCTOR;
1527 else if (name == name.table.names.clinit)
1528 return ElementKind.STATIC_INIT;
1529 else if ((flags() & BLOCK) != 0)
1530 return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT;
1531 else
1532 return ElementKind.METHOD;
1533 }
1535 public boolean isStaticOrInstanceInit() {
1536 return getKind() == ElementKind.STATIC_INIT ||
1537 getKind() == ElementKind.INSTANCE_INIT;
1538 }
1540 public Attribute getDefaultValue() {
1541 return defaultValue;
1542 }
1544 public List<VarSymbol> getParameters() {
1545 return params();
1546 }
1548 public boolean isVarArgs() {
1549 return (flags() & VARARGS) != 0;
1550 }
1552 public boolean isDefault() {
1553 return (flags() & DEFAULT) != 0;
1554 }
1556 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1557 return v.visitExecutable(this, p);
1558 }
1560 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1561 return v.visitMethodSymbol(this, p);
1562 }
1564 public Type getReceiverType() {
1565 return asType().getReceiverType();
1566 }
1568 public Type getReturnType() {
1569 return asType().getReturnType();
1570 }
1572 public List<Type> getThrownTypes() {
1573 return asType().getThrownTypes();
1574 }
1575 }
1577 /** A class for invokedynamic method calls.
1578 */
1579 public static class DynamicMethodSymbol extends MethodSymbol {
1581 public Object[] staticArgs;
1582 public Symbol bsm;
1583 public int bsmKind;
1585 public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
1586 super(0, name, type, owner);
1587 this.bsm = bsm;
1588 this.bsmKind = bsmKind;
1589 this.staticArgs = staticArgs;
1590 }
1592 @Override
1593 public boolean isDynamic() {
1594 return true;
1595 }
1596 }
1598 /** A class for predefined operators.
1599 */
1600 public static class OperatorSymbol extends MethodSymbol {
1602 public int opcode;
1604 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1605 super(PUBLIC | STATIC, name, type, owner);
1606 this.opcode = opcode;
1607 }
1609 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1610 return v.visitOperatorSymbol(this, p);
1611 }
1612 }
1614 /** Symbol completer interface.
1615 */
1616 public static interface Completer {
1617 void complete(Symbol sym) throws CompletionFailure;
1618 }
1620 public static class CompletionFailure extends RuntimeException {
1621 private static final long serialVersionUID = 0;
1622 public Symbol sym;
1624 /** A diagnostic object describing the failure
1625 */
1626 public JCDiagnostic diag;
1628 /** A localized string describing the failure.
1629 * @deprecated Use {@code getDetail()} or {@code getMessage()}
1630 */
1631 @Deprecated
1632 public String errmsg;
1634 public CompletionFailure(Symbol sym, String errmsg) {
1635 this.sym = sym;
1636 this.errmsg = errmsg;
1637 // this.printStackTrace();//DEBUG
1638 }
1640 public CompletionFailure(Symbol sym, JCDiagnostic diag) {
1641 this.sym = sym;
1642 this.diag = diag;
1643 // this.printStackTrace();//DEBUG
1644 }
1646 public JCDiagnostic getDiagnostic() {
1647 return diag;
1648 }
1650 @Override
1651 public String getMessage() {
1652 if (diag != null)
1653 return diag.getMessage(null);
1654 else
1655 return errmsg;
1656 }
1658 public Object getDetailValue() {
1659 return (diag != null ? diag : errmsg);
1660 }
1662 @Override
1663 public CompletionFailure initCause(Throwable cause) {
1664 super.initCause(cause);
1665 return this;
1666 }
1668 }
1670 /**
1671 * A visitor for symbols. A visitor is used to implement operations
1672 * (or relations) on symbols. Most common operations on types are
1673 * binary relations and this interface is designed for binary
1674 * relations, that is, operations on the form
1675 * Symbol × P → R.
1676 * <!-- In plain text: Type x P -> R -->
1677 *
1678 * @param <R> the return type of the operation implemented by this
1679 * visitor; use Void if no return type is needed.
1680 * @param <P> the type of the second argument (the first being the
1681 * symbol itself) of the operation implemented by this visitor; use
1682 * Void if a second argument is not needed.
1683 */
1684 public interface Visitor<R,P> {
1685 R visitClassSymbol(ClassSymbol s, P arg);
1686 R visitMethodSymbol(MethodSymbol s, P arg);
1687 R visitPackageSymbol(PackageSymbol s, P arg);
1688 R visitOperatorSymbol(OperatorSymbol s, P arg);
1689 R visitVarSymbol(VarSymbol s, P arg);
1690 R visitTypeSymbol(TypeSymbol s, P arg);
1691 R visitSymbol(Symbol s, P arg);
1692 }
1693 }