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