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 */ 25 26 package com.sun.tools.javac.code; 27 28 import java.util.Set; 29 import java.util.concurrent.Callable; 30 31 import javax.lang.model.element.*; 32 import javax.tools.JavaFileObject; 33 34 import com.sun.tools.javac.code.Type.*; 35 import com.sun.tools.javac.comp.Annotate; 36 import com.sun.tools.javac.comp.Attr; 37 import com.sun.tools.javac.comp.AttrContext; 38 import com.sun.tools.javac.comp.Env; 39 import com.sun.tools.javac.jvm.*; 40 import com.sun.tools.javac.model.*; 41 import com.sun.tools.javac.tree.JCTree; 42 import com.sun.tools.javac.util.*; 43 import com.sun.tools.javac.util.Name; 44 import static com.sun.tools.javac.code.Flags.*; 45 import static com.sun.tools.javac.code.Kinds.*; 46 import static com.sun.tools.javac.code.TypeTag.CLASS; 47 import static com.sun.tools.javac.code.TypeTag.FORALL; 48 import static com.sun.tools.javac.code.TypeTag.TYPEVAR; 49 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(); 62 63 /** The kind of this symbol. 64 * @see Kinds 65 */ 66 public int kind; 67 68 /** The flags of this symbol. 69 */ 70 public long flags_field; 71 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; } 77 78 /** The name of this symbol in Utf8 representation. 79 */ 80 public Name name; 81 82 /** The type of this symbol. 83 */ 84 public Type type; 85 86 /** The owner of this symbol. 87 */ 88 public Symbol owner; 89 90 /** The completer of this symbol. 91 */ 92 public Completer completer; 93 94 /** A cache for the type erasure of this symbol. 95 */ 96 public Type erasure_field; 97 98 // <editor-fold defaultstate="collapsed" desc="annotations"> 99 100 /** The attributes of this symbol are contained in this 101 * Annotations. The Annotations instance is NOT immutable. 102 */ 103 protected Annotations annotations; 104 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 } 114 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 } 124 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 } 132 133 public boolean annotationsPendingCompletion() { 134 return annotations == null ? false : annotations.pendingCompletion(); 135 } 136 137 public void appendAttributes(List<Attribute.Compound> l) { 138 if (l.nonEmpty()) { 139 initedAnnos().append(l); 140 } 141 } 142 143 public void appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) { 144 if (l.nonEmpty()) { 145 initedAnnos().appendClassInitTypeAttributes(l); 146 } 147 } 148 149 public void appendInitTypeAttributes(List<Attribute.TypeCompound> l) { 150 if (l.nonEmpty()) { 151 initedAnnos().appendInitTypeAttributes(l); 152 } 153 } 154 155 public void appendTypeAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.TypeCompound> ctx) { 156 initedAnnos().appendTypeAttributesWithCompletion(ctx); 157 } 158 159 public void appendUniqueTypeAttributes(List<Attribute.TypeCompound> l) { 160 if (l.nonEmpty()) { 161 initedAnnos().appendUniqueTypes(l); 162 } 163 } 164 165 public List<Attribute.TypeCompound> getClassInitTypeAttributes() { 166 return (annotations == null) 167 ? List.<Attribute.TypeCompound>nil() 168 : annotations.getClassInitTypeAttributes(); 169 } 170 171 public List<Attribute.TypeCompound> getInitTypeAttributes() { 172 return (annotations == null) 173 ? List.<Attribute.TypeCompound>nil() 174 : annotations.getInitTypeAttributes(); 175 } 176 177 public List<Attribute.Compound> getDeclarationAttributes() { 178 return (annotations == null) 179 ? List.<Attribute.Compound>nil() 180 : annotations.getDeclarationAttributes(); 181 } 182 183 public boolean hasAnnotations() { 184 return (annotations != null && !annotations.isEmpty()); 185 } 186 187 public boolean hasTypeAnnotations() { 188 return (annotations != null && !annotations.isTypesEmpty()); 189 } 190 191 public void prependAttributes(List<Attribute.Compound> l) { 192 if (l.nonEmpty()) { 193 initedAnnos().prepend(l); 194 } 195 } 196 197 public void resetAnnotations() { 198 initedAnnos().reset(); 199 } 200 201 public void setAttributes(Symbol other) { 202 if (annotations != null || other.annotations != null) { 203 initedAnnos().setAttributes(other.annotations); 204 } 205 } 206 207 public void setDeclarationAttributes(List<Attribute.Compound> a) { 208 if (annotations != null || a.nonEmpty()) { 209 initedAnnos().setDeclarationAttributes(a); 210 } 211 } 212 213 public void setDeclarationAttributesWithCompletion(final Annotate.AnnotateRepeatedContext<Attribute.Compound> ctx) { 214 initedAnnos().setDeclarationAttributesWithCompletion(ctx); 215 } 216 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 } 224 225 private Annotations initedAnnos() { 226 if (annotations == null) 227 annotations = new Annotations(this); 228 return annotations; 229 } 230 231 /** This method is intended for debugging only. */ 232 public Annotations getAnnotations() { 233 return annotations; 234 } 235 236 // </editor-fold> 237 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 } 249 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 } 256 257 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 258 return v.visitSymbol(this, p); 259 } 260 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 } 267 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 } 281 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 } 292 293 public Symbol baseSymbol() { 294 return this; 295 } 296 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 } 304 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 } 321 322 public boolean isDeprecated() { 323 return (flags_field & DEPRECATED) != 0; 324 } 325 326 public boolean isStatic() { 327 return 328 (flags() & STATIC) != 0 || 329 (owner.flags() & INTERFACE) != 0 && kind != MTH; 330 } 331 332 public boolean isInterface() { 333 return (flags() & INTERFACE) != 0; 334 } 335 336 public boolean isPrivate() { 337 return (flags_field & Flags.AccessFlags) == PRIVATE; 338 } 339 340 public boolean isEnum() { 341 return (flags() & ENUM) != 0; 342 } 343 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 } 354 355 /** Has this symbol an empty name? This includes anonymous 356 * inner classes. 357 */ 358 public boolean isAnonymous() { 359 return name.isEmpty(); 360 } 361 362 /** Is this symbol a constructor? 363 */ 364 public boolean isConstructor() { 365 return name == name.table.names.init; 366 } 367 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 } 375 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 } 383 384 /** If this is a class or package, its members, otherwise null. 385 */ 386 public Scope members() { 387 return null; 388 } 389 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 } 395 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 } 408 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 } 419 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 } 431 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 } 441 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 } 447 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 } 458 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 } 465 466 /** Check for hiding. Note that this doesn't handle multiple 467 * (interface) inheritance. */ 468 private boolean hiddenIn(ClassSymbol clazz, Types types) { 469 if (kind == MTH && (flags() & STATIC) == 0) return false; 470 while (true) { 471 if (owner == clazz) return false; 472 Scope.Entry e = clazz.members().lookup(name); 473 while (e.scope != null) { 474 if (e.sym == this) return false; 475 if (e.sym.kind == kind && 476 (kind != MTH || 477 (e.sym.flags() & STATIC) != 0 && 478 types.isSubSignature(e.sym.type, type))) 479 return true; 480 e = e.next(); 481 } 482 Type superType = types.supertype(clazz.type); 483 if (!superType.hasTag(CLASS)) return false; 484 clazz = (ClassSymbol)superType.tsym; 485 } 486 } 487 488 /** Is this symbol inherited into a given class? 489 * PRE: If symbol's owner is a interface, 490 * it is already assumed that the interface is a superinterface 491 * of given class. 492 * @param clazz The class for which we want to establish membership. 493 * This must be a subclass of the member's owner. 494 */ 495 public boolean isInheritedIn(Symbol clazz, Types types) { 496 switch ((int)(flags_field & Flags.AccessFlags)) { 497 default: // error recovery 498 case PUBLIC: 499 return true; 500 case PRIVATE: 501 return this.owner == clazz; 502 case PROTECTED: 503 // we model interfaces as extending Object 504 return (clazz.flags() & INTERFACE) == 0; 505 case 0: 506 PackageSymbol thisPackage = this.packge(); 507 for (Symbol sup = clazz; 508 sup != null && sup != this.owner; 509 sup = types.supertype(sup.type).tsym) { 510 while (sup.type.hasTag(TYPEVAR)) 511 sup = sup.type.getUpperBound().tsym; 512 if (sup.type.isErroneous()) 513 return true; // error recovery 514 if ((sup.flags() & COMPOUND) != 0) 515 continue; 516 if (sup.packge() != thisPackage) 517 return false; 518 } 519 return (clazz.flags() & INTERFACE) == 0; 520 } 521 } 522 523 /** The (variable or method) symbol seen as a member of given 524 * class type`site' (this might change the symbol's type). 525 * This is used exclusively for producing diagnostics. 526 */ 527 public Symbol asMemberOf(Type site, Types types) { 528 throw new AssertionError(); 529 } 530 531 /** Does this method symbol override `other' symbol, when both are seen as 532 * members of class `origin'? It is assumed that _other is a member 533 * of origin. 534 * 535 * It is assumed that both symbols have the same name. The static 536 * modifier is ignored for this test. 537 * 538 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 539 */ 540 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { 541 return false; 542 } 543 544 /** Complete the elaboration of this symbol's definition. 545 */ 546 public void complete() throws CompletionFailure { 547 if (completer != null) { 548 Completer c = completer; 549 completer = null; 550 c.complete(this); 551 } 552 } 553 554 /** True if the symbol represents an entity that exists. 555 */ 556 public boolean exists() { 557 return true; 558 } 559 560 public Type asType() { 561 return type; 562 } 563 564 public Symbol getEnclosingElement() { 565 return owner; 566 } 567 568 public ElementKind getKind() { 569 return ElementKind.OTHER; // most unkind 570 } 571 572 public Set<Modifier> getModifiers() { 573 return Flags.asModifierSet(flags()); 574 } 575 576 public Name getSimpleName() { 577 return name; 578 } 579 580 /** 581 * This is the implementation for {@code 582 * javax.lang.model.element.Element.getAnnotationMirrors()}. 583 */ 584 @Override 585 public List<Attribute.Compound> getAnnotationMirrors() { 586 return getRawAttributes(); 587 } 588 589 /** 590 * @deprecated this method should never be used by javac internally. 591 */ 592 @Deprecated 593 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) { 594 return JavacAnnoConstructs.getAnnotation(this, annoType); 595 } 596 597 // This method is part of the javax.lang.model API, do not use this in javac code. 598 public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(Class<A> annoType) { 599 return JavacAnnoConstructs.getAnnotationsByType(this, annoType); 600 } 601 602 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList 603 public java.util.List<Symbol> getEnclosedElements() { 604 return List.nil(); 605 } 606 607 public List<TypeVariableSymbol> getTypeParameters() { 608 ListBuffer<TypeVariableSymbol> l = ListBuffer.lb(); 609 for (Type t : type.getTypeArguments()) { 610 Assert.check(t.tsym.getKind() == ElementKind.TYPE_PARAMETER); 611 l.append((TypeVariableSymbol)t.tsym); 612 } 613 return l.toList(); 614 } 615 616 public static class DelegatedSymbol<T extends Symbol> extends Symbol { 617 protected T other; 618 public DelegatedSymbol(T other) { 619 super(other.kind, other.flags_field, other.name, other.type, other.owner); 620 this.other = other; 621 } 622 public String toString() { return other.toString(); } 623 public Symbol location() { return other.location(); } 624 public Symbol location(Type site, Types types) { return other.location(site, types); } 625 public Symbol baseSymbol() { return other; } 626 public Type erasure(Types types) { return other.erasure(types); } 627 public Type externalType(Types types) { return other.externalType(types); } 628 public boolean isLocal() { return other.isLocal(); } 629 public boolean isConstructor() { return other.isConstructor(); } 630 public Name getQualifiedName() { return other.getQualifiedName(); } 631 public Name flatName() { return other.flatName(); } 632 public Scope members() { return other.members(); } 633 public boolean isInner() { return other.isInner(); } 634 public boolean hasOuterInstance() { return other.hasOuterInstance(); } 635 public ClassSymbol enclClass() { return other.enclClass(); } 636 public ClassSymbol outermostClass() { return other.outermostClass(); } 637 public PackageSymbol packge() { return other.packge(); } 638 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); } 639 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); } 640 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); } 641 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); } 642 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); } 643 public void complete() throws CompletionFailure { other.complete(); } 644 645 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 646 return other.accept(v, p); 647 } 648 649 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 650 return v.visitSymbol(other, p); 651 } 652 653 public T getUnderlyingSymbol() { 654 return other; 655 } 656 } 657 658 /** A base class for Symbols representing types. 659 */ 660 public static abstract class TypeSymbol extends Symbol { 661 public TypeSymbol(int kind, long flags, Name name, Type type, Symbol owner) { 662 super(kind, flags, name, type, owner); 663 } 664 /** form a fully qualified name from a name and an owner 665 */ 666 static public Name formFullName(Name name, Symbol owner) { 667 if (owner == null) return name; 668 if (((owner.kind != ERR)) && 669 ((owner.kind & (VAR | MTH)) != 0 670 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR)) 671 )) return name; 672 Name prefix = owner.getQualifiedName(); 673 if (prefix == null || prefix == prefix.table.names.empty) 674 return name; 675 else return prefix.append('.', name); 676 } 677 678 /** form a fully qualified name from a name and an owner, after 679 * converting to flat representation 680 */ 681 static public Name formFlatName(Name name, Symbol owner) { 682 if (owner == null || 683 (owner.kind & (VAR | MTH)) != 0 684 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR)) 685 ) return name; 686 char sep = owner.kind == TYP ? '$' : '.'; 687 Name prefix = owner.flatName(); 688 if (prefix == null || prefix == prefix.table.names.empty) 689 return name; 690 else return prefix.append(sep, name); 691 } 692 693 /** 694 * A total ordering between type symbols that refines the 695 * class inheritance graph. 696 * 697 * Typevariables always precede other kinds of symbols. 698 */ 699 public final boolean precedes(TypeSymbol that, Types types) { 700 if (this == that) 701 return false; 702 if (type.hasTag(that.type.getTag())) { 703 if (type.hasTag(CLASS)) { 704 return 705 types.rank(that.type) < types.rank(this.type) || 706 types.rank(that.type) == types.rank(this.type) && 707 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0; 708 } else if (type.hasTag(TYPEVAR)) { 709 return types.isSubtype(this.type, that.type); 710 } 711 } 712 return type.hasTag(TYPEVAR); 713 } 714 715 @Override 716 public java.util.List<Symbol> getEnclosedElements() { 717 List<Symbol> list = List.nil(); 718 if (kind == TYP && type.hasTag(TYPEVAR)) { 719 return list; 720 } 721 for (Scope.Entry e = members().elems; e != null; e = e.sibling) { 722 if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this) 723 list = list.prepend(e.sym); 724 } 725 return list; 726 } 727 728 @Override 729 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 730 return v.visitTypeSymbol(this, p); 731 } 732 } 733 734 /** 735 * Type variables are represented by instances of this class. 736 */ 737 public static class TypeVariableSymbol 738 extends TypeSymbol implements TypeParameterElement { 739 740 public TypeVariableSymbol(long flags, Name name, Type type, Symbol owner) { 741 super(TYP, flags, name, type, owner); 742 } 743 744 public ElementKind getKind() { 745 return ElementKind.TYPE_PARAMETER; 746 } 747 748 @Override 749 public Symbol getGenericElement() { 750 return owner; 751 } 752 753 public List<Type> getBounds() { 754 TypeVar t = (TypeVar)type; 755 Type bound = t.getUpperBound(); 756 if (!bound.isCompound()) 757 return List.of(bound); 758 ClassType ct = (ClassType)bound; 759 if (!ct.tsym.erasure_field.isInterface()) { 760 return ct.interfaces_field.prepend(ct.supertype_field); 761 } else { 762 // No superclass was given in bounds. 763 // In this case, supertype is Object, erasure is first interface. 764 return ct.interfaces_field; 765 } 766 } 767 768 @Override 769 public List<Attribute.Compound> getAnnotationMirrors() { 770 return onlyTypeVariableAnnotations(owner.getRawTypeAttributes()); 771 } 772 773 private List<Attribute.Compound> onlyTypeVariableAnnotations( 774 List<Attribute.TypeCompound> candidates) { 775 // Declaration annotations on TypeParameters are stored in type attributes 776 List<Attribute.Compound> res = List.nil(); 777 for (Attribute.TypeCompound a : candidates) { 778 if (a.position.type == TargetType.CLASS_TYPE_PARAMETER || 779 a.position.type == TargetType.METHOD_TYPE_PARAMETER) 780 res = res.prepend(a); 781 } 782 783 return res = res.reverse(); 784 } 785 786 @Override 787 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 788 return v.visitTypeParameter(this, p); 789 } 790 } 791 792 /** A class for package symbols 793 */ 794 public static class PackageSymbol extends TypeSymbol 795 implements PackageElement { 796 797 public Scope members_field; 798 public Name fullname; 799 public ClassSymbol package_info; // see bug 6443073 800 801 public PackageSymbol(Name name, Type type, Symbol owner) { 802 super(PCK, 0, name, type, owner); 803 this.members_field = null; 804 this.fullname = formFullName(name, owner); 805 } 806 807 public PackageSymbol(Name name, Symbol owner) { 808 this(name, null, owner); 809 this.type = new PackageType(this); 810 } 811 812 public String toString() { 813 return fullname.toString(); 814 } 815 816 public Name getQualifiedName() { 817 return fullname; 818 } 819 820 public boolean isUnnamed() { 821 return name.isEmpty() && owner != null; 822 } 823 824 public Scope members() { 825 if (completer != null) complete(); 826 return members_field; 827 } 828 829 public long flags() { 830 if (completer != null) complete(); 831 return flags_field; 832 } 833 834 @Override 835 public List<Attribute.Compound> getRawAttributes() { 836 if (completer != null) complete(); 837 if (package_info != null && package_info.completer != null) { 838 package_info.complete(); 839 mergeAttributes(); 840 } 841 return super.getRawAttributes(); 842 } 843 844 private void mergeAttributes() { 845 if (annotations == null && 846 package_info.annotations != null) { 847 annotations = new Annotations(this); 848 annotations.setAttributes(package_info.annotations); 849 } 850 } 851 852 /** A package "exists" if a type or package that exists has 853 * been seen within it. 854 */ 855 public boolean exists() { 856 return (flags_field & EXISTS) != 0; 857 } 858 859 public ElementKind getKind() { 860 return ElementKind.PACKAGE; 861 } 862 863 public Symbol getEnclosingElement() { 864 return null; 865 } 866 867 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 868 return v.visitPackage(this, p); 869 } 870 871 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 872 return v.visitPackageSymbol(this, p); 873 } 874 } 875 876 /** A class for class symbols 877 */ 878 public static class ClassSymbol extends TypeSymbol implements TypeElement { 879 880 /** a scope for all class members; variables, methods and inner classes 881 * type parameters are not part of this scope 882 */ 883 public Scope members_field; 884 885 /** the fully qualified name of the class, i.e. pck.outer.inner. 886 * null for anonymous classes 887 */ 888 public Name fullname; 889 890 /** the fully qualified name of the class after converting to flat 891 * representation, i.e. pck.outer$inner, 892 * set externally for local and anonymous classes 893 */ 894 public Name flatname; 895 896 /** the sourcefile where the class came from 897 */ 898 public JavaFileObject sourcefile; 899 900 /** the classfile from where to load this class 901 * this will have extension .class or .java 902 */ 903 public JavaFileObject classfile; 904 905 /** the list of translated local classes (used for generating 906 * InnerClasses attribute) 907 */ 908 public List<ClassSymbol> trans_local; 909 910 /** the constant pool of the class 911 */ 912 public Pool pool; 913 914 public ClassSymbol(long flags, Name name, Type type, Symbol owner) { 915 super(TYP, flags, name, type, owner); 916 this.members_field = null; 917 this.fullname = formFullName(name, owner); 918 this.flatname = formFlatName(name, owner); 919 this.sourcefile = null; 920 this.classfile = null; 921 this.pool = null; 922 } 923 924 public ClassSymbol(long flags, Name name, Symbol owner) { 925 this( 926 flags, 927 name, 928 new ClassType(Type.noType, null, null), 929 owner); 930 this.type.tsym = this; 931 } 932 933 /** The Java source which this symbol represents. 934 */ 935 public String toString() { 936 return className(); 937 } 938 939 public long flags() { 940 if (completer != null) complete(); 941 return flags_field; 942 } 943 944 public Scope members() { 945 if (completer != null) complete(); 946 return members_field; 947 } 948 949 @Override 950 public List<Attribute.Compound> getRawAttributes() { 951 if (completer != null) complete(); 952 return super.getRawAttributes(); 953 } 954 955 @Override 956 public List<Attribute.TypeCompound> getRawTypeAttributes() { 957 if (completer != null) complete(); 958 return super.getRawTypeAttributes(); 959 } 960 961 public Type erasure(Types types) { 962 if (erasure_field == null) 963 erasure_field = new ClassType(types.erasure(type.getEnclosingType()), 964 List.<Type>nil(), this); 965 return erasure_field; 966 } 967 968 public String className() { 969 if (name.isEmpty()) 970 return 971 Log.getLocalizedString("anonymous.class", flatname); 972 else 973 return fullname.toString(); 974 } 975 976 public Name getQualifiedName() { 977 return fullname; 978 } 979 980 public Name flatName() { 981 return flatname; 982 } 983 984 public boolean isSubClass(Symbol base, Types types) { 985 if (this == base) { 986 return true; 987 } else if ((base.flags() & INTERFACE) != 0) { 988 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t)) 989 for (List<Type> is = types.interfaces(t); 990 is.nonEmpty(); 991 is = is.tail) 992 if (is.head.tsym.isSubClass(base, types)) return true; 993 } else { 994 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t)) 995 if (t.tsym == base) return true; 996 } 997 return false; 998 } 999 1000 /** Complete the elaboration of this symbol's definition. 1001 */ 1002 public void complete() throws CompletionFailure { 1003 try { 1004 super.complete(); 1005 } catch (CompletionFailure ex) { 1006 // quiet error recovery 1007 flags_field |= (PUBLIC|STATIC); 1008 this.type = new ErrorType(this, Type.noType); 1009 throw ex; 1010 } 1011 } 1012 1013 public List<Type> getInterfaces() { 1014 complete(); 1015 if (type instanceof ClassType) { 1016 ClassType t = (ClassType)type; 1017 if (t.interfaces_field == null) // FIXME: shouldn't be null 1018 t.interfaces_field = List.nil(); 1019 if (t.all_interfaces_field != null) 1020 return Type.getModelTypes(t.all_interfaces_field); 1021 return t.interfaces_field; 1022 } else { 1023 return List.nil(); 1024 } 1025 } 1026 1027 public Type getSuperclass() { 1028 complete(); 1029 if (type instanceof ClassType) { 1030 ClassType t = (ClassType)type; 1031 if (t.supertype_field == null) // FIXME: shouldn't be null 1032 t.supertype_field = Type.noType; 1033 // An interface has no superclass; its supertype is Object. 1034 return t.isInterface() 1035 ? Type.noType 1036 : t.supertype_field.getModelType(); 1037 } else { 1038 return Type.noType; 1039 } 1040 } 1041 1042 public ElementKind getKind() { 1043 long flags = flags(); 1044 if ((flags & ANNOTATION) != 0) 1045 return ElementKind.ANNOTATION_TYPE; 1046 else if ((flags & INTERFACE) != 0) 1047 return ElementKind.INTERFACE; 1048 else if ((flags & ENUM) != 0) 1049 return ElementKind.ENUM; 1050 else 1051 return ElementKind.CLASS; 1052 } 1053 1054 public NestingKind getNestingKind() { 1055 complete(); 1056 if (owner.kind == PCK) 1057 return NestingKind.TOP_LEVEL; 1058 else if (name.isEmpty()) 1059 return NestingKind.ANONYMOUS; 1060 else if (owner.kind == MTH) 1061 return NestingKind.LOCAL; 1062 else 1063 return NestingKind.MEMBER; 1064 } 1065 1066 /** 1067 * Since this method works in terms of the runtime representation 1068 * of annotations, it should never be used by javac internally. 1069 */ 1070 @Override 1071 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) { 1072 return JavacAnnoConstructs.getAnnotation(this, annoType); 1073 } 1074 1075 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1076 return v.visitType(this, p); 1077 } 1078 1079 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1080 return v.visitClassSymbol(this, p); 1081 } 1082 } 1083 1084 1085 /** A class for variable symbols 1086 */ 1087 public static class VarSymbol extends Symbol implements VariableElement { 1088 1089 /** The variable's declaration position. 1090 */ 1091 public int pos = Position.NOPOS; 1092 1093 /** The variable's address. Used for different purposes during 1094 * flow analysis, translation and code generation. 1095 * Flow analysis: 1096 * If this is a blank final or local variable, its sequence number. 1097 * Translation: 1098 * If this is a private field, its access number. 1099 * Code generation: 1100 * If this is a local variable, its logical slot number. 1101 */ 1102 public int adr = -1; 1103 1104 /** Construct a variable symbol, given its flags, name, type and owner. 1105 */ 1106 public VarSymbol(long flags, Name name, Type type, Symbol owner) { 1107 super(VAR, flags, name, type, owner); 1108 } 1109 1110 /** Clone this symbol with new owner. 1111 */ 1112 public VarSymbol clone(Symbol newOwner) { 1113 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) { 1114 @Override 1115 public Symbol baseSymbol() { 1116 return VarSymbol.this; 1117 } 1118 }; 1119 v.pos = pos; 1120 v.adr = adr; 1121 v.data = data; 1122 // System.out.println("clone " + v + " in " + newOwner);//DEBUG 1123 return v; 1124 } 1125 1126 public String toString() { 1127 return name.toString(); 1128 } 1129 1130 public Symbol asMemberOf(Type site, Types types) { 1131 return new VarSymbol(flags_field, name, types.memberType(site, this), owner); 1132 } 1133 1134 public ElementKind getKind() { 1135 long flags = flags(); 1136 if ((flags & PARAMETER) != 0) { 1137 if (isExceptionParameter()) 1138 return ElementKind.EXCEPTION_PARAMETER; 1139 else 1140 return ElementKind.PARAMETER; 1141 } else if ((flags & ENUM) != 0) { 1142 return ElementKind.ENUM_CONSTANT; 1143 } else if (owner.kind == TYP || owner.kind == ERR) { 1144 return ElementKind.FIELD; 1145 } else if (isResourceVariable()) { 1146 return ElementKind.RESOURCE_VARIABLE; 1147 } else { 1148 return ElementKind.LOCAL_VARIABLE; 1149 } 1150 } 1151 1152 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1153 return v.visitVariable(this, p); 1154 } 1155 1156 public Object getConstantValue() { // Mirror API 1157 return Constants.decode(getConstValue(), type); 1158 } 1159 1160 public void setLazyConstValue(final Env<AttrContext> env, 1161 final Attr attr, 1162 final JCTree.JCExpression initializer) 1163 { 1164 setData(new Callable<Object>() { 1165 public Object call() { 1166 return attr.attribLazyConstantValue(env, initializer, type); 1167 } 1168 }); 1169 } 1170 1171 /** 1172 * The variable's constant value, if this is a constant. 1173 * Before the constant value is evaluated, it points to an 1174 * initalizer environment. If this is not a constant, it can 1175 * be used for other stuff. 1176 */ 1177 private Object data; 1178 1179 public boolean isExceptionParameter() { 1180 return data == ElementKind.EXCEPTION_PARAMETER; 1181 } 1182 1183 public boolean isResourceVariable() { 1184 return data == ElementKind.RESOURCE_VARIABLE; 1185 } 1186 1187 public Object getConstValue() { 1188 // TODO: Consider if getConstValue and getConstantValue can be collapsed 1189 if (data == ElementKind.EXCEPTION_PARAMETER || 1190 data == ElementKind.RESOURCE_VARIABLE) { 1191 return null; 1192 } else if (data instanceof Callable<?>) { 1193 // In this case, this is a final variable, with an as 1194 // yet unevaluated initializer. 1195 Callable<?> eval = (Callable<?>)data; 1196 data = null; // to make sure we don't evaluate this twice. 1197 try { 1198 data = eval.call(); 1199 } catch (Exception ex) { 1200 throw new AssertionError(ex); 1201 } 1202 } 1203 return data; 1204 } 1205 1206 public void setData(Object data) { 1207 Assert.check(!(data instanceof Env<?>), this); 1208 this.data = data; 1209 } 1210 1211 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1212 return v.visitVarSymbol(this, p); 1213 } 1214 } 1215 1216 /** A class for method symbols. 1217 */ 1218 public static class MethodSymbol extends Symbol implements ExecutableElement { 1219 1220 /** The code of the method. */ 1221 public Code code = null; 1222 1223 /** The extra (synthetic/mandated) parameters of the method. */ 1224 public List<VarSymbol> extraParams = List.nil(); 1225 1226 /** The parameters of the method. */ 1227 public List<VarSymbol> params = null; 1228 1229 /** The names of the parameters */ 1230 public List<Name> savedParameterNames; 1231 1232 /** For an attribute field accessor, its default value if any. 1233 * The value is null if none appeared in the method 1234 * declaration. 1235 */ 1236 public Attribute defaultValue = null; 1237 1238 /** Construct a method symbol, given its flags, name, type and owner. 1239 */ 1240 public MethodSymbol(long flags, Name name, Type type, Symbol owner) { 1241 super(MTH, flags, name, type, owner); 1242 if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name); 1243 } 1244 1245 /** Clone this symbol with new owner. 1246 */ 1247 public MethodSymbol clone(Symbol newOwner) { 1248 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) { 1249 @Override 1250 public Symbol baseSymbol() { 1251 return MethodSymbol.this; 1252 } 1253 }; 1254 m.code = code; 1255 return m; 1256 } 1257 1258 @Override 1259 public Set<Modifier> getModifiers() { 1260 long flags = flags(); 1261 return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags); 1262 } 1263 1264 /** The Java source which this symbol represents. 1265 */ 1266 public String toString() { 1267 if ((flags() & BLOCK) != 0) { 1268 return owner.name.toString(); 1269 } else { 1270 String s = (name == name.table.names.init) 1271 ? owner.name.toString() 1272 : name.toString(); 1273 if (type != null) { 1274 if (type.hasTag(FORALL)) 1275 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s; 1276 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")"; 1277 } 1278 return s; 1279 } 1280 } 1281 1282 public boolean isDynamic() { 1283 return false; 1284 } 1285 1286 /** find a symbol that this (proxy method) symbol implements. 1287 * @param c The class whose members are searched for 1288 * implementations 1289 */ 1290 public Symbol implemented(TypeSymbol c, Types types) { 1291 Symbol impl = null; 1292 for (List<Type> is = types.interfaces(c.type); 1293 impl == null && is.nonEmpty(); 1294 is = is.tail) { 1295 TypeSymbol i = is.head.tsym; 1296 impl = implementedIn(i, types); 1297 if (impl == null) 1298 impl = implemented(i, types); 1299 } 1300 return impl; 1301 } 1302 1303 public Symbol implementedIn(TypeSymbol c, Types types) { 1304 Symbol impl = null; 1305 for (Scope.Entry e = c.members().lookup(name); 1306 impl == null && e.scope != null; 1307 e = e.next()) { 1308 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) && 1309 // FIXME: I suspect the following requires a 1310 // subst() for a parametric return type. 1311 types.isSameType(type.getReturnType(), 1312 types.memberType(owner.type, e.sym).getReturnType())) { 1313 impl = e.sym; 1314 } 1315 } 1316 return impl; 1317 } 1318 1319 /** Will the erasure of this method be considered by the VM to 1320 * override the erasure of the other when seen from class `origin'? 1321 */ 1322 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) { 1323 if (isConstructor() || _other.kind != MTH) return false; 1324 1325 if (this == _other) return true; 1326 MethodSymbol other = (MethodSymbol)_other; 1327 1328 // check for a direct implementation 1329 if (other.isOverridableIn((TypeSymbol)owner) && 1330 types.asSuper(owner.type, other.owner) != null && 1331 types.isSameType(erasure(types), other.erasure(types))) 1332 return true; 1333 1334 // check for an inherited implementation 1335 return 1336 (flags() & ABSTRACT) == 0 && 1337 other.isOverridableIn(origin) && 1338 this.isMemberOf(origin, types) && 1339 types.isSameType(erasure(types), other.erasure(types)); 1340 } 1341 1342 /** The implementation of this (abstract) symbol in class origin, 1343 * from the VM's point of view, null if method does not have an 1344 * implementation in class. 1345 * @param origin The class of which the implementation is a member. 1346 */ 1347 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) { 1348 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) { 1349 for (Scope.Entry e = c.members().lookup(name); 1350 e.scope != null; 1351 e = e.next()) { 1352 if (e.sym.kind == MTH && 1353 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types)) 1354 return (MethodSymbol)e.sym; 1355 } 1356 } 1357 return null; 1358 } 1359 1360 /** Does this symbol override `other' symbol, when both are seen as 1361 * members of class `origin'? It is assumed that _other is a member 1362 * of origin. 1363 * 1364 * It is assumed that both symbols have the same name. The static 1365 * modifier is ignored for this test. 1366 * 1367 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 1368 */ 1369 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { 1370 if (isConstructor() || _other.kind != MTH) return false; 1371 1372 if (this == _other) return true; 1373 MethodSymbol other = (MethodSymbol)_other; 1374 1375 // check for a direct implementation 1376 if (other.isOverridableIn((TypeSymbol)owner) && 1377 types.asSuper(owner.type, other.owner) != null) { 1378 Type mt = types.memberType(owner.type, this); 1379 Type ot = types.memberType(owner.type, other); 1380 if (types.isSubSignature(mt, ot)) { 1381 if (!checkResult) 1382 return true; 1383 if (types.returnTypeSubstitutable(mt, ot)) 1384 return true; 1385 } 1386 } 1387 1388 // check for an inherited implementation 1389 if ((flags() & ABSTRACT) != 0 || 1390 ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) || 1391 !other.isOverridableIn(origin) || 1392 !this.isMemberOf(origin, types)) 1393 return false; 1394 1395 // assert types.asSuper(origin.type, other.owner) != null; 1396 Type mt = types.memberType(origin.type, this); 1397 Type ot = types.memberType(origin.type, other); 1398 return 1399 types.isSubSignature(mt, ot) && 1400 (!checkResult || types.resultSubtype(mt, ot, types.noWarnings)); 1401 } 1402 1403 private boolean isOverridableIn(TypeSymbol origin) { 1404 // JLS 8.4.6.1 1405 switch ((int)(flags_field & Flags.AccessFlags)) { 1406 case Flags.PRIVATE: 1407 return false; 1408 case Flags.PUBLIC: 1409 return !this.owner.isInterface() || 1410 (flags_field & STATIC) == 0; 1411 case Flags.PROTECTED: 1412 return (origin.flags() & INTERFACE) == 0; 1413 case 0: 1414 // for package private: can only override in the same 1415 // package 1416 return 1417 this.packge() == origin.packge() && 1418 (origin.flags() & INTERFACE) == 0; 1419 default: 1420 return false; 1421 } 1422 } 1423 1424 @Override 1425 public boolean isInheritedIn(Symbol clazz, Types types) { 1426 switch ((int)(flags_field & Flags.AccessFlags)) { 1427 case PUBLIC: 1428 return !this.owner.isInterface() || 1429 clazz == owner || 1430 (flags_field & STATIC) == 0; 1431 default: 1432 return super.isInheritedIn(clazz, types); 1433 } 1434 } 1435 1436 /** The implementation of this (abstract) symbol in class origin; 1437 * null if none exists. Synthetic methods are not considered 1438 * as possible implementations. 1439 */ 1440 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { 1441 return implementation(origin, types, checkResult, implementation_filter); 1442 } 1443 // where 1444 public static final Filter<Symbol> implementation_filter = new Filter<Symbol>() { 1445 public boolean accepts(Symbol s) { 1446 return s.kind == Kinds.MTH && 1447 (s.flags() & SYNTHETIC) == 0; 1448 } 1449 }; 1450 1451 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) { 1452 MethodSymbol res = types.implementation(this, origin, checkResult, implFilter); 1453 if (res != null) 1454 return res; 1455 // if origin is derived from a raw type, we might have missed 1456 // an implementation because we do not know enough about instantiations. 1457 // in this case continue with the supertype as origin. 1458 if (types.isDerivedRaw(origin.type) && !origin.isInterface()) 1459 return implementation(types.supertype(origin.type).tsym, types, checkResult); 1460 else 1461 return null; 1462 } 1463 1464 public List<VarSymbol> params() { 1465 owner.complete(); 1466 if (params == null) { 1467 // If ClassReader.saveParameterNames has been set true, then 1468 // savedParameterNames will be set to a list of names that 1469 // matches the types in type.getParameterTypes(). If any names 1470 // were not found in the class file, those names in the list will 1471 // be set to the empty name. 1472 // If ClassReader.saveParameterNames has been set false, then 1473 // savedParameterNames will be null. 1474 List<Name> paramNames = savedParameterNames; 1475 savedParameterNames = null; 1476 // discard the provided names if the list of names is the wrong size. 1477 if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) { 1478 paramNames = List.nil(); 1479 } 1480 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>(); 1481 List<Name> remaining = paramNames; 1482 // assert: remaining and paramNames are both empty or both 1483 // have same cardinality as type.getParameterTypes() 1484 int i = 0; 1485 for (Type t : type.getParameterTypes()) { 1486 Name paramName; 1487 if (remaining.isEmpty()) { 1488 // no names for any parameters available 1489 paramName = createArgName(i, paramNames); 1490 } else { 1491 paramName = remaining.head; 1492 remaining = remaining.tail; 1493 if (paramName.isEmpty()) { 1494 // no name for this specific parameter 1495 paramName = createArgName(i, paramNames); 1496 } 1497 } 1498 buf.append(new VarSymbol(PARAMETER, paramName, t, this)); 1499 i++; 1500 } 1501 params = buf.toList(); 1502 } 1503 return params; 1504 } 1505 1506 // Create a name for the argument at position 'index' that is not in 1507 // the exclude list. In normal use, either no names will have been 1508 // provided, in which case the exclude list is empty, or all the names 1509 // will have been provided, in which case this method will not be called. 1510 private Name createArgName(int index, List<Name> exclude) { 1511 String prefix = "arg"; 1512 while (true) { 1513 Name argName = name.table.fromString(prefix + index); 1514 if (!exclude.contains(argName)) 1515 return argName; 1516 prefix += "$"; 1517 } 1518 } 1519 1520 public Symbol asMemberOf(Type site, Types types) { 1521 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner); 1522 } 1523 1524 public ElementKind getKind() { 1525 if (name == name.table.names.init) 1526 return ElementKind.CONSTRUCTOR; 1527 else if (name == name.table.names.clinit) 1528 return ElementKind.STATIC_INIT; 1529 else if ((flags() & BLOCK) != 0) 1530 return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT; 1531 else 1532 return ElementKind.METHOD; 1533 } 1534 1535 public boolean isStaticOrInstanceInit() { 1536 return getKind() == ElementKind.STATIC_INIT || 1537 getKind() == ElementKind.INSTANCE_INIT; 1538 } 1539 1540 public Attribute getDefaultValue() { 1541 return defaultValue; 1542 } 1543 1544 public List<VarSymbol> getParameters() { 1545 return params(); 1546 } 1547 1548 public boolean isVarArgs() { 1549 return (flags() & VARARGS) != 0; 1550 } 1551 1552 public boolean isDefault() { 1553 return (flags() & DEFAULT) != 0; 1554 } 1555 1556 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1557 return v.visitExecutable(this, p); 1558 } 1559 1560 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1561 return v.visitMethodSymbol(this, p); 1562 } 1563 1564 public Type getReceiverType() { 1565 return asType().getReceiverType(); 1566 } 1567 1568 public Type getReturnType() { 1569 return asType().getReturnType(); 1570 } 1571 1572 public List<Type> getThrownTypes() { 1573 return asType().getThrownTypes(); 1574 } 1575 } 1576 1577 /** A class for invokedynamic method calls. 1578 */ 1579 public static class DynamicMethodSymbol extends MethodSymbol { 1580 1581 public Object[] staticArgs; 1582 public Symbol bsm; 1583 public int bsmKind; 1584 1585 public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) { 1586 super(0, name, type, owner); 1587 this.bsm = bsm; 1588 this.bsmKind = bsmKind; 1589 this.staticArgs = staticArgs; 1590 } 1591 1592 @Override 1593 public boolean isDynamic() { 1594 return true; 1595 } 1596 } 1597 1598 /** A class for predefined operators. 1599 */ 1600 public static class OperatorSymbol extends MethodSymbol { 1601 1602 public int opcode; 1603 1604 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) { 1605 super(PUBLIC | STATIC, name, type, owner); 1606 this.opcode = opcode; 1607 } 1608 1609 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1610 return v.visitOperatorSymbol(this, p); 1611 } 1612 } 1613 1614 /** Symbol completer interface. 1615 */ 1616 public static interface Completer { 1617 void complete(Symbol sym) throws CompletionFailure; 1618 } 1619 1620 public static class CompletionFailure extends RuntimeException { 1621 private static final long serialVersionUID = 0; 1622 public Symbol sym; 1623 1624 /** A diagnostic object describing the failure 1625 */ 1626 public JCDiagnostic diag; 1627 1628 /** A localized string describing the failure. 1629 * @deprecated Use {@code getDetail()} or {@code getMessage()} 1630 */ 1631 @Deprecated 1632 public String errmsg; 1633 1634 public CompletionFailure(Symbol sym, String errmsg) { 1635 this.sym = sym; 1636 this.errmsg = errmsg; 1637 // this.printStackTrace();//DEBUG 1638 } 1639 1640 public CompletionFailure(Symbol sym, JCDiagnostic diag) { 1641 this.sym = sym; 1642 this.diag = diag; 1643 // this.printStackTrace();//DEBUG 1644 } 1645 1646 public JCDiagnostic getDiagnostic() { 1647 return diag; 1648 } 1649 1650 @Override 1651 public String getMessage() { 1652 if (diag != null) 1653 return diag.getMessage(null); 1654 else 1655 return errmsg; 1656 } 1657 1658 public Object getDetailValue() { 1659 return (diag != null ? diag : errmsg); 1660 } 1661 1662 @Override 1663 public CompletionFailure initCause(Throwable cause) { 1664 super.initCause(cause); 1665 return this; 1666 } 1667 1668 } 1669 1670 /** 1671 * A visitor for symbols. A visitor is used to implement operations 1672 * (or relations) on symbols. Most common operations on types are 1673 * binary relations and this interface is designed for binary 1674 * relations, that is, operations on the form 1675 * Symbol × P → R. 1676 * <!-- In plain text: Type x P -> R --> 1677 * 1678 * @param <R> the return type of the operation implemented by this 1679 * visitor; use Void if no return type is needed. 1680 * @param <P> the type of the second argument (the first being the 1681 * symbol itself) of the operation implemented by this visitor; use 1682 * Void if a second argument is not needed. 1683 */ 1684 public interface Visitor<R,P> { 1685 R visitClassSymbol(ClassSymbol s, P arg); 1686 R visitMethodSymbol(MethodSymbol s, P arg); 1687 R visitPackageSymbol(PackageSymbol s, P arg); 1688 R visitOperatorSymbol(OperatorSymbol s, P arg); 1689 R visitVarSymbol(VarSymbol s, P arg); 1690 R visitTypeSymbol(TypeSymbol s, P arg); 1691 R visitSymbol(Symbol s, P arg); 1692 } 1693 }