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