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