Thu, 06 Feb 2014 21:11:27 +0000
8030855: Default methods should be visible under source previous to 8
Reviewed-by: jjg, dlsmith
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.lang.annotation.Annotation;
29 import java.lang.annotation.Inherited;
30 import java.util.Set;
31 import java.util.concurrent.Callable;
33 import javax.lang.model.element.*;
34 import javax.tools.JavaFileObject;
36 import com.sun.tools.javac.code.Type.*;
37 import com.sun.tools.javac.comp.Annotate;
38 import com.sun.tools.javac.comp.Attr;
39 import com.sun.tools.javac.comp.AttrContext;
40 import com.sun.tools.javac.comp.Env;
41 import com.sun.tools.javac.jvm.*;
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 extends AnnoConstruct implements Element {
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 * SymbolMetadata. The SymbolMetadata instance is NOT immutable.
102 */
103 protected SymbolMetadata metadata;
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 (metadata == null)
112 ? List.<Attribute.Compound>nil()
113 : metadata.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 (metadata == null)
122 ? List.<Attribute.TypeCompound>nil()
123 : metadata.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 metadata == null ? false : metadata.pendingCompletion();
136 }
138 public void appendAttributes(List<Attribute.Compound> l) {
139 if (l.nonEmpty()) {
140 initedMetadata().append(l);
141 }
142 }
144 public void appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
145 if (l.nonEmpty()) {
146 initedMetadata().appendClassInitTypeAttributes(l);
147 }
148 }
150 public void appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
151 if (l.nonEmpty()) {
152 initedMetadata().appendInitTypeAttributes(l);
153 }
154 }
156 public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) {
157 initedMetadata().appendTypeAttributesWithCompletion(ctx);
158 }
160 public void appendUniqueTypeAttributes(List<Attribute.TypeCompound> l) {
161 if (l.nonEmpty()) {
162 initedMetadata().appendUniqueTypes(l);
163 }
164 }
166 public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
167 return (metadata == null)
168 ? List.<Attribute.TypeCompound>nil()
169 : metadata.getClassInitTypeAttributes();
170 }
172 public List<Attribute.TypeCompound> getInitTypeAttributes() {
173 return (metadata == null)
174 ? List.<Attribute.TypeCompound>nil()
175 : metadata.getInitTypeAttributes();
176 }
178 public List<Attribute.Compound> getDeclarationAttributes() {
179 return (metadata == null)
180 ? List.<Attribute.Compound>nil()
181 : metadata.getDeclarationAttributes();
182 }
184 public boolean hasAnnotations() {
185 return (metadata != null && !metadata.isEmpty());
186 }
188 public boolean hasTypeAnnotations() {
189 return (metadata != null && !metadata.isTypesEmpty());
190 }
192 public void prependAttributes(List<Attribute.Compound> l) {
193 if (l.nonEmpty()) {
194 initedMetadata().prepend(l);
195 }
196 }
198 public void resetAnnotations() {
199 initedMetadata().reset();
200 }
202 public void setAttributes(Symbol other) {
203 if (metadata != null || other.metadata != null) {
204 initedMetadata().setAttributes(other.metadata);
205 }
206 }
208 public void setDeclarationAttributes(List<Attribute.Compound> a) {
209 if (metadata != null || a.nonEmpty()) {
210 initedMetadata().setDeclarationAttributes(a);
211 }
212 }
214 public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) {
215 initedMetadata().setDeclarationAttributesWithCompletion(ctx);
216 }
218 public void setTypeAttributes(List<Attribute.TypeCompound> a) {
219 if (metadata != null || a.nonEmpty()) {
220 if (metadata == null)
221 metadata = new SymbolMetadata(this);
222 metadata.setTypeAttributes(a);
223 }
224 }
226 private SymbolMetadata initedMetadata() {
227 if (metadata == null)
228 metadata = new SymbolMetadata(this);
229 return metadata;
230 }
232 /** This method is intended for debugging only. */
233 public SymbolMetadata getMetadata() {
234 return metadata;
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 name != name.table.names._this;
332 }
334 public boolean isInterface() {
335 return (flags() & INTERFACE) != 0;
336 }
338 public boolean isPrivate() {
339 return (flags_field & Flags.AccessFlags) == PRIVATE;
340 }
342 public boolean isEnum() {
343 return (flags() & ENUM) != 0;
344 }
346 /** Is this symbol declared (directly or indirectly) local
347 * to a method or variable initializer?
348 * Also includes fields of inner classes which are in
349 * turn local to a method or variable initializer.
350 */
351 public boolean isLocal() {
352 return
353 (owner.kind & (VAR | MTH)) != 0 ||
354 (owner.kind == TYP && owner.isLocal());
355 }
357 /** Has this symbol an empty name? This includes anonymous
358 * inner classes.
359 */
360 public boolean isAnonymous() {
361 return name.isEmpty();
362 }
364 /** Is this symbol a constructor?
365 */
366 public boolean isConstructor() {
367 return name == name.table.names.init;
368 }
370 /** The fully qualified name of this symbol.
371 * This is the same as the symbol's name except for class symbols,
372 * which are handled separately.
373 */
374 public Name getQualifiedName() {
375 return name;
376 }
378 /** The fully qualified name of this symbol after converting to flat
379 * representation. This is the same as the symbol's name except for
380 * class symbols, which are handled separately.
381 */
382 public Name flatName() {
383 return getQualifiedName();
384 }
386 /** If this is a class or package, its members, otherwise null.
387 */
388 public Scope members() {
389 return null;
390 }
392 /** A class is an inner class if it it has an enclosing instance class.
393 */
394 public boolean isInner() {
395 return type.getEnclosingType().hasTag(CLASS);
396 }
398 /** An inner class has an outer instance if it is not an interface
399 * it has an enclosing instance class which might be referenced from the class.
400 * Nested classes can see instance members of their enclosing class.
401 * Their constructors carry an additional this$n parameter, inserted
402 * implicitly by the compiler.
403 *
404 * @see #isInner
405 */
406 public boolean hasOuterInstance() {
407 return
408 type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
409 }
411 /** The closest enclosing class of this symbol's declaration.
412 */
413 public ClassSymbol enclClass() {
414 Symbol c = this;
415 while (c != null &&
416 ((c.kind & TYP) == 0 || !c.type.hasTag(CLASS))) {
417 c = c.owner;
418 }
419 return (ClassSymbol)c;
420 }
422 /** The outermost class which indirectly owns this symbol.
423 */
424 public ClassSymbol outermostClass() {
425 Symbol sym = this;
426 Symbol prev = null;
427 while (sym.kind != PCK) {
428 prev = sym;
429 sym = sym.owner;
430 }
431 return (ClassSymbol) prev;
432 }
434 /** The package which indirectly owns this symbol.
435 */
436 public PackageSymbol packge() {
437 Symbol sym = this;
438 while (sym.kind != PCK) {
439 sym = sym.owner;
440 }
441 return (PackageSymbol) sym;
442 }
444 /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
445 */
446 public boolean isSubClass(Symbol base, Types types) {
447 throw new AssertionError("isSubClass " + this);
448 }
450 /** Fully check membership: hierarchy, protection, and hiding.
451 * Does not exclude methods not inherited due to overriding.
452 */
453 public boolean isMemberOf(TypeSymbol clazz, Types types) {
454 return
455 owner == clazz ||
456 clazz.isSubClass(owner, types) &&
457 isInheritedIn(clazz, types) &&
458 !hiddenIn((ClassSymbol)clazz, types);
459 }
461 /** Is this symbol the same as or enclosed by the given class? */
462 public boolean isEnclosedBy(ClassSymbol clazz) {
463 for (Symbol sym = this; sym.kind != PCK; sym = sym.owner)
464 if (sym == clazz) return true;
465 return false;
466 }
468 private boolean hiddenIn(ClassSymbol clazz, Types types) {
469 Symbol sym = hiddenInInternal(clazz, types);
470 return sym != null && sym != this;
471 }
473 private Symbol hiddenInInternal(ClassSymbol c, Types types) {
474 Scope.Entry e = c.members().lookup(name);
475 while (e.scope != null) {
476 if (e.sym.kind == kind &&
477 (kind != MTH ||
478 (e.sym.flags() & STATIC) != 0 &&
479 types.isSubSignature(e.sym.type, type))) {
480 return e.sym;
481 }
482 e = e.next();
483 }
484 List<Symbol> hiddenSyms = List.nil();
485 for (Type st : types.interfaces(c.type).prepend(types.supertype(c.type))) {
486 if (st != null && (st.hasTag(CLASS))) {
487 Symbol sym = hiddenInInternal((ClassSymbol)st.tsym, types);
488 if (sym != null) {
489 hiddenSyms = hiddenSyms.prepend(hiddenInInternal((ClassSymbol)st.tsym, types));
490 }
491 }
492 }
493 return hiddenSyms.contains(this) ?
494 this :
495 (hiddenSyms.isEmpty() ? null : hiddenSyms.head);
496 }
498 /** Is this symbol inherited into a given class?
499 * PRE: If symbol's owner is a interface,
500 * it is already assumed that the interface is a superinterface
501 * of given class.
502 * @param clazz The class for which we want to establish membership.
503 * This must be a subclass of the member's owner.
504 */
505 public boolean isInheritedIn(Symbol clazz, Types types) {
506 switch ((int)(flags_field & Flags.AccessFlags)) {
507 default: // error recovery
508 case PUBLIC:
509 return true;
510 case PRIVATE:
511 return this.owner == clazz;
512 case PROTECTED:
513 // we model interfaces as extending Object
514 return (clazz.flags() & INTERFACE) == 0;
515 case 0:
516 PackageSymbol thisPackage = this.packge();
517 for (Symbol sup = clazz;
518 sup != null && sup != this.owner;
519 sup = types.supertype(sup.type).tsym) {
520 while (sup.type.hasTag(TYPEVAR))
521 sup = sup.type.getUpperBound().tsym;
522 if (sup.type.isErroneous())
523 return true; // error recovery
524 if ((sup.flags() & COMPOUND) != 0)
525 continue;
526 if (sup.packge() != thisPackage)
527 return false;
528 }
529 return (clazz.flags() & INTERFACE) == 0;
530 }
531 }
533 /** The (variable or method) symbol seen as a member of given
534 * class type`site' (this might change the symbol's type).
535 * This is used exclusively for producing diagnostics.
536 */
537 public Symbol asMemberOf(Type site, Types types) {
538 throw new AssertionError();
539 }
541 /** Does this method symbol override `other' symbol, when both are seen as
542 * members of class `origin'? It is assumed that _other is a member
543 * of origin.
544 *
545 * It is assumed that both symbols have the same name. The static
546 * modifier is ignored for this test.
547 *
548 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
549 */
550 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
551 return false;
552 }
554 /** Complete the elaboration of this symbol's definition.
555 */
556 public void complete() throws CompletionFailure {
557 if (completer != null) {
558 Completer c = completer;
559 completer = null;
560 c.complete(this);
561 }
562 }
564 /** True if the symbol represents an entity that exists.
565 */
566 public boolean exists() {
567 return true;
568 }
570 public Type asType() {
571 return type;
572 }
574 public Symbol getEnclosingElement() {
575 return owner;
576 }
578 public ElementKind getKind() {
579 return ElementKind.OTHER; // most unkind
580 }
582 public Set<Modifier> getModifiers() {
583 return Flags.asModifierSet(flags());
584 }
586 public Name getSimpleName() {
587 return name;
588 }
590 /**
591 * This is the implementation for {@code
592 * javax.lang.model.element.Element.getAnnotationMirrors()}.
593 */
594 @Override
595 public List<Attribute.Compound> getAnnotationMirrors() {
596 return getRawAttributes();
597 }
600 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
601 public java.util.List<Symbol> getEnclosedElements() {
602 return List.nil();
603 }
605 public List<TypeVariableSymbol> getTypeParameters() {
606 ListBuffer<TypeVariableSymbol> l = new ListBuffer<>();
607 for (Type t : type.getTypeArguments()) {
608 Assert.check(t.tsym.getKind() == ElementKind.TYPE_PARAMETER);
609 l.append((TypeVariableSymbol)t.tsym);
610 }
611 return l.toList();
612 }
614 public static class DelegatedSymbol<T extends Symbol> extends Symbol {
615 protected T other;
616 public DelegatedSymbol(T other) {
617 super(other.kind, other.flags_field, other.name, other.type, other.owner);
618 this.other = other;
619 }
620 public String toString() { return other.toString(); }
621 public Symbol location() { return other.location(); }
622 public Symbol location(Type site, Types types) { return other.location(site, types); }
623 public Symbol baseSymbol() { return other; }
624 public Type erasure(Types types) { return other.erasure(types); }
625 public Type externalType(Types types) { return other.externalType(types); }
626 public boolean isLocal() { return other.isLocal(); }
627 public boolean isConstructor() { return other.isConstructor(); }
628 public Name getQualifiedName() { return other.getQualifiedName(); }
629 public Name flatName() { return other.flatName(); }
630 public Scope members() { return other.members(); }
631 public boolean isInner() { return other.isInner(); }
632 public boolean hasOuterInstance() { return other.hasOuterInstance(); }
633 public ClassSymbol enclClass() { return other.enclClass(); }
634 public ClassSymbol outermostClass() { return other.outermostClass(); }
635 public PackageSymbol packge() { return other.packge(); }
636 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
637 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
638 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
639 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
640 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
641 public void complete() throws CompletionFailure { other.complete(); }
643 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
644 return other.accept(v, p);
645 }
647 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
648 return v.visitSymbol(other, p);
649 }
651 public T getUnderlyingSymbol() {
652 return other;
653 }
654 }
656 /** A base class for Symbols representing types.
657 */
658 public static abstract class TypeSymbol extends Symbol {
659 public TypeSymbol(int kind, long flags, Name name, Type type, Symbol owner) {
660 super(kind, flags, name, type, owner);
661 }
662 /** form a fully qualified name from a name and an owner
663 */
664 static public Name formFullName(Name name, Symbol owner) {
665 if (owner == null) return name;
666 if (((owner.kind != ERR)) &&
667 ((owner.kind & (VAR | MTH)) != 0
668 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
669 )) return name;
670 Name prefix = owner.getQualifiedName();
671 if (prefix == null || prefix == prefix.table.names.empty)
672 return name;
673 else return prefix.append('.', name);
674 }
676 /** form a fully qualified name from a name and an owner, after
677 * converting to flat representation
678 */
679 static public Name formFlatName(Name name, Symbol owner) {
680 if (owner == null ||
681 (owner.kind & (VAR | MTH)) != 0
682 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
683 ) return name;
684 char sep = owner.kind == TYP ? '$' : '.';
685 Name prefix = owner.flatName();
686 if (prefix == null || prefix == prefix.table.names.empty)
687 return name;
688 else return prefix.append(sep, name);
689 }
691 /**
692 * A total ordering between type symbols that refines the
693 * class inheritance graph.
694 *
695 * Typevariables always precede other kinds of symbols.
696 */
697 public final boolean precedes(TypeSymbol that, Types types) {
698 if (this == that)
699 return false;
700 if (type.hasTag(that.type.getTag())) {
701 if (type.hasTag(CLASS)) {
702 return
703 types.rank(that.type) < types.rank(this.type) ||
704 types.rank(that.type) == types.rank(this.type) &&
705 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0;
706 } else if (type.hasTag(TYPEVAR)) {
707 return types.isSubtype(this.type, that.type);
708 }
709 }
710 return type.hasTag(TYPEVAR);
711 }
713 @Override
714 public java.util.List<Symbol> getEnclosedElements() {
715 List<Symbol> list = List.nil();
716 if (kind == TYP && type.hasTag(TYPEVAR)) {
717 return list;
718 }
719 for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
720 if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this)
721 list = list.prepend(e.sym);
722 }
723 return list;
724 }
726 @Override
727 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
728 return v.visitTypeSymbol(this, p);
729 }
730 }
732 /**
733 * Type variables are represented by instances of this class.
734 */
735 public static class TypeVariableSymbol
736 extends TypeSymbol implements TypeParameterElement {
738 public TypeVariableSymbol(long flags, Name name, Type type, Symbol owner) {
739 super(TYP, flags, name, type, owner);
740 }
742 public ElementKind getKind() {
743 return ElementKind.TYPE_PARAMETER;
744 }
746 @Override
747 public Symbol getGenericElement() {
748 return owner;
749 }
751 public List<Type> getBounds() {
752 TypeVar t = (TypeVar)type;
753 Type bound = t.getUpperBound();
754 if (!bound.isCompound())
755 return List.of(bound);
756 ClassType ct = (ClassType)bound;
757 if (!ct.tsym.erasure_field.isInterface()) {
758 return ct.interfaces_field.prepend(ct.supertype_field);
759 } else {
760 // No superclass was given in bounds.
761 // In this case, supertype is Object, erasure is first interface.
762 return ct.interfaces_field;
763 }
764 }
766 @Override
767 public List<Attribute.Compound> getAnnotationMirrors() {
768 return onlyTypeVariableAnnotations(owner.getRawTypeAttributes());
769 }
771 private List<Attribute.Compound> onlyTypeVariableAnnotations(
772 List<Attribute.TypeCompound> candidates) {
773 // Declaration annotations on TypeParameters are stored in type attributes
774 List<Attribute.Compound> res = List.nil();
775 for (Attribute.TypeCompound a : candidates) {
776 if (a.position.type == TargetType.CLASS_TYPE_PARAMETER ||
777 a.position.type == TargetType.METHOD_TYPE_PARAMETER)
778 res = res.prepend(a);
779 }
781 return res = res.reverse();
782 }
786 // Helper to getAnnotation[s]
787 @Override
788 public <A extends Annotation> Attribute.Compound getAttribute(Class<A> annoType) {
790 String name = annoType.getName();
792 // Declaration annotations on type variables are stored in type attributes
793 // on the owner of the TypeVariableSymbol
794 List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes();
795 for (Attribute.TypeCompound anno : candidates)
796 if (anno.position.type == TargetType.CLASS_TYPE_PARAMETER ||
797 anno.position.type == TargetType.METHOD_TYPE_PARAMETER)
798 if (name.contentEquals(anno.type.tsym.flatName()))
799 return anno;
801 return null;
802 }
806 @Override
807 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
808 return v.visitTypeParameter(this, p);
809 }
810 }
812 /** A class for package symbols
813 */
814 public static class PackageSymbol extends TypeSymbol
815 implements PackageElement {
817 public Scope members_field;
818 public Name fullname;
819 public ClassSymbol package_info; // see bug 6443073
821 public PackageSymbol(Name name, Type type, Symbol owner) {
822 super(PCK, 0, name, type, owner);
823 this.members_field = null;
824 this.fullname = formFullName(name, owner);
825 }
827 public PackageSymbol(Name name, Symbol owner) {
828 this(name, null, owner);
829 this.type = new PackageType(this);
830 }
832 public String toString() {
833 return fullname.toString();
834 }
836 public Name getQualifiedName() {
837 return fullname;
838 }
840 public boolean isUnnamed() {
841 return name.isEmpty() && owner != null;
842 }
844 public Scope members() {
845 if (completer != null) complete();
846 return members_field;
847 }
849 public long flags() {
850 if (completer != null) complete();
851 return flags_field;
852 }
854 @Override
855 public List<Attribute.Compound> getRawAttributes() {
856 if (completer != null) complete();
857 if (package_info != null && package_info.completer != null) {
858 package_info.complete();
859 mergeAttributes();
860 }
861 return super.getRawAttributes();
862 }
864 private void mergeAttributes() {
865 if (metadata == null &&
866 package_info.metadata != null) {
867 metadata = new SymbolMetadata(this);
868 metadata.setAttributes(package_info.metadata);
869 }
870 }
872 /** A package "exists" if a type or package that exists has
873 * been seen within it.
874 */
875 public boolean exists() {
876 return (flags_field & EXISTS) != 0;
877 }
879 public ElementKind getKind() {
880 return ElementKind.PACKAGE;
881 }
883 public Symbol getEnclosingElement() {
884 return null;
885 }
887 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
888 return v.visitPackage(this, p);
889 }
891 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
892 return v.visitPackageSymbol(this, p);
893 }
894 }
896 /** A class for class symbols
897 */
898 public static class ClassSymbol extends TypeSymbol implements TypeElement {
900 /** a scope for all class members; variables, methods and inner classes
901 * type parameters are not part of this scope
902 */
903 public Scope members_field;
905 /** the fully qualified name of the class, i.e. pck.outer.inner.
906 * null for anonymous classes
907 */
908 public Name fullname;
910 /** the fully qualified name of the class after converting to flat
911 * representation, i.e. pck.outer$inner,
912 * set externally for local and anonymous classes
913 */
914 public Name flatname;
916 /** the sourcefile where the class came from
917 */
918 public JavaFileObject sourcefile;
920 /** the classfile from where to load this class
921 * this will have extension .class or .java
922 */
923 public JavaFileObject classfile;
925 /** the list of translated local classes (used for generating
926 * InnerClasses attribute)
927 */
928 public List<ClassSymbol> trans_local;
930 /** the constant pool of the class
931 */
932 public Pool pool;
934 public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
935 super(TYP, flags, name, type, owner);
936 this.members_field = null;
937 this.fullname = formFullName(name, owner);
938 this.flatname = formFlatName(name, owner);
939 this.sourcefile = null;
940 this.classfile = null;
941 this.pool = null;
942 }
944 public ClassSymbol(long flags, Name name, Symbol owner) {
945 this(
946 flags,
947 name,
948 new ClassType(Type.noType, null, null),
949 owner);
950 this.type.tsym = this;
951 }
953 /** The Java source which this symbol represents.
954 */
955 public String toString() {
956 return className();
957 }
959 public long flags() {
960 if (completer != null) complete();
961 return flags_field;
962 }
964 public Scope members() {
965 if (completer != null) complete();
966 return members_field;
967 }
969 @Override
970 public List<Attribute.Compound> getRawAttributes() {
971 if (completer != null) complete();
972 return super.getRawAttributes();
973 }
975 @Override
976 public List<Attribute.TypeCompound> getRawTypeAttributes() {
977 if (completer != null) complete();
978 return super.getRawTypeAttributes();
979 }
981 public Type erasure(Types types) {
982 if (erasure_field == null)
983 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
984 List.<Type>nil(), this);
985 return erasure_field;
986 }
988 public String className() {
989 if (name.isEmpty())
990 return
991 Log.getLocalizedString("anonymous.class", flatname);
992 else
993 return fullname.toString();
994 }
996 public Name getQualifiedName() {
997 return fullname;
998 }
1000 public Name flatName() {
1001 return flatname;
1002 }
1004 public boolean isSubClass(Symbol base, Types types) {
1005 if (this == base) {
1006 return true;
1007 } else if ((base.flags() & INTERFACE) != 0) {
1008 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1009 for (List<Type> is = types.interfaces(t);
1010 is.nonEmpty();
1011 is = is.tail)
1012 if (is.head.tsym.isSubClass(base, types)) return true;
1013 } else {
1014 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1015 if (t.tsym == base) return true;
1016 }
1017 return false;
1018 }
1020 /** Complete the elaboration of this symbol's definition.
1021 */
1022 public void complete() throws CompletionFailure {
1023 try {
1024 super.complete();
1025 } catch (CompletionFailure ex) {
1026 // quiet error recovery
1027 flags_field |= (PUBLIC|STATIC);
1028 this.type = new ErrorType(this, Type.noType);
1029 throw ex;
1030 }
1031 }
1033 public List<Type> getInterfaces() {
1034 complete();
1035 if (type instanceof ClassType) {
1036 ClassType t = (ClassType)type;
1037 if (t.interfaces_field == null) // FIXME: shouldn't be null
1038 t.interfaces_field = List.nil();
1039 if (t.all_interfaces_field != null)
1040 return Type.getModelTypes(t.all_interfaces_field);
1041 return t.interfaces_field;
1042 } else {
1043 return List.nil();
1044 }
1045 }
1047 public Type getSuperclass() {
1048 complete();
1049 if (type instanceof ClassType) {
1050 ClassType t = (ClassType)type;
1051 if (t.supertype_field == null) // FIXME: shouldn't be null
1052 t.supertype_field = Type.noType;
1053 // An interface has no superclass; its supertype is Object.
1054 return t.isInterface()
1055 ? Type.noType
1056 : t.supertype_field.getModelType();
1057 } else {
1058 return Type.noType;
1059 }
1060 }
1062 /**
1063 * Returns the next class to search for inherited annotations or {@code null}
1064 * if the next class can't be found.
1065 */
1066 private ClassSymbol getSuperClassToSearchForAnnotations() {
1068 Type sup = getSuperclass();
1070 if (!sup.hasTag(CLASS) || sup.isErroneous())
1071 return null;
1073 return (ClassSymbol) sup.tsym;
1074 }
1077 @Override
1078 protected <A extends Annotation> A[] getInheritedAnnotations(Class<A> annoType) {
1080 ClassSymbol sup = getSuperClassToSearchForAnnotations();
1082 return sup == null ? super.getInheritedAnnotations(annoType)
1083 : sup.getAnnotationsByType(annoType);
1084 }
1087 public ElementKind getKind() {
1088 long flags = flags();
1089 if ((flags & ANNOTATION) != 0)
1090 return ElementKind.ANNOTATION_TYPE;
1091 else if ((flags & INTERFACE) != 0)
1092 return ElementKind.INTERFACE;
1093 else if ((flags & ENUM) != 0)
1094 return ElementKind.ENUM;
1095 else
1096 return ElementKind.CLASS;
1097 }
1099 @Override
1100 public Set<Modifier> getModifiers() {
1101 long flags = flags();
1102 return Flags.asModifierSet(flags & ~DEFAULT);
1103 }
1105 public NestingKind getNestingKind() {
1106 complete();
1107 if (owner.kind == PCK)
1108 return NestingKind.TOP_LEVEL;
1109 else if (name.isEmpty())
1110 return NestingKind.ANONYMOUS;
1111 else if (owner.kind == MTH)
1112 return NestingKind.LOCAL;
1113 else
1114 return NestingKind.MEMBER;
1115 }
1118 @Override
1119 protected <A extends Annotation> Attribute.Compound getAttribute(final Class<A> annoType) {
1121 Attribute.Compound attrib = super.getAttribute(annoType);
1123 boolean inherited = annoType.isAnnotationPresent(Inherited.class);
1124 if (attrib != null || !inherited)
1125 return attrib;
1127 // Search supertypes
1128 ClassSymbol superType = getSuperClassToSearchForAnnotations();
1129 return superType == null ? null
1130 : superType.getAttribute(annoType);
1131 }
1136 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1137 return v.visitType(this, p);
1138 }
1140 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1141 return v.visitClassSymbol(this, p);
1142 }
1143 }
1146 /** A class for variable symbols
1147 */
1148 public static class VarSymbol extends Symbol implements VariableElement {
1150 /** The variable's declaration position.
1151 */
1152 public int pos = Position.NOPOS;
1154 /** The variable's address. Used for different purposes during
1155 * flow analysis, translation and code generation.
1156 * Flow analysis:
1157 * If this is a blank final or local variable, its sequence number.
1158 * Translation:
1159 * If this is a private field, its access number.
1160 * Code generation:
1161 * If this is a local variable, its logical slot number.
1162 */
1163 public int adr = -1;
1165 /** Construct a variable symbol, given its flags, name, type and owner.
1166 */
1167 public VarSymbol(long flags, Name name, Type type, Symbol owner) {
1168 super(VAR, flags, name, type, owner);
1169 }
1171 /** Clone this symbol with new owner.
1172 */
1173 public VarSymbol clone(Symbol newOwner) {
1174 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) {
1175 @Override
1176 public Symbol baseSymbol() {
1177 return VarSymbol.this;
1178 }
1179 };
1180 v.pos = pos;
1181 v.adr = adr;
1182 v.data = data;
1183 // System.out.println("clone " + v + " in " + newOwner);//DEBUG
1184 return v;
1185 }
1187 public String toString() {
1188 return name.toString();
1189 }
1191 public Symbol asMemberOf(Type site, Types types) {
1192 return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
1193 }
1195 public ElementKind getKind() {
1196 long flags = flags();
1197 if ((flags & PARAMETER) != 0) {
1198 if (isExceptionParameter())
1199 return ElementKind.EXCEPTION_PARAMETER;
1200 else
1201 return ElementKind.PARAMETER;
1202 } else if ((flags & ENUM) != 0) {
1203 return ElementKind.ENUM_CONSTANT;
1204 } else if (owner.kind == TYP || owner.kind == ERR) {
1205 return ElementKind.FIELD;
1206 } else if (isResourceVariable()) {
1207 return ElementKind.RESOURCE_VARIABLE;
1208 } else {
1209 return ElementKind.LOCAL_VARIABLE;
1210 }
1211 }
1213 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1214 return v.visitVariable(this, p);
1215 }
1217 public Object getConstantValue() { // Mirror API
1218 return Constants.decode(getConstValue(), type);
1219 }
1221 public void setLazyConstValue(final Env<AttrContext> env,
1222 final Attr attr,
1223 final JCVariableDecl variable)
1224 {
1225 setData(new Callable<Object>() {
1226 public Object call() {
1227 return attr.attribLazyConstantValue(env, variable, type);
1228 }
1229 });
1230 }
1232 /**
1233 * The variable's constant value, if this is a constant.
1234 * Before the constant value is evaluated, it points to an
1235 * initializer environment. If this is not a constant, it can
1236 * be used for other stuff.
1237 */
1238 private Object data;
1240 public boolean isExceptionParameter() {
1241 return data == ElementKind.EXCEPTION_PARAMETER;
1242 }
1244 public boolean isResourceVariable() {
1245 return data == ElementKind.RESOURCE_VARIABLE;
1246 }
1248 public Object getConstValue() {
1249 // TODO: Consider if getConstValue and getConstantValue can be collapsed
1250 if (data == ElementKind.EXCEPTION_PARAMETER ||
1251 data == ElementKind.RESOURCE_VARIABLE) {
1252 return null;
1253 } else if (data instanceof Callable<?>) {
1254 // In this case, this is a final variable, with an as
1255 // yet unevaluated initializer.
1256 Callable<?> eval = (Callable<?>)data;
1257 data = null; // to make sure we don't evaluate this twice.
1258 try {
1259 data = eval.call();
1260 } catch (Exception ex) {
1261 throw new AssertionError(ex);
1262 }
1263 }
1264 return data;
1265 }
1267 public void setData(Object data) {
1268 Assert.check(!(data instanceof Env<?>), this);
1269 this.data = data;
1270 }
1272 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1273 return v.visitVarSymbol(this, p);
1274 }
1275 }
1277 /** A class for method symbols.
1278 */
1279 public static class MethodSymbol extends Symbol implements ExecutableElement {
1281 /** The code of the method. */
1282 public Code code = null;
1284 /** The extra (synthetic/mandated) parameters of the method. */
1285 public List<VarSymbol> extraParams = List.nil();
1287 /** The captured local variables in an anonymous class */
1288 public List<VarSymbol> capturedLocals = List.nil();
1290 /** The parameters of the method. */
1291 public List<VarSymbol> params = null;
1293 /** The names of the parameters */
1294 public List<Name> savedParameterNames;
1296 /** For an attribute field accessor, its default value if any.
1297 * The value is null if none appeared in the method
1298 * declaration.
1299 */
1300 public Attribute defaultValue = null;
1302 /** Construct a method symbol, given its flags, name, type and owner.
1303 */
1304 public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1305 super(MTH, flags, name, type, owner);
1306 if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name);
1307 }
1309 /** Clone this symbol with new owner.
1310 */
1311 public MethodSymbol clone(Symbol newOwner) {
1312 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) {
1313 @Override
1314 public Symbol baseSymbol() {
1315 return MethodSymbol.this;
1316 }
1317 };
1318 m.code = code;
1319 return m;
1320 }
1322 @Override
1323 public Set<Modifier> getModifiers() {
1324 long flags = flags();
1325 return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags);
1326 }
1328 /** The Java source which this symbol represents.
1329 */
1330 public String toString() {
1331 if ((flags() & BLOCK) != 0) {
1332 return owner.name.toString();
1333 } else {
1334 String s = (name == name.table.names.init)
1335 ? owner.name.toString()
1336 : name.toString();
1337 if (type != null) {
1338 if (type.hasTag(FORALL))
1339 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
1340 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
1341 }
1342 return s;
1343 }
1344 }
1346 public boolean isDynamic() {
1347 return false;
1348 }
1350 /** find a symbol that this (proxy method) symbol implements.
1351 * @param c The class whose members are searched for
1352 * implementations
1353 */
1354 public Symbol implemented(TypeSymbol c, Types types) {
1355 Symbol impl = null;
1356 for (List<Type> is = types.interfaces(c.type);
1357 impl == null && is.nonEmpty();
1358 is = is.tail) {
1359 TypeSymbol i = is.head.tsym;
1360 impl = implementedIn(i, types);
1361 if (impl == null)
1362 impl = implemented(i, types);
1363 }
1364 return impl;
1365 }
1367 public Symbol implementedIn(TypeSymbol c, Types types) {
1368 Symbol impl = null;
1369 for (Scope.Entry e = c.members().lookup(name);
1370 impl == null && e.scope != null;
1371 e = e.next()) {
1372 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
1373 // FIXME: I suspect the following requires a
1374 // subst() for a parametric return type.
1375 types.isSameType(type.getReturnType(),
1376 types.memberType(owner.type, e.sym).getReturnType())) {
1377 impl = e.sym;
1378 }
1379 }
1380 return impl;
1381 }
1383 /** Will the erasure of this method be considered by the VM to
1384 * override the erasure of the other when seen from class `origin'?
1385 */
1386 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
1387 if (isConstructor() || _other.kind != MTH) return false;
1389 if (this == _other) return true;
1390 MethodSymbol other = (MethodSymbol)_other;
1392 // check for a direct implementation
1393 if (other.isOverridableIn((TypeSymbol)owner) &&
1394 types.asSuper(owner.type, other.owner) != null &&
1395 types.isSameType(erasure(types), other.erasure(types)))
1396 return true;
1398 // check for an inherited implementation
1399 return
1400 (flags() & ABSTRACT) == 0 &&
1401 other.isOverridableIn(origin) &&
1402 this.isMemberOf(origin, types) &&
1403 types.isSameType(erasure(types), other.erasure(types));
1404 }
1406 /** The implementation of this (abstract) symbol in class origin,
1407 * from the VM's point of view, null if method does not have an
1408 * implementation in class.
1409 * @param origin The class of which the implementation is a member.
1410 */
1411 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
1412 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
1413 for (Scope.Entry e = c.members().lookup(name);
1414 e.scope != null;
1415 e = e.next()) {
1416 if (e.sym.kind == MTH &&
1417 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
1418 return (MethodSymbol)e.sym;
1419 }
1420 }
1421 return null;
1422 }
1424 /** Does this symbol override `other' symbol, when both are seen as
1425 * members of class `origin'? It is assumed that _other is a member
1426 * of origin.
1427 *
1428 * It is assumed that both symbols have the same name. The static
1429 * modifier is ignored for this test.
1430 *
1431 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4
1432 */
1433 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
1434 if (isConstructor() || _other.kind != MTH) return false;
1436 if (this == _other) return true;
1437 MethodSymbol other = (MethodSymbol)_other;
1439 // check for a direct implementation
1440 if (other.isOverridableIn((TypeSymbol)owner) &&
1441 types.asSuper(owner.type, other.owner) != null) {
1442 Type mt = types.memberType(owner.type, this);
1443 Type ot = types.memberType(owner.type, other);
1444 if (types.isSubSignature(mt, ot)) {
1445 if (!checkResult)
1446 return true;
1447 if (types.returnTypeSubstitutable(mt, ot))
1448 return true;
1449 }
1450 }
1452 // check for an inherited implementation
1453 if ((flags() & ABSTRACT) != 0 ||
1454 ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
1455 !other.isOverridableIn(origin) ||
1456 !this.isMemberOf(origin, types))
1457 return false;
1459 // assert types.asSuper(origin.type, other.owner) != null;
1460 Type mt = types.memberType(origin.type, this);
1461 Type ot = types.memberType(origin.type, other);
1462 return
1463 types.isSubSignature(mt, ot) &&
1464 (!checkResult || types.resultSubtype(mt, ot, types.noWarnings));
1465 }
1467 private boolean isOverridableIn(TypeSymbol origin) {
1468 // JLS 8.4.6.1
1469 switch ((int)(flags_field & Flags.AccessFlags)) {
1470 case Flags.PRIVATE:
1471 return false;
1472 case Flags.PUBLIC:
1473 return !this.owner.isInterface() ||
1474 (flags_field & STATIC) == 0;
1475 case Flags.PROTECTED:
1476 return (origin.flags() & INTERFACE) == 0;
1477 case 0:
1478 // for package private: can only override in the same
1479 // package
1480 return
1481 this.packge() == origin.packge() &&
1482 (origin.flags() & INTERFACE) == 0;
1483 default:
1484 return false;
1485 }
1486 }
1488 @Override
1489 public boolean isInheritedIn(Symbol clazz, Types types) {
1490 switch ((int)(flags_field & Flags.AccessFlags)) {
1491 case PUBLIC:
1492 return !this.owner.isInterface() ||
1493 clazz == owner ||
1494 (flags_field & STATIC) == 0;
1495 default:
1496 return super.isInheritedIn(clazz, types);
1497 }
1498 }
1500 /** The implementation of this (abstract) symbol in class origin;
1501 * null if none exists. Synthetic methods are not considered
1502 * as possible implementations.
1503 */
1504 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
1505 return implementation(origin, types, checkResult, implementation_filter);
1506 }
1507 // where
1508 public static final Filter<Symbol> implementation_filter = new Filter<Symbol>() {
1509 public boolean accepts(Symbol s) {
1510 return s.kind == Kinds.MTH &&
1511 (s.flags() & SYNTHETIC) == 0;
1512 }
1513 };
1515 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
1516 MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
1517 if (res != null)
1518 return res;
1519 // if origin is derived from a raw type, we might have missed
1520 // an implementation because we do not know enough about instantiations.
1521 // in this case continue with the supertype as origin.
1522 if (types.isDerivedRaw(origin.type) && !origin.isInterface())
1523 return implementation(types.supertype(origin.type).tsym, types, checkResult);
1524 else
1525 return null;
1526 }
1528 public List<VarSymbol> params() {
1529 owner.complete();
1530 if (params == null) {
1531 // If ClassReader.saveParameterNames has been set true, then
1532 // savedParameterNames will be set to a list of names that
1533 // matches the types in type.getParameterTypes(). If any names
1534 // were not found in the class file, those names in the list will
1535 // be set to the empty name.
1536 // If ClassReader.saveParameterNames has been set false, then
1537 // savedParameterNames will be null.
1538 List<Name> paramNames = savedParameterNames;
1539 savedParameterNames = null;
1540 // discard the provided names if the list of names is the wrong size.
1541 if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) {
1542 paramNames = List.nil();
1543 }
1544 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>();
1545 List<Name> remaining = paramNames;
1546 // assert: remaining and paramNames are both empty or both
1547 // have same cardinality as type.getParameterTypes()
1548 int i = 0;
1549 for (Type t : type.getParameterTypes()) {
1550 Name paramName;
1551 if (remaining.isEmpty()) {
1552 // no names for any parameters available
1553 paramName = createArgName(i, paramNames);
1554 } else {
1555 paramName = remaining.head;
1556 remaining = remaining.tail;
1557 if (paramName.isEmpty()) {
1558 // no name for this specific parameter
1559 paramName = createArgName(i, paramNames);
1560 }
1561 }
1562 buf.append(new VarSymbol(PARAMETER, paramName, t, this));
1563 i++;
1564 }
1565 params = buf.toList();
1566 }
1567 return params;
1568 }
1570 // Create a name for the argument at position 'index' that is not in
1571 // the exclude list. In normal use, either no names will have been
1572 // provided, in which case the exclude list is empty, or all the names
1573 // will have been provided, in which case this method will not be called.
1574 private Name createArgName(int index, List<Name> exclude) {
1575 String prefix = "arg";
1576 while (true) {
1577 Name argName = name.table.fromString(prefix + index);
1578 if (!exclude.contains(argName))
1579 return argName;
1580 prefix += "$";
1581 }
1582 }
1584 public Symbol asMemberOf(Type site, Types types) {
1585 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
1586 }
1588 public ElementKind getKind() {
1589 if (name == name.table.names.init)
1590 return ElementKind.CONSTRUCTOR;
1591 else if (name == name.table.names.clinit)
1592 return ElementKind.STATIC_INIT;
1593 else if ((flags() & BLOCK) != 0)
1594 return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT;
1595 else
1596 return ElementKind.METHOD;
1597 }
1599 public boolean isStaticOrInstanceInit() {
1600 return getKind() == ElementKind.STATIC_INIT ||
1601 getKind() == ElementKind.INSTANCE_INIT;
1602 }
1604 public Attribute getDefaultValue() {
1605 return defaultValue;
1606 }
1608 public List<VarSymbol> getParameters() {
1609 return params();
1610 }
1612 public boolean isVarArgs() {
1613 return (flags() & VARARGS) != 0;
1614 }
1616 public boolean isDefault() {
1617 return (flags() & DEFAULT) != 0;
1618 }
1620 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1621 return v.visitExecutable(this, p);
1622 }
1624 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1625 return v.visitMethodSymbol(this, p);
1626 }
1628 public Type getReceiverType() {
1629 return asType().getReceiverType();
1630 }
1632 public Type getReturnType() {
1633 return asType().getReturnType();
1634 }
1636 public List<Type> getThrownTypes() {
1637 return asType().getThrownTypes();
1638 }
1639 }
1641 /** A class for invokedynamic method calls.
1642 */
1643 public static class DynamicMethodSymbol extends MethodSymbol {
1645 public Object[] staticArgs;
1646 public Symbol bsm;
1647 public int bsmKind;
1649 public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) {
1650 super(0, name, type, owner);
1651 this.bsm = bsm;
1652 this.bsmKind = bsmKind;
1653 this.staticArgs = staticArgs;
1654 }
1656 @Override
1657 public boolean isDynamic() {
1658 return true;
1659 }
1660 }
1662 /** A class for predefined operators.
1663 */
1664 public static class OperatorSymbol extends MethodSymbol {
1666 public int opcode;
1668 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
1669 super(PUBLIC | STATIC, name, type, owner);
1670 this.opcode = opcode;
1671 }
1673 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1674 return v.visitOperatorSymbol(this, p);
1675 }
1676 }
1678 /** Symbol completer interface.
1679 */
1680 public static interface Completer {
1681 void complete(Symbol sym) throws CompletionFailure;
1682 }
1684 public static class CompletionFailure extends RuntimeException {
1685 private static final long serialVersionUID = 0;
1686 public Symbol sym;
1688 /** A diagnostic object describing the failure
1689 */
1690 public JCDiagnostic diag;
1692 /** A localized string describing the failure.
1693 * @deprecated Use {@code getDetail()} or {@code getMessage()}
1694 */
1695 @Deprecated
1696 public String errmsg;
1698 public CompletionFailure(Symbol sym, String errmsg) {
1699 this.sym = sym;
1700 this.errmsg = errmsg;
1701 // this.printStackTrace();//DEBUG
1702 }
1704 public CompletionFailure(Symbol sym, JCDiagnostic diag) {
1705 this.sym = sym;
1706 this.diag = diag;
1707 // this.printStackTrace();//DEBUG
1708 }
1710 public JCDiagnostic getDiagnostic() {
1711 return diag;
1712 }
1714 @Override
1715 public String getMessage() {
1716 if (diag != null)
1717 return diag.getMessage(null);
1718 else
1719 return errmsg;
1720 }
1722 public Object getDetailValue() {
1723 return (diag != null ? diag : errmsg);
1724 }
1726 @Override
1727 public CompletionFailure initCause(Throwable cause) {
1728 super.initCause(cause);
1729 return this;
1730 }
1732 }
1734 /**
1735 * A visitor for symbols. A visitor is used to implement operations
1736 * (or relations) on symbols. Most common operations on types are
1737 * binary relations and this interface is designed for binary
1738 * relations, that is, operations on the form
1739 * Symbol × P → R.
1740 * <!-- In plain text: Type x P -> R -->
1741 *
1742 * @param <R> the return type of the operation implemented by this
1743 * visitor; use Void if no return type is needed.
1744 * @param <P> the type of the second argument (the first being the
1745 * symbol itself) of the operation implemented by this visitor; use
1746 * Void if a second argument is not needed.
1747 */
1748 public interface Visitor<R,P> {
1749 R visitClassSymbol(ClassSymbol s, P arg);
1750 R visitMethodSymbol(MethodSymbol s, P arg);
1751 R visitPackageSymbol(PackageSymbol s, P arg);
1752 R visitOperatorSymbol(OperatorSymbol s, P arg);
1753 R visitVarSymbol(VarSymbol s, P arg);
1754 R visitTypeSymbol(TypeSymbol s, P arg);
1755 R visitSymbol(Symbol s, P arg);
1756 }
1757 }