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