Mon, 12 Aug 2013 17:25:07 +0100
6537020: JCK tests: a compile-time error should be given in case of ambiguously imported fields (types, methods)
Summary: Hiding check does not support interface multiple inheritance
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;
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 private boolean hiddenIn(ClassSymbol clazz, Types types) {
467 Symbol sym = hiddenInInternal(clazz, types);
468 return sym != null && sym != this;
469 }
471 private Symbol hiddenInInternal(ClassSymbol c, Types types) {
472 Scope.Entry e = c.members().lookup(name);
473 while (e.scope != null) {
474 if (e.sym.kind == kind &&
475 (kind != MTH ||
476 (e.sym.flags() & STATIC) != 0 &&
477 types.isSubSignature(e.sym.type, type))) {
478 return e.sym;
479 }
480 e = e.next();
481 }
482 List<Symbol> hiddenSyms = List.nil();
483 for (Type st : types.interfaces(c.type).prepend(types.supertype(c.type))) {
484 if (st != null && (st.hasTag(CLASS))) {
485 Symbol sym = hiddenInInternal((ClassSymbol)st.tsym, types);
486 if (sym != null) {
487 hiddenSyms = hiddenSyms.prepend(hiddenInInternal((ClassSymbol)st.tsym, types));
488 }
489 }
490 }
491 return hiddenSyms.contains(this) ?
492 this :
493 (hiddenSyms.isEmpty() ? null : hiddenSyms.head);
494 }
496 /** Is this symbol inherited into a given class?
497 * PRE: If symbol's owner is a interface,
498 * it is already assumed that the interface is a superinterface
499 * of given class.
500 * @param clazz The class for which we want to establish membership.
501 * This must be a subclass of the member's owner.
502 */
503 public boolean isInheritedIn(Symbol clazz, Types types) {
504 switch ((int)(flags_field & Flags.AccessFlags)) {
505 default: // error recovery
506 case PUBLIC:
507 return true;
508 case PRIVATE:
509 return this.owner == clazz;
510 case PROTECTED:
511 // we model interfaces as extending Object
512 return (clazz.flags() & INTERFACE) == 0;
513 case 0:
514 PackageSymbol thisPackage = this.packge();
515 for (Symbol sup = clazz;
516 sup != null && sup != this.owner;
517 sup = types.supertype(sup.type).tsym) {
518 while (sup.type.hasTag(TYPEVAR))
519 sup = sup.type.getUpperBound().tsym;
520 if (sup.type.isErroneous())
521 return true; // error recovery
522 if ((sup.flags() & COMPOUND) != 0)
523 continue;
524 if (sup.packge() != thisPackage)
525 return false;
526 }
527 return (clazz.flags() & INTERFACE) == 0;
528 }
529 }
531 /** The (variable or method) symbol seen as a member of given
532 * class type`site' (this might change the symbol's type).
533 * This is used exclusively for producing diagnostics.
534 */
535 public Symbol asMemberOf(Type site, Types types) {
536 throw new AssertionError();
537 }
539 /** Does this method symbol override `other' symbol, when both are seen as
540 * members of class `origin'? It is assumed that _other is a member
541 * of origin.
542 *
543 * It is assumed that both symbols have the same name. The static
544 * modifier is ignored for this test.
545 *
546 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
547 */
548 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
549 return false;
550 }
552 /** Complete the elaboration of this symbol's definition.
553 */
554 public void complete() throws CompletionFailure {
555 if (completer != null) {
556 Completer c = completer;
557 completer = null;
558 c.complete(this);
559 }
560 }
562 /** True if the symbol represents an entity that exists.
563 */
564 public boolean exists() {
565 return true;
566 }
568 public Type asType() {
569 return type;
570 }
572 public Symbol getEnclosingElement() {
573 return owner;
574 }
576 public ElementKind getKind() {
577 return ElementKind.OTHER; // most unkind
578 }
580 public Set<Modifier> getModifiers() {
581 return Flags.asModifierSet(flags());
582 }
584 public Name getSimpleName() {
585 return name;
586 }
588 /**
589 * This is the implementation for {@code
590 * javax.lang.model.element.Element.getAnnotationMirrors()}.
591 */
592 @Override
593 public List<Attribute.Compound> getAnnotationMirrors() {
594 return getRawAttributes();
595 }
597 /**
598 * @deprecated this method should never be used by javac internally.
599 */
600 @Deprecated
601 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
602 return JavacAnnoConstructs.getAnnotation(this, annoType);
603 }
605 // This method is part of the javax.lang.model API, do not use this in javac code.
606 public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(Class<A> annoType) {
607 return JavacAnnoConstructs.getAnnotationsByType(this, annoType);
608 }
610 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
611 public java.util.List<Symbol> getEnclosedElements() {
612 return List.nil();
613 }
615 public List<TypeVariableSymbol> getTypeParameters() {
616 ListBuffer<TypeVariableSymbol> l = ListBuffer.lb();
617 for (Type t : type.getTypeArguments()) {
618 Assert.check(t.tsym.getKind() == ElementKind.TYPE_PARAMETER);
619 l.append((TypeVariableSymbol)t.tsym);
620 }
621 return l.toList();
622 }
624 public static class DelegatedSymbol<T extends Symbol> extends Symbol {
625 protected T other;
626 public DelegatedSymbol(T other) {
627 super(other.kind, other.flags_field, other.name, other.type, other.owner);
628 this.other = other;
629 }
630 public String toString() { return other.toString(); }
631 public Symbol location() { return other.location(); }
632 public Symbol location(Type site, Types types) { return other.location(site, types); }
633 public Symbol baseSymbol() { return other; }
634 public Type erasure(Types types) { return other.erasure(types); }
635 public Type externalType(Types types) { return other.externalType(types); }
636 public boolean isLocal() { return other.isLocal(); }
637 public boolean isConstructor() { return other.isConstructor(); }
638 public Name getQualifiedName() { return other.getQualifiedName(); }
639 public Name flatName() { return other.flatName(); }
640 public Scope members() { return other.members(); }
641 public boolean isInner() { return other.isInner(); }
642 public boolean hasOuterInstance() { return other.hasOuterInstance(); }
643 public ClassSymbol enclClass() { return other.enclClass(); }
644 public ClassSymbol outermostClass() { return other.outermostClass(); }
645 public PackageSymbol packge() { return other.packge(); }
646 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
647 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
648 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
649 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
650 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
651 public void complete() throws CompletionFailure { other.complete(); }
653 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
654 return other.accept(v, p);
655 }
657 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
658 return v.visitSymbol(other, p);
659 }
661 public T getUnderlyingSymbol() {
662 return other;
663 }
664 }
666 /** A base class for Symbols representing types.
667 */
668 public static abstract class TypeSymbol extends Symbol {
669 public TypeSymbol(int kind, long flags, Name name, Type type, Symbol owner) {
670 super(kind, flags, name, type, owner);
671 }
672 /** form a fully qualified name from a name and an owner
673 */
674 static public Name formFullName(Name name, Symbol owner) {
675 if (owner == null) return name;
676 if (((owner.kind != ERR)) &&
677 ((owner.kind & (VAR | MTH)) != 0
678 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
679 )) return name;
680 Name prefix = owner.getQualifiedName();
681 if (prefix == null || prefix == prefix.table.names.empty)
682 return name;
683 else return prefix.append('.', name);
684 }
686 /** form a fully qualified name from a name and an owner, after
687 * converting to flat representation
688 */
689 static public Name formFlatName(Name name, Symbol owner) {
690 if (owner == null ||
691 (owner.kind & (VAR | MTH)) != 0
692 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
693 ) return name;
694 char sep = owner.kind == TYP ? '$' : '.';
695 Name prefix = owner.flatName();
696 if (prefix == null || prefix == prefix.table.names.empty)
697 return name;
698 else return prefix.append(sep, name);
699 }
701 /**
702 * A total ordering between type symbols that refines the
703 * class inheritance graph.
704 *
705 * Typevariables always precede other kinds of symbols.
706 */
707 public final boolean precedes(TypeSymbol that, Types types) {
708 if (this == that)
709 return false;
710 if (type.hasTag(that.type.getTag())) {
711 if (type.hasTag(CLASS)) {
712 return
713 types.rank(that.type) < types.rank(this.type) ||
714 types.rank(that.type) == types.rank(this.type) &&
715 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
716 } else if (type.hasTag(TYPEVAR)) {
717 return types.isSubtype(this.type, that.type);
718 }
719 }
720 return type.hasTag(TYPEVAR);
721 }
723 @Override
724 public java.util.List<Symbol> getEnclosedElements() {
725 List<Symbol> list = List.nil();
726 if (kind == TYP && type.hasTag(TYPEVAR)) {
727 return list;
728 }
729 for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
730 if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this)
731 list = list.prepend(e.sym);
732 }
733 return list;
734 }
736 @Override
737 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
738 return v.visitTypeSymbol(this, p);
739 }
740 }
742 /**
743 * Type variables are represented by instances of this class.
744 */
745 public static class TypeVariableSymbol
746 extends TypeSymbol implements TypeParameterElement {
748 public TypeVariableSymbol(long flags, Name name, Type type, Symbol owner) {
749 super(TYP, flags, name, type, owner);
750 }
752 public ElementKind getKind() {
753 return ElementKind.TYPE_PARAMETER;
754 }
756 @Override
757 public Symbol getGenericElement() {
758 return owner;
759 }
761 public List<Type> getBounds() {
762 TypeVar t = (TypeVar)type;
763 Type bound = t.getUpperBound();
764 if (!bound.isCompound())
765 return List.of(bound);
766 ClassType ct = (ClassType)bound;
767 if (!ct.tsym.erasure_field.isInterface()) {
768 return ct.interfaces_field.prepend(ct.supertype_field);
769 } else {
770 // No superclass was given in bounds.
771 // In this case, supertype is Object, erasure is first interface.
772 return ct.interfaces_field;
773 }
774 }
776 @Override
777 public List<Attribute.Compound> getAnnotationMirrors() {
778 return onlyTypeVariableAnnotations(owner.getRawTypeAttributes());
779 }
781 private List<Attribute.Compound> onlyTypeVariableAnnotations(
782 List<Attribute.TypeCompound> candidates) {
783 // Declaration annotations on TypeParameters are stored in type attributes
784 List<Attribute.Compound> res = List.nil();
785 for (Attribute.TypeCompound a : candidates) {
786 if (a.position.type == TargetType.CLASS_TYPE_PARAMETER ||
787 a.position.type == TargetType.METHOD_TYPE_PARAMETER)
788 res = res.prepend(a);
789 }
791 return res = res.reverse();
792 }
794 @Override
795 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
796 return v.visitTypeParameter(this, p);
797 }
798 }
800 /** A class for package symbols
801 */
802 public static class PackageSymbol extends TypeSymbol
803 implements PackageElement {
805 public Scope members_field;
806 public Name fullname;
807 public ClassSymbol package_info; // see bug 6443073
809 public PackageSymbol(Name name, Type type, Symbol owner) {
810 super(PCK, 0, name, type, owner);
811 this.members_field = null;
812 this.fullname = formFullName(name, owner);
813 }
815 public PackageSymbol(Name name, Symbol owner) {
816 this(name, null, owner);
817 this.type = new PackageType(this);
818 }
820 public String toString() {
821 return fullname.toString();
822 }
824 public Name getQualifiedName() {
825 return fullname;
826 }
828 public boolean isUnnamed() {
829 return name.isEmpty() && owner != null;
830 }
832 public Scope members() {
833 if (completer != null) complete();
834 return members_field;
835 }
837 public long flags() {
838 if (completer != null) complete();
839 return flags_field;
840 }
842 @Override
843 public List<Attribute.Compound> getRawAttributes() {
844 if (completer != null) complete();
845 if (package_info != null && package_info.completer != null) {
846 package_info.complete();
847 mergeAttributes();
848 }
849 return super.getRawAttributes();
850 }
852 private void mergeAttributes() {
853 if (annotations == null &&
854 package_info.annotations != null) {
855 annotations = new Annotations(this);
856 annotations.setAttributes(package_info.annotations);
857 }
858 }
860 /** A package "exists" if a type or package that exists has
861 * been seen within it.
862 */
863 public boolean exists() {
864 return (flags_field & EXISTS) != 0;
865 }
867 public ElementKind getKind() {
868 return ElementKind.PACKAGE;
869 }
871 public Symbol getEnclosingElement() {
872 return null;
873 }
875 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
876 return v.visitPackage(this, p);
877 }
879 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
880 return v.visitPackageSymbol(this, p);
881 }
882 }
884 /** A class for class symbols
885 */
886 public static class ClassSymbol extends TypeSymbol implements TypeElement {
888 /** a scope for all class members; variables, methods and inner classes
889 * type parameters are not part of this scope
890 */
891 public Scope members_field;
893 /** the fully qualified name of the class, i.e. pck.outer.inner.
894 * null for anonymous classes
895 */
896 public Name fullname;
898 /** the fully qualified name of the class after converting to flat
899 * representation, i.e. pck.outer$inner,
900 * set externally for local and anonymous classes
901 */
902 public Name flatname;
904 /** the sourcefile where the class came from
905 */
906 public JavaFileObject sourcefile;
908 /** the classfile from where to load this class
909 * this will have extension .class or .java
910 */
911 public JavaFileObject classfile;
913 /** the list of translated local classes (used for generating
914 * InnerClasses attribute)
915 */
916 public List<ClassSymbol> trans_local;
918 /** the constant pool of the class
919 */
920 public Pool pool;
922 public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
923 super(TYP, flags, name, type, owner);
924 this.members_field = null;
925 this.fullname = formFullName(name, owner);
926 this.flatname = formFlatName(name, owner);
927 this.sourcefile = null;
928 this.classfile = null;
929 this.pool = null;
930 }
932 public ClassSymbol(long flags, Name name, Symbol owner) {
933 this(
934 flags,
935 name,
936 new ClassType(Type.noType, null, null),
937 owner);
938 this.type.tsym = this;
939 }
941 /** The Java source which this symbol represents.
942 */
943 public String toString() {
944 return className();
945 }
947 public long flags() {
948 if (completer != null) complete();
949 return flags_field;
950 }
952 public Scope members() {
953 if (completer != null) complete();
954 return members_field;
955 }
957 @Override
958 public List<Attribute.Compound> getRawAttributes() {
959 if (completer != null) complete();
960 return super.getRawAttributes();
961 }
963 @Override
964 public List<Attribute.TypeCompound> getRawTypeAttributes() {
965 if (completer != null) complete();
966 return super.getRawTypeAttributes();
967 }
969 public Type erasure(Types types) {
970 if (erasure_field == null)
971 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
972 List.<Type>nil(), this);
973 return erasure_field;
974 }
976 public String className() {
977 if (name.isEmpty())
978 return
979 Log.getLocalizedString("anonymous.class", flatname);
980 else
981 return fullname.toString();
982 }
984 public Name getQualifiedName() {
985 return fullname;
986 }
988 public Name flatName() {
989 return flatname;
990 }
992 public boolean isSubClass(Symbol base, Types types) {
993 if (this == base) {
994 return true;
995 } else if ((base.flags() & INTERFACE) != 0) {
996 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
997 for (List<Type> is = types.interfaces(t);
998 is.nonEmpty();
999 is = is.tail)
1000 if (is.head.tsym.isSubClass(base, types)) return true;
1001 } else {
1002 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1003 if (t.tsym == base) return true;
1004 }
1005 return false;
1006 }
1008 /** Complete the elaboration of this symbol's definition.
1009 */
1010 public void complete() throws CompletionFailure {
1011 try {
1012 super.complete();
1013 } catch (CompletionFailure ex) {
1014 // quiet error recovery
1015 flags_field |= (PUBLIC|STATIC);
1016 this.type = new ErrorType(this, Type.noType);
1017 throw ex;
1018 }
1019 }
1021 public List<Type> getInterfaces() {
1022 complete();
1023 if (type instanceof ClassType) {
1024 ClassType t = (ClassType)type;
1025 if (t.interfaces_field == null) // FIXME: shouldn't be null
1026 t.interfaces_field = List.nil();
1027 if (t.all_interfaces_field != null)
1028 return Type.getModelTypes(t.all_interfaces_field);
1029 return t.interfaces_field;
1030 } else {
1031 return List.nil();
1032 }
1033 }
1035 public Type getSuperclass() {
1036 complete();
1037 if (type instanceof ClassType) {
1038 ClassType t = (ClassType)type;
1039 if (t.supertype_field == null) // FIXME: shouldn't be null
1040 t.supertype_field = Type.noType;
1041 // An interface has no superclass; its supertype is Object.
1042 return t.isInterface()
1043 ? Type.noType
1044 : t.supertype_field.getModelType();
1045 } else {
1046 return Type.noType;
1047 }
1048 }
1050 public ElementKind getKind() {
1051 long flags = flags();
1052 if ((flags & ANNOTATION) != 0)
1053 return ElementKind.ANNOTATION_TYPE;
1054 else if ((flags & INTERFACE) != 0)
1055 return ElementKind.INTERFACE;
1056 else if ((flags & ENUM) != 0)
1057 return ElementKind.ENUM;
1058 else
1059 return ElementKind.CLASS;
1060 }
1062 public NestingKind getNestingKind() {
1063 complete();
1064 if (owner.kind == PCK)
1065 return NestingKind.TOP_LEVEL;
1066 else if (name.isEmpty())
1067 return NestingKind.ANONYMOUS;
1068 else if (owner.kind == MTH)
1069 return NestingKind.LOCAL;
1070 else
1071 return NestingKind.MEMBER;
1072 }
1074 /**
1075 * Since this method works in terms of the runtime representation
1076 * of annotations, it should never be used by javac internally.
1077 */
1078 @Override
1079 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) {
1080 return JavacAnnoConstructs.getAnnotation(this, annoType);
1081 }
1083 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1084 return v.visitType(this, p);
1085 }
1087 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1088 return v.visitClassSymbol(this, p);
1089 }
1090 }
1093 /** A class for variable symbols
1094 */
1095 public static class VarSymbol extends Symbol implements VariableElement {
1097 /** The variable's declaration position.
1098 */
1099 public int pos = Position.NOPOS;
1101 /** The variable's address. Used for different purposes during
1102 * flow analysis, translation and code generation.
1103 * Flow analysis:
1104 * If this is a blank final or local variable, its sequence number.
1105 * Translation:
1106 * If this is a private field, its access number.
1107 * Code generation:
1108 * If this is a local variable, its logical slot number.
1109 */
1110 public int adr = -1;
1112 /** Construct a variable symbol, given its flags, name, type and owner.
1113 */
1114 public VarSymbol(long flags, Name name, Type type, Symbol owner) {
1115 super(VAR, flags, name, type, owner);
1116 }
1118 /** Clone this symbol with new owner.
1119 */
1120 public VarSymbol clone(Symbol newOwner) {
1121 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) {
1122 @Override
1123 public Symbol baseSymbol() {
1124 return VarSymbol.this;
1125 }
1126 };
1127 v.pos = pos;
1128 v.adr = adr;
1129 v.data = data;
1130 // System.out.println("clone " + v + " in " + newOwner);//DEBUG
1131 return v;
1132 }
1134 public String toString() {
1135 return name.toString();
1136 }
1138 public Symbol asMemberOf(Type site, Types types) {
1139 return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
1140 }
1142 public ElementKind getKind() {
1143 long flags = flags();
1144 if ((flags & PARAMETER) != 0) {
1145 if (isExceptionParameter())
1146 return ElementKind.EXCEPTION_PARAMETER;
1147 else
1148 return ElementKind.PARAMETER;
1149 } else if ((flags & ENUM) != 0) {
1150 return ElementKind.ENUM_CONSTANT;
1151 } else if (owner.kind == TYP || owner.kind == ERR) {
1152 return ElementKind.FIELD;
1153 } else if (isResourceVariable()) {
1154 return ElementKind.RESOURCE_VARIABLE;
1155 } else {
1156 return ElementKind.LOCAL_VARIABLE;
1157 }
1158 }
1160 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1161 return v.visitVariable(this, p);
1162 }
1164 public Object getConstantValue() { // Mirror API
1165 return Constants.decode(getConstValue(), type);
1166 }
1168 public void setLazyConstValue(final Env<AttrContext> env,
1169 final Attr attr,
1170 final JCTree.JCExpression initializer)
1171 {
1172 setData(new Callable<Object>() {
1173 public Object call() {
1174 return attr.attribLazyConstantValue(env, initializer, type);
1175 }
1176 });
1177 }
1179 /**
1180 * The variable's constant value, if this is a constant.
1181 * Before the constant value is evaluated, it points to an
1182 * initalizer environment. If this is not a constant, it can
1183 * be used for other stuff.
1184 */
1185 private Object data;
1187 public boolean isExceptionParameter() {
1188 return data == ElementKind.EXCEPTION_PARAMETER;
1189 }
1191 public boolean isResourceVariable() {
1192 return data == ElementKind.RESOURCE_VARIABLE;
1193 }
1195 public Object getConstValue() {
1196 // TODO: Consider if getConstValue and getConstantValue can be collapsed
1197 if (data == ElementKind.EXCEPTION_PARAMETER ||
1198 data == ElementKind.RESOURCE_VARIABLE) {
1199 return null;
1200 } else if (data instanceof Callable<?>) {
1201 // In this case, this is a final variable, with an as
1202 // yet unevaluated initializer.
1203 Callable<?> eval = (Callable<?>)data;
1204 data = null; // to make sure we don't evaluate this twice.
1205 try {
1206 data = eval.call();
1207 } catch (Exception ex) {
1208 throw new AssertionError(ex);
1209 }
1210 }
1211 return data;
1212 }
1214 public void setData(Object data) {
1215 Assert.check(!(data instanceof Env<?>), this);
1216 this.data = data;
1217 }
1219 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1220 return v.visitVarSymbol(this, p);
1221 }
1222 }
1224 /** A class for method symbols.
1225 */
1226 public static class MethodSymbol extends Symbol implements ExecutableElement {
1228 /** The code of the method. */
1229 public Code code = null;
1231 /** The extra (synthetic/mandated) parameters of the method. */
1232 public List<VarSymbol> extraParams = List.nil();
1234 /** The parameters of the method. */
1235 public List<VarSymbol> params = null;
1237 /** The names of the parameters */
1238 public List<Name> savedParameterNames;
1240 /** For an attribute field accessor, its default value if any.
1241 * The value is null if none appeared in the method
1242 * declaration.
1243 */
1244 public Attribute defaultValue = null;
1246 /** Construct a method symbol, given its flags, name, type and owner.
1247 */
1248 public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1249 super(MTH, flags, name, type, owner);
1250 if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name);
1251 }
1253 /** Clone this symbol with new owner.
1254 */
1255 public MethodSymbol clone(Symbol newOwner) {
1256 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) {
1257 @Override
1258 public Symbol baseSymbol() {
1259 return MethodSymbol.this;
1260 }
1261 };
1262 m.code = code;
1263 return m;
1264 }
1266 @Override
1267 public Set<Modifier> getModifiers() {
1268 long flags = flags();
1269 return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags);
1270 }
1272 /** The Java source which this symbol represents.
1273 */
1274 public String toString() {
1275 if ((flags() & BLOCK) != 0) {
1276 return owner.name.toString();
1277 } else {
1278 String s = (name == name.table.names.init)
1279 ? owner.name.toString()
1280 : name.toString();
1281 if (type != null) {
1282 if (type.hasTag(FORALL))
1283 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1284 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1285 }
1286 return s;
1287 }
1288 }
1290 public boolean isDynamic() {
1291 return false;
1292 }
1294 /** find a symbol that this (proxy method) symbol implements.
1295 * @param c The class whose members are searched for
1296 * implementations
1297 */
1298 public Symbol implemented(TypeSymbol c, Types types) {
1299 Symbol impl = null;
1300 for (List<Type> is = types.interfaces(c.type);
1301 impl == null && is.nonEmpty();
1302 is = is.tail) {
1303 TypeSymbol i = is.head.tsym;
1304 impl = implementedIn(i, types);
1305 if (impl == null)
1306 impl = implemented(i, types);
1307 }
1308 return impl;
1309 }
1311 public Symbol implementedIn(TypeSymbol c, Types types) {
1312 Symbol impl = null;
1313 for (Scope.Entry e = c.members().lookup(name);
1314 impl == null && e.scope != null;
1315 e = e.next()) {
1316 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
1317 // FIXME: I suspect the following requires a
1318 // subst() for a parametric return type.
1319 types.isSameType(type.getReturnType(),
1320 types.memberType(owner.type, e.sym).getReturnType())) {
1321 impl = e.sym;
1322 }
1323 }
1324 return impl;
1325 }
1327 /** Will the erasure of this method be considered by the VM to
1328 * override the erasure of the other when seen from class `origin'?
1329 */
1330 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1331 if (isConstructor() || _other.kind != MTH) return false;
1333 if (this == _other) return true;
1334 MethodSymbol other = (MethodSymbol)_other;
1336 // check for a direct implementation
1337 if (other.isOverridableIn((TypeSymbol)owner) &&
1338 types.asSuper(owner.type, other.owner) != null &&
1339 types.isSameType(erasure(types), other.erasure(types)))
1340 return true;
1342 // check for an inherited implementation
1343 return
1344 (flags() & ABSTRACT) == 0 &&
1345 other.isOverridableIn(origin) &&
1346 this.isMemberOf(origin, types) &&
1347 types.isSameType(erasure(types), other.erasure(types));
1348 }
1350 /** The implementation of this (abstract) symbol in class origin,
1351 * from the VM's point of view, null if method does not have an
1352 * implementation in class.
1353 * @param origin The class of which the implementation is a member.
1354 */
1355 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1356 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1357 for (Scope.Entry e = c.members().lookup(name);
1358 e.scope != null;
1359 e = e.next()) {
1360 if (e.sym.kind == MTH &&
1361 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
1362 return (MethodSymbol)e.sym;
1363 }
1364 }
1365 return null;
1366 }
1368 /** Does this symbol override `other' symbol, when both are seen as
1369 * members of class `origin'? It is assumed that _other is a member
1370 * of origin.
1371 *
1372 * It is assumed that both symbols have the same name. The static
1373 * modifier is ignored for this test.
1374 *
1375 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1376 */
1377 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1378 if (isConstructor() || _other.kind != MTH) return false;
1380 if (this == _other) return true;
1381 MethodSymbol other = (MethodSymbol)_other;
1383 // check for a direct implementation
1384 if (other.isOverridableIn((TypeSymbol)owner) &&
1385 types.asSuper(owner.type, other.owner) != null) {
1386 Type mt = types.memberType(owner.type, this);
1387 Type ot = types.memberType(owner.type, other);
1388 if (types.isSubSignature(mt, ot)) {
1389 if (!checkResult)
1390 return true;
1391 if (types.returnTypeSubstitutable(mt, ot))
1392 return true;
1393 }
1394 }
1396 // check for an inherited implementation
1397 if ((flags() & ABSTRACT) != 0 ||
1398 ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
1399 !other.isOverridableIn(origin) ||
1400 !this.isMemberOf(origin, types))
1401 return false;
1403 // assert types.asSuper(origin.type, other.owner) != null;
1404 Type mt = types.memberType(origin.type, this);
1405 Type ot = types.memberType(origin.type, other);
1406 return
1407 types.isSubSignature(mt, ot) &&
1408 (!checkResult || types.resultSubtype(mt, ot, types.noWarnings));
1409 }
1411 private boolean isOverridableIn(TypeSymbol origin) {
1412 // JLS 8.4.6.1
1413 switch ((int)(flags_field & Flags.AccessFlags)) {
1414 case Flags.PRIVATE:
1415 return false;
1416 case Flags.PUBLIC:
1417 return !this.owner.isInterface() ||
1418 (flags_field & STATIC) == 0;
1419 case Flags.PROTECTED:
1420 return (origin.flags() & INTERFACE) == 0;
1421 case 0:
1422 // for package private: can only override in the same
1423 // package
1424 return
1425 this.packge() == origin.packge() &&
1426 (origin.flags() & INTERFACE) == 0;
1427 default:
1428 return false;
1429 }
1430 }
1432 @Override
1433 public boolean isInheritedIn(Symbol clazz, Types types) {
1434 switch ((int)(flags_field & Flags.AccessFlags)) {
1435 case PUBLIC:
1436 return !this.owner.isInterface() ||
1437 clazz == owner ||
1438 (flags_field & STATIC) == 0;
1439 default:
1440 return super.isInheritedIn(clazz, types);
1441 }
1442 }
1444 /** The implementation of this (abstract) symbol in class origin;
1445 * null if none exists. Synthetic methods are not considered
1446 * as possible implementations.
1447 */
1448 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1449 return implementation(origin, types, checkResult, implementation_filter);
1450 }
1451 // where
1452 public static final Filter<Symbol> implementation_filter = new Filter<Symbol>() {
1453 public boolean accepts(Symbol s) {
1454 return s.kind == Kinds.MTH &&
1455 (s.flags() & SYNTHETIC) == 0;
1456 }
1457 };
1459 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
1460 MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
1461 if (res != null)
1462 return res;
1463 // if origin is derived from a raw type, we might have missed
1464 // an implementation because we do not know enough about instantiations.
1465 // in this case continue with the supertype as origin.
1466 if (types.isDerivedRaw(origin.type) && !origin.isInterface())
1467 return implementation(types.supertype(origin.type).tsym, types, checkResult);
1468 else
1469 return null;
1470 }
1472 public List<VarSymbol> params() {
1473 owner.complete();
1474 if (params == null) {
1475 // If ClassReader.saveParameterNames has been set true, then
1476 // savedParameterNames will be set to a list of names that
1477 // matches the types in type.getParameterTypes(). If any names
1478 // were not found in the class file, those names in the list will
1479 // be set to the empty name.
1480 // If ClassReader.saveParameterNames has been set false, then
1481 // savedParameterNames will be null.
1482 List<Name> paramNames = savedParameterNames;
1483 savedParameterNames = null;
1484 // discard the provided names if the list of names is the wrong size.
1485 if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) {
1486 paramNames = List.nil();
1487 }
1488 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
1489 List<Name> remaining = paramNames;
1490 // assert: remaining and paramNames are both empty or both
1491 // have same cardinality as type.getParameterTypes()
1492 int i = 0;
1493 for (Type t : type.getParameterTypes()) {
1494 Name paramName;
1495 if (remaining.isEmpty()) {
1496 // no names for any parameters available
1497 paramName = createArgName(i, paramNames);
1498 } else {
1499 paramName = remaining.head;
1500 remaining = remaining.tail;
1501 if (paramName.isEmpty()) {
1502 // no name for this specific parameter
1503 paramName = createArgName(i, paramNames);
1504 }
1505 }
1506 buf.append(new VarSymbol(PARAMETER, paramName, t, this));
1507 i++;
1508 }
1509 params = buf.toList();
1510 }
1511 return params;
1512 }
1514 // Create a name for the argument at position 'index' that is not in
1515 // the exclude list. In normal use, either no names will have been
1516 // provided, in which case the exclude list is empty, or all the names
1517 // will have been provided, in which case this method will not be called.
1518 private Name createArgName(int index, List<Name> exclude) {
1519 String prefix = "arg";
1520 while (true) {
1521 Name argName = name.table.fromString(prefix + index);
1522 if (!exclude.contains(argName))
1523 return argName;
1524 prefix += "$";
1525 }
1526 }
1528 public Symbol asMemberOf(Type site, Types types) {
1529 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1530 }
1532 public ElementKind getKind() {
1533 if (name == name.table.names.init)
1534 return ElementKind.CONSTRUCTOR;
1535 else if (name == name.table.names.clinit)
1536 return ElementKind.STATIC_INIT;
1537 else if ((flags() & BLOCK) != 0)
1538 return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT;
1539 else
1540 return ElementKind.METHOD;
1541 }
1543 public boolean isStaticOrInstanceInit() {
1544 return getKind() == ElementKind.STATIC_INIT ||
1545 getKind() == ElementKind.INSTANCE_INIT;
1546 }
1548 public Attribute getDefaultValue() {
1549 return defaultValue;
1550 }
1552 public List<VarSymbol> getParameters() {
1553 return params();
1554 }
1556 public boolean isVarArgs() {
1557 return (flags() & VARARGS) != 0;
1558 }
1560 public boolean isDefault() {
1561 return (flags() & DEFAULT) != 0;
1562 }
1564 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1565 return v.visitExecutable(this, p);
1566 }
1568 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1569 return v.visitMethodSymbol(this, p);
1570 }
1572 public Type getReceiverType() {
1573 return asType().getReceiverType();
1574 }
1576 public Type getReturnType() {
1577 return asType().getReturnType();
1578 }
1580 public List<Type> getThrownTypes() {
1581 return asType().getThrownTypes();
1582 }
1583 }
1585 /** A class for invokedynamic method calls.
1586 */
1587 public static class DynamicMethodSymbol extends MethodSymbol {
1589 public Object[] staticArgs;
1590 public Symbol bsm;
1591 public int bsmKind;
1593 public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
1594 super(0, name, type, owner);
1595 this.bsm = bsm;
1596 this.bsmKind = bsmKind;
1597 this.staticArgs = staticArgs;
1598 }
1600 @Override
1601 public boolean isDynamic() {
1602 return true;
1603 }
1604 }
1606 /** A class for predefined operators.
1607 */
1608 public static class OperatorSymbol extends MethodSymbol {
1610 public int opcode;
1612 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1613 super(PUBLIC | STATIC, name, type, owner);
1614 this.opcode = opcode;
1615 }
1617 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1618 return v.visitOperatorSymbol(this, p);
1619 }
1620 }
1622 /** Symbol completer interface.
1623 */
1624 public static interface Completer {
1625 void complete(Symbol sym) throws CompletionFailure;
1626 }
1628 public static class CompletionFailure extends RuntimeException {
1629 private static final long serialVersionUID = 0;
1630 public Symbol sym;
1632 /** A diagnostic object describing the failure
1633 */
1634 public JCDiagnostic diag;
1636 /** A localized string describing the failure.
1637 * @deprecated Use {@code getDetail()} or {@code getMessage()}
1638 */
1639 @Deprecated
1640 public String errmsg;
1642 public CompletionFailure(Symbol sym, String errmsg) {
1643 this.sym = sym;
1644 this.errmsg = errmsg;
1645 // this.printStackTrace();//DEBUG
1646 }
1648 public CompletionFailure(Symbol sym, JCDiagnostic diag) {
1649 this.sym = sym;
1650 this.diag = diag;
1651 // this.printStackTrace();//DEBUG
1652 }
1654 public JCDiagnostic getDiagnostic() {
1655 return diag;
1656 }
1658 @Override
1659 public String getMessage() {
1660 if (diag != null)
1661 return diag.getMessage(null);
1662 else
1663 return errmsg;
1664 }
1666 public Object getDetailValue() {
1667 return (diag != null ? diag : errmsg);
1668 }
1670 @Override
1671 public CompletionFailure initCause(Throwable cause) {
1672 super.initCause(cause);
1673 return this;
1674 }
1676 }
1678 /**
1679 * A visitor for symbols. A visitor is used to implement operations
1680 * (or relations) on symbols. Most common operations on types are
1681 * binary relations and this interface is designed for binary
1682 * relations, that is, operations on the form
1683 * Symbol × P → R.
1684 * <!-- In plain text: Type x P -> R -->
1685 *
1686 * @param <R> the return type of the operation implemented by this
1687 * visitor; use Void if no return type is needed.
1688 * @param <P> the type of the second argument (the first being the
1689 * symbol itself) of the operation implemented by this visitor; use
1690 * Void if a second argument is not needed.
1691 */
1692 public interface Visitor<R,P> {
1693 R visitClassSymbol(ClassSymbol s, P arg);
1694 R visitMethodSymbol(MethodSymbol s, P arg);
1695 R visitPackageSymbol(PackageSymbol s, P arg);
1696 R visitOperatorSymbol(OperatorSymbol s, P arg);
1697 R visitVarSymbol(VarSymbol s, P arg);
1698 R visitTypeSymbol(TypeSymbol s, P arg);
1699 R visitSymbol(Symbol s, P arg);
1700 }
1701 }