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