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