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