1 /* 2 * Copyright 1999-2008 Sun Microsystems, Inc. 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. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 package com.sun.tools.javac.code; 27 28 import java.util.Set; 29 import java.util.concurrent.Callable; 30 import javax.lang.model.element.*; 31 import javax.tools.JavaFileObject; 32 33 import com.sun.tools.javac.util.*; 34 import com.sun.tools.javac.util.Name; 35 import com.sun.tools.javac.code.Type.*; 36 import com.sun.tools.javac.comp.Attr; 37 import com.sun.tools.javac.comp.AttrContext; 38 import com.sun.tools.javac.comp.Env; 39 import com.sun.tools.javac.jvm.*; 40 import com.sun.tools.javac.model.*; 41 import com.sun.tools.javac.tree.JCTree; 42 43 import static com.sun.tools.javac.code.Flags.*; 44 import static com.sun.tools.javac.code.Kinds.*; 45 import static com.sun.tools.javac.code.TypeTags.*; 46 47 /** Root class for Java symbols. It contains subclasses 48 * for specific sorts of symbols, such as variables, methods and operators, 49 * types, packages. Each subclass is represented as a static inner class 50 * inside Symbol. 51 * 52 * <p><b>This is NOT part of any API supported by Sun Microsystems. If 53 * you write code that depends on this, you do so at your own risk. 54 * This code and its internal interfaces are subject to change or 55 * deletion without notice.</b> 56 */ 57 public abstract class Symbol implements Element { 58 // public Throwable debug = new Throwable(); 59 60 /** The kind of this symbol. 61 * @see Kinds 62 */ 63 public int kind; 64 65 /** The flags of this symbol. 66 */ 67 public long flags_field; 68 69 /** An accessor method for the flags of this symbol. 70 * Flags of class symbols should be accessed through the accessor 71 * method to make sure that the class symbol is loaded. 72 */ 73 public long flags() { return flags_field; } 74 75 /** The attributes of this symbol. 76 */ 77 public List<Attribute.Compound> attributes_field; 78 79 /** An accessor method for the attributes of this symbol. 80 * Attributes of class symbols should be accessed through the accessor 81 * method to make sure that the class symbol is loaded. 82 */ 83 public List<Attribute.Compound> getAnnotationMirrors() { 84 assert attributes_field != null; 85 return attributes_field; 86 } 87 88 /** Fetch a particular annotation from a symbol. */ 89 public Attribute.Compound attribute(Symbol anno) { 90 for (Attribute.Compound a : getAnnotationMirrors()) 91 if (a.type.tsym == anno) return a; 92 return null; 93 } 94 95 /** The name of this symbol in Utf8 representation. 96 */ 97 public Name name; 98 99 /** The type of this symbol. 100 */ 101 public Type type; 102 103 /** The type annotations targeted to a tree directly owned by this symbol 104 */ 105 // type annotations are stored here for two purposes: 106 // - convenient location to store annotations for generation after erasure 107 // - a private interface for accessing type annotations parsed from 108 // classfiles 109 // the field is populated for the following declaration only 110 // class, field, variable and type parameters 111 // 112 public List<Attribute.TypeCompound> typeAnnotations; 113 114 /** The owner of this symbol. 115 */ 116 public Symbol owner; 117 118 /** The completer of this symbol. 119 */ 120 public Completer completer; 121 122 /** A cache for the type erasure of this symbol. 123 */ 124 public Type erasure_field; 125 126 /** Construct a symbol with given kind, flags, name, type and owner. 127 */ 128 public Symbol(int kind, long flags, Name name, Type type, Symbol owner) { 129 this.kind = kind; 130 this.flags_field = flags; 131 this.type = type; 132 this.owner = owner; 133 this.completer = null; 134 this.erasure_field = null; 135 this.attributes_field = List.nil(); 136 this.typeAnnotations = List.nil(); 137 this.name = name; 138 } 139 140 /** Clone this symbol with new owner. 141 * Legal only for fields and methods. 142 */ 143 public Symbol clone(Symbol newOwner) { 144 throw new AssertionError(); 145 } 146 147 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 148 return v.visitSymbol(this, p); 149 } 150 151 /** The Java source which this symbol represents. 152 * A description of this symbol; overrides Object. 153 */ 154 public String toString() { 155 return name.toString(); 156 } 157 158 /** A Java source description of the location of this symbol; used for 159 * error reporting. 160 * 161 * @return null if the symbol is a package or a toplevel class defined in 162 * the default package; otherwise, the owner symbol is returned 163 */ 164 public Symbol location() { 165 if (owner.name == null || (owner.name.isEmpty() && owner.kind != PCK && owner.kind != TYP)) { 166 return null; 167 } 168 return owner; 169 } 170 171 public Symbol location(Type site, Types types) { 172 if (owner.name == null || owner.name.isEmpty()) { 173 return location(); 174 } 175 if (owner.type.tag == CLASS) { 176 Type ownertype = types.asOuterSuper(site, owner); 177 if (ownertype != null) return ownertype.tsym; 178 } 179 return owner; 180 } 181 182 /** The symbol's erased type. 183 */ 184 public Type erasure(Types types) { 185 if (erasure_field == null) 186 erasure_field = types.erasure(type); 187 return erasure_field; 188 } 189 190 /** The external type of a symbol. This is the symbol's erased type 191 * except for constructors of inner classes which get the enclosing 192 * instance class added as first argument. 193 */ 194 public Type externalType(Types types) { 195 Type t = erasure(types); 196 if (name == name.table.names.init && owner.hasOuterInstance()) { 197 Type outerThisType = types.erasure(owner.type.getEnclosingType()); 198 return new MethodType(t.getParameterTypes().prepend(outerThisType), 199 t.getReturnType(), 200 t.getThrownTypes(), 201 t.tsym); 202 } else { 203 return t; 204 } 205 } 206 207 public boolean isStatic() { 208 return 209 (flags() & STATIC) != 0 || 210 (owner.flags() & INTERFACE) != 0 && kind != MTH; 211 } 212 213 public boolean isInterface() { 214 return (flags() & INTERFACE) != 0; 215 } 216 217 /** Is this symbol declared (directly or indirectly) local 218 * to a method or variable initializer? 219 * Also includes fields of inner classes which are in 220 * turn local to a method or variable initializer. 221 */ 222 public boolean isLocal() { 223 return 224 (owner.kind & (VAR | MTH)) != 0 || 225 (owner.kind == TYP && owner.isLocal()); 226 } 227 228 /** Is this symbol a constructor? 229 */ 230 public boolean isConstructor() { 231 return name == name.table.names.init; 232 } 233 234 /** The fully qualified name of this symbol. 235 * This is the same as the symbol's name except for class symbols, 236 * which are handled separately. 237 */ 238 public Name getQualifiedName() { 239 return name; 240 } 241 242 /** The fully qualified name of this symbol after converting to flat 243 * representation. This is the same as the symbol's name except for 244 * class symbols, which are handled separately. 245 */ 246 public Name flatName() { 247 return getQualifiedName(); 248 } 249 250 /** If this is a class or package, its members, otherwise null. 251 */ 252 public Scope members() { 253 return null; 254 } 255 256 /** A class is an inner class if it it has an enclosing instance class. 257 */ 258 public boolean isInner() { 259 return type.getEnclosingType().tag == CLASS; 260 } 261 262 /** An inner class has an outer instance if it is not an interface 263 * it has an enclosing instance class which might be referenced from the class. 264 * Nested classes can see instance members of their enclosing class. 265 * Their constructors carry an additional this$n parameter, inserted 266 * implicitly by the compiler. 267 * 268 * @see #isInner 269 */ 270 public boolean hasOuterInstance() { 271 return 272 type.getEnclosingType().tag == CLASS && (flags() & (INTERFACE | NOOUTERTHIS)) == 0; 273 } 274 275 /** The closest enclosing class of this symbol's declaration. 276 */ 277 public ClassSymbol enclClass() { 278 Symbol c = this; 279 while (c != null && 280 ((c.kind & TYP) == 0 || c.type.tag != CLASS)) { 281 c = c.owner; 282 } 283 return (ClassSymbol)c; 284 } 285 286 /** The outermost class which indirectly owns this symbol. 287 */ 288 public ClassSymbol outermostClass() { 289 Symbol sym = this; 290 Symbol prev = null; 291 while (sym.kind != PCK) { 292 prev = sym; 293 sym = sym.owner; 294 } 295 return (ClassSymbol) prev; 296 } 297 298 /** The package which indirectly owns this symbol. 299 */ 300 public PackageSymbol packge() { 301 Symbol sym = this; 302 while (sym.kind != PCK) { 303 sym = sym.owner; 304 } 305 return (PackageSymbol) sym; 306 } 307 308 /** Is this symbol a subclass of `base'? Only defined for ClassSymbols. 309 */ 310 public boolean isSubClass(Symbol base, Types types) { 311 throw new AssertionError("isSubClass " + this); 312 } 313 314 /** Fully check membership: hierarchy, protection, and hiding. 315 * Does not exclude methods not inherited due to overriding. 316 */ 317 public boolean isMemberOf(TypeSymbol clazz, Types types) { 318 return 319 owner == clazz || 320 clazz.isSubClass(owner, types) && 321 isInheritedIn(clazz, types) && 322 !hiddenIn((ClassSymbol)clazz, types); 323 } 324 325 /** Is this symbol the same as or enclosed by the given class? */ 326 public boolean isEnclosedBy(ClassSymbol clazz) { 327 for (Symbol sym = this; sym.kind != PCK; sym = sym.owner) 328 if (sym == clazz) return true; 329 return false; 330 } 331 332 /** Check for hiding. Note that this doesn't handle multiple 333 * (interface) inheritance. */ 334 private boolean hiddenIn(ClassSymbol clazz, Types types) { 335 if (kind == MTH && (flags() & STATIC) == 0) return false; 336 while (true) { 337 if (owner == clazz) return false; 338 Scope.Entry e = clazz.members().lookup(name); 339 while (e.scope != null) { 340 if (e.sym == this) return false; 341 if (e.sym.kind == kind && 342 (kind != MTH || 343 (e.sym.flags() & STATIC) != 0 && 344 types.isSubSignature(e.sym.type, type))) 345 return true; 346 e = e.next(); 347 } 348 Type superType = types.supertype(clazz.type); 349 if (superType.tag != TypeTags.CLASS) return false; 350 clazz = (ClassSymbol)superType.tsym; 351 } 352 } 353 354 /** Is this symbol inherited into a given class? 355 * PRE: If symbol's owner is a interface, 356 * it is already assumed that the interface is a superinterface 357 * of given class. 358 * @param clazz The class for which we want to establish membership. 359 * This must be a subclass of the member's owner. 360 */ 361 public boolean isInheritedIn(Symbol clazz, Types types) { 362 switch ((int)(flags_field & Flags.AccessFlags)) { 363 default: // error recovery 364 case PUBLIC: 365 return true; 366 case PRIVATE: 367 return this.owner == clazz; 368 case PROTECTED: 369 // we model interfaces as extending Object 370 return (clazz.flags() & INTERFACE) == 0; 371 case 0: 372 PackageSymbol thisPackage = this.packge(); 373 for (Symbol sup = clazz; 374 sup != null && sup != this.owner; 375 sup = types.supertype(sup.type).tsym) { 376 while (sup.type.tag == TYPEVAR) 377 sup = sup.type.getUpperBound().tsym; 378 if (sup.type.isErroneous()) 379 return true; // error recovery 380 if ((sup.flags() & COMPOUND) != 0) 381 continue; 382 if (sup.packge() != thisPackage) 383 return false; 384 } 385 return (clazz.flags() & INTERFACE) == 0; 386 } 387 } 388 389 /** The (variable or method) symbol seen as a member of given 390 * class type`site' (this might change the symbol's type). 391 * This is used exclusively for producing diagnostics. 392 */ 393 public Symbol asMemberOf(Type site, Types types) { 394 throw new AssertionError(); 395 } 396 397 /** Does this method symbol override `other' symbol, when both are seen as 398 * members of class `origin'? It is assumed that _other is a member 399 * of origin. 400 * 401 * It is assumed that both symbols have the same name. The static 402 * modifier is ignored for this test. 403 * 404 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 405 */ 406 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { 407 return false; 408 } 409 410 /** Complete the elaboration of this symbol's definition. 411 */ 412 public void complete() throws CompletionFailure { 413 if (completer != null) { 414 Completer c = completer; 415 completer = null; 416 c.complete(this); 417 } 418 } 419 420 /** True if the symbol represents an entity that exists. 421 */ 422 public boolean exists() { 423 return true; 424 } 425 426 public Type asType() { 427 return type; 428 } 429 430 public Symbol getEnclosingElement() { 431 return owner; 432 } 433 434 public ElementKind getKind() { 435 return ElementKind.OTHER; // most unkind 436 } 437 438 public Set<Modifier> getModifiers() { 439 return Flags.asModifierSet(flags()); 440 } 441 442 public Name getSimpleName() { 443 return name; 444 } 445 446 /** 447 * @deprecated this method should never be used by javac internally. 448 */ 449 @Deprecated 450 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) { 451 return JavacElements.getAnnotation(this, annoType); 452 } 453 454 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList 455 public java.util.List<Symbol> getEnclosedElements() { 456 return List.nil(); 457 } 458 459 public List<TypeSymbol> getTypeParameters() { 460 ListBuffer<TypeSymbol> l = ListBuffer.lb(); 461 for (Type t : type.getTypeArguments()) { 462 l.append(t.tsym); 463 } 464 return l.toList(); 465 } 466 467 public static class DelegatedSymbol extends Symbol { 468 protected Symbol other; 469 public DelegatedSymbol(Symbol other) { 470 super(other.kind, other.flags_field, other.name, other.type, other.owner); 471 this.other = other; 472 } 473 public String toString() { return other.toString(); } 474 public Symbol location() { return other.location(); } 475 public Symbol location(Type site, Types types) { return other.location(site, types); } 476 public Type erasure(Types types) { return other.erasure(types); } 477 public Type externalType(Types types) { return other.externalType(types); } 478 public boolean isLocal() { return other.isLocal(); } 479 public boolean isConstructor() { return other.isConstructor(); } 480 public Name getQualifiedName() { return other.getQualifiedName(); } 481 public Name flatName() { return other.flatName(); } 482 public Scope members() { return other.members(); } 483 public boolean isInner() { return other.isInner(); } 484 public boolean hasOuterInstance() { return other.hasOuterInstance(); } 485 public ClassSymbol enclClass() { return other.enclClass(); } 486 public ClassSymbol outermostClass() { return other.outermostClass(); } 487 public PackageSymbol packge() { return other.packge(); } 488 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); } 489 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); } 490 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); } 491 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); } 492 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); } 493 public void complete() throws CompletionFailure { other.complete(); } 494 495 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 496 return other.accept(v, p); 497 } 498 499 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 500 return v.visitSymbol(other, p); 501 } 502 } 503 504 /** A class for type symbols. Type variables are represented by instances 505 * of this class, classes and packages by instances of subclasses. 506 */ 507 public static class TypeSymbol 508 extends Symbol implements TypeParameterElement { 509 // Implements TypeParameterElement because type parameters don't 510 // have their own TypeSymbol subclass. 511 // TODO: type parameters should have their own TypeSymbol subclass 512 513 public TypeSymbol(long flags, Name name, Type type, Symbol owner) { 514 super(TYP, flags, name, type, owner); 515 } 516 517 /** form a fully qualified name from a name and an owner 518 */ 519 static public Name formFullName(Name name, Symbol owner) { 520 if (owner == null) return name; 521 if (((owner.kind != ERR)) && 522 ((owner.kind & (VAR | MTH)) != 0 523 || (owner.kind == TYP && owner.type.tag == TYPEVAR) 524 )) return name; 525 Name prefix = owner.getQualifiedName(); 526 if (prefix == null || prefix == prefix.table.names.empty) 527 return name; 528 else return prefix.append('.', name); 529 } 530 531 /** form a fully qualified name from a name and an owner, after 532 * converting to flat representation 533 */ 534 static public Name formFlatName(Name name, Symbol owner) { 535 if (owner == null || 536 (owner.kind & (VAR | MTH)) != 0 537 || (owner.kind == TYP && owner.type.tag == TYPEVAR) 538 ) return name; 539 char sep = owner.kind == TYP ? '$' : '.'; 540 Name prefix = owner.flatName(); 541 if (prefix == null || prefix == prefix.table.names.empty) 542 return name; 543 else return prefix.append(sep, name); 544 } 545 546 /** 547 * A total ordering between type symbols that refines the 548 * class inheritance graph. 549 * 550 * Typevariables always precede other kinds of symbols. 551 */ 552 public final boolean precedes(TypeSymbol that, Types types) { 553 if (this == that) 554 return false; 555 if (this.type.tag == that.type.tag) { 556 if (this.type.tag == CLASS) { 557 return 558 types.rank(that.type) < types.rank(this.type) || 559 types.rank(that.type) == types.rank(this.type) && 560 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0; 561 } else if (this.type.tag == TYPEVAR) { 562 return types.isSubtype(this.type, that.type); 563 } 564 } 565 return this.type.tag == TYPEVAR; 566 } 567 568 // For type params; overridden in subclasses. 569 public ElementKind getKind() { 570 return ElementKind.TYPE_PARAMETER; 571 } 572 573 public java.util.List<Symbol> getEnclosedElements() { 574 List<Symbol> list = List.nil(); 575 for (Scope.Entry e = members().elems; e != null; e = e.sibling) { 576 if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this) 577 list = list.prepend(e.sym); 578 } 579 return list; 580 } 581 582 // For type params. 583 // Perhaps not needed if getEnclosingElement can be spec'ed 584 // to do the same thing. 585 // TODO: getGenericElement() might not be needed 586 public Symbol getGenericElement() { 587 return owner; 588 } 589 590 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 591 assert type.tag == TYPEVAR; // else override will be invoked 592 return v.visitTypeParameter(this, p); 593 } 594 595 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 596 return v.visitTypeSymbol(this, p); 597 } 598 599 public List<Type> getBounds() { 600 TypeVar t = (TypeVar)type; 601 Type bound = t.getUpperBound(); 602 if (!bound.isCompound()) 603 return List.of(bound); 604 ClassType ct = (ClassType)bound; 605 if (!ct.tsym.erasure_field.isInterface()) { 606 return ct.interfaces_field.prepend(ct.supertype_field); 607 } else { 608 // No superclass was given in bounds. 609 // In this case, supertype is Object, erasure is first interface. 610 return ct.interfaces_field; 611 } 612 } 613 } 614 615 /** A class for package symbols 616 */ 617 public static class PackageSymbol extends TypeSymbol 618 implements PackageElement { 619 620 public Scope members_field; 621 public Name fullname; 622 public ClassSymbol package_info; // see bug 6443073 623 624 public PackageSymbol(Name name, Type type, Symbol owner) { 625 super(0, name, type, owner); 626 this.kind = PCK; 627 this.members_field = null; 628 this.fullname = formFullName(name, owner); 629 } 630 631 public PackageSymbol(Name name, Symbol owner) { 632 this(name, null, owner); 633 this.type = new PackageType(this); 634 } 635 636 public String toString() { 637 return fullname.toString(); 638 } 639 640 public Name getQualifiedName() { 641 return fullname; 642 } 643 644 public boolean isUnnamed() { 645 return name.isEmpty() && owner != null; 646 } 647 648 public Scope members() { 649 if (completer != null) complete(); 650 return members_field; 651 } 652 653 public long flags() { 654 if (completer != null) complete(); 655 return flags_field; 656 } 657 658 public List<Attribute.Compound> getAnnotationMirrors() { 659 if (completer != null) complete(); 660 if (package_info != null && package_info.completer != null) { 661 package_info.complete(); 662 if (attributes_field.isEmpty()) 663 attributes_field = package_info.attributes_field; 664 } 665 assert attributes_field != null; 666 return attributes_field; 667 } 668 669 /** A package "exists" if a type or package that exists has 670 * been seen within it. 671 */ 672 public boolean exists() { 673 return (flags_field & EXISTS) != 0; 674 } 675 676 public ElementKind getKind() { 677 return ElementKind.PACKAGE; 678 } 679 680 public Symbol getEnclosingElement() { 681 return null; 682 } 683 684 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 685 return v.visitPackage(this, p); 686 } 687 688 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 689 return v.visitPackageSymbol(this, p); 690 } 691 } 692 693 /** A class for class symbols 694 */ 695 public static class ClassSymbol extends TypeSymbol implements TypeElement { 696 697 /** a scope for all class members; variables, methods and inner classes 698 * type parameters are not part of this scope 699 */ 700 public Scope members_field; 701 702 /** the fully qualified name of the class, i.e. pck.outer.inner. 703 * null for anonymous classes 704 */ 705 public Name fullname; 706 707 /** the fully qualified name of the class after converting to flat 708 * representation, i.e. pck.outer$inner, 709 * set externally for local and anonymous classes 710 */ 711 public Name flatname; 712 713 /** the sourcefile where the class came from 714 */ 715 public JavaFileObject sourcefile; 716 717 /** the classfile from where to load this class 718 * this will have extension .class or .java 719 */ 720 public JavaFileObject classfile; 721 722 /** the constant pool of the class 723 */ 724 public Pool pool; 725 726 public ClassSymbol(long flags, Name name, Type type, Symbol owner) { 727 super(flags, name, type, owner); 728 this.members_field = null; 729 this.fullname = formFullName(name, owner); 730 this.flatname = formFlatName(name, owner); 731 this.sourcefile = null; 732 this.classfile = null; 733 this.pool = null; 734 } 735 736 public ClassSymbol(long flags, Name name, Symbol owner) { 737 this( 738 flags, 739 name, 740 new ClassType(Type.noType, null, null), 741 owner); 742 this.type.tsym = this; 743 } 744 745 /** The Java source which this symbol represents. 746 */ 747 public String toString() { 748 return className(); 749 } 750 751 public long flags() { 752 if (completer != null) complete(); 753 return flags_field; 754 } 755 756 public Scope members() { 757 if (completer != null) complete(); 758 return members_field; 759 } 760 761 public List<Attribute.Compound> getAnnotationMirrors() { 762 if (completer != null) complete(); 763 assert attributes_field != null; 764 return attributes_field; 765 } 766 767 public Type erasure(Types types) { 768 if (erasure_field == null) 769 erasure_field = new ClassType(types.erasure(type.getEnclosingType()), 770 List.<Type>nil(), this); 771 return erasure_field; 772 } 773 774 public String className() { 775 if (name.isEmpty()) 776 return 777 Log.getLocalizedString("anonymous.class", flatname); 778 else 779 return fullname.toString(); 780 } 781 782 public Name getQualifiedName() { 783 return fullname; 784 } 785 786 public Name flatName() { 787 return flatname; 788 } 789 790 public boolean isSubClass(Symbol base, Types types) { 791 if (this == base) { 792 return true; 793 } else if ((base.flags() & INTERFACE) != 0) { 794 for (Type t = type; t.tag == CLASS; t = types.supertype(t)) 795 for (List<Type> is = types.interfaces(t); 796 is.nonEmpty(); 797 is = is.tail) 798 if (is.head.tsym.isSubClass(base, types)) return true; 799 } else { 800 for (Type t = type; t.tag == CLASS; t = types.supertype(t)) 801 if (t.tsym == base) return true; 802 } 803 return false; 804 } 805 806 /** Complete the elaboration of this symbol's definition. 807 */ 808 public void complete() throws CompletionFailure { 809 try { 810 super.complete(); 811 } catch (CompletionFailure ex) { 812 // quiet error recovery 813 flags_field |= (PUBLIC|STATIC); 814 this.type = new ErrorType(this, Type.noType); 815 throw ex; 816 } 817 } 818 819 public List<Type> getInterfaces() { 820 complete(); 821 if (type instanceof ClassType) { 822 ClassType t = (ClassType)type; 823 if (t.interfaces_field == null) // FIXME: shouldn't be null 824 t.interfaces_field = List.nil(); 825 return t.interfaces_field; 826 } else { 827 return List.nil(); 828 } 829 } 830 831 public Type getSuperclass() { 832 complete(); 833 if (type instanceof ClassType) { 834 ClassType t = (ClassType)type; 835 if (t.supertype_field == null) // FIXME: shouldn't be null 836 t.supertype_field = Type.noType; 837 // An interface has no superclass; its supertype is Object. 838 return t.isInterface() 839 ? Type.noType 840 : t.supertype_field; 841 } else { 842 return Type.noType; 843 } 844 } 845 846 public ElementKind getKind() { 847 long flags = flags(); 848 if ((flags & ANNOTATION) != 0) 849 return ElementKind.ANNOTATION_TYPE; 850 else if ((flags & INTERFACE) != 0) 851 return ElementKind.INTERFACE; 852 else if ((flags & ENUM) != 0) 853 return ElementKind.ENUM; 854 else 855 return ElementKind.CLASS; 856 } 857 858 public NestingKind getNestingKind() { 859 complete(); 860 if (owner.kind == PCK) 861 return NestingKind.TOP_LEVEL; 862 else if (name.isEmpty()) 863 return NestingKind.ANONYMOUS; 864 else if (owner.kind == MTH) 865 return NestingKind.LOCAL; 866 else 867 return NestingKind.MEMBER; 868 } 869 870 /** 871 * @deprecated this method should never be used by javac internally. 872 */ 873 @Override @Deprecated 874 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) { 875 return JavacElements.getAnnotation(this, annoType); 876 } 877 878 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 879 return v.visitType(this, p); 880 } 881 882 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 883 return v.visitClassSymbol(this, p); 884 } 885 } 886 887 888 /** A class for variable symbols 889 */ 890 public static class VarSymbol extends Symbol implements VariableElement { 891 892 /** The variable's declaration position. 893 */ 894 public int pos = Position.NOPOS; 895 896 /** The variable's address. Used for different purposes during 897 * flow analysis, translation and code generation. 898 * Flow analysis: 899 * If this is a blank final or local variable, its sequence number. 900 * Translation: 901 * If this is a private field, its access number. 902 * Code generation: 903 * If this is a local variable, its logical slot number. 904 */ 905 public int adr = -1; 906 907 /** Construct a variable symbol, given its flags, name, type and owner. 908 */ 909 public VarSymbol(long flags, Name name, Type type, Symbol owner) { 910 super(VAR, flags, name, type, owner); 911 } 912 913 /** Clone this symbol with new owner. 914 */ 915 public VarSymbol clone(Symbol newOwner) { 916 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner); 917 v.pos = pos; 918 v.adr = adr; 919 v.data = data; 920 // System.out.println("clone " + v + " in " + newOwner);//DEBUG 921 return v; 922 } 923 924 public String toString() { 925 return name.toString(); 926 } 927 928 public Symbol asMemberOf(Type site, Types types) { 929 return new VarSymbol(flags_field, name, types.memberType(site, this), owner); 930 } 931 932 public ElementKind getKind() { 933 long flags = flags(); 934 if ((flags & PARAMETER) != 0) { 935 if (isExceptionParameter()) 936 return ElementKind.EXCEPTION_PARAMETER; 937 else 938 return ElementKind.PARAMETER; 939 } else if ((flags & ENUM) != 0) { 940 return ElementKind.ENUM_CONSTANT; 941 } else if (owner.kind == TYP || owner.kind == ERR) { 942 return ElementKind.FIELD; 943 } else { 944 return ElementKind.LOCAL_VARIABLE; 945 } 946 } 947 948 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 949 return v.visitVariable(this, p); 950 } 951 952 public Object getConstantValue() { // Mirror API 953 return Constants.decode(getConstValue(), type); 954 } 955 956 public void setLazyConstValue(final Env<AttrContext> env, 957 final Log log, 958 final Attr attr, 959 final JCTree.JCExpression initializer) 960 { 961 setData(new Callable<Object>() { 962 public Object call() { 963 JavaFileObject source = log.useSource(env.toplevel.sourcefile); 964 try { 965 Type itype = attr.attribExpr(initializer, env, type); 966 if (itype.constValue() != null) 967 return attr.coerce(itype, type).constValue(); 968 else 969 return null; 970 } finally { 971 log.useSource(source); 972 } 973 } 974 }); 975 } 976 977 /** 978 * The variable's constant value, if this is a constant. 979 * Before the constant value is evaluated, it points to an 980 * initalizer environment. If this is not a constant, it can 981 * be used for other stuff. 982 */ 983 private Object data; 984 985 public boolean isExceptionParameter() { 986 return data == ElementKind.EXCEPTION_PARAMETER; 987 } 988 989 public Object getConstValue() { 990 // TODO: Consider if getConstValue and getConstantValue can be collapsed 991 if (data == ElementKind.EXCEPTION_PARAMETER) { 992 return null; 993 } else if (data instanceof Callable<?>) { 994 // In this case, this is final a variable, with an as 995 // yet unevaluated initializer. 996 Callable<?> eval = (Callable<?>)data; 997 data = null; // to make sure we don't evaluate this twice. 998 try { 999 data = eval.call(); 1000 } catch (Exception ex) { 1001 throw new AssertionError(ex); 1002 } 1003 } 1004 return data; 1005 } 1006 1007 public void setData(Object data) { 1008 assert !(data instanceof Env<?>) : this; 1009 this.data = data; 1010 } 1011 1012 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1013 return v.visitVarSymbol(this, p); 1014 } 1015 } 1016 1017 /** A class for method symbols. 1018 */ 1019 public static class MethodSymbol extends Symbol implements ExecutableElement { 1020 1021 /** The code of the method. */ 1022 public Code code = null; 1023 1024 /** The parameters of the method. */ 1025 public List<VarSymbol> params = null; 1026 1027 /** The names of the parameters */ 1028 public List<Name> savedParameterNames; 1029 1030 /** For an attribute field accessor, its default value if any. 1031 * The value is null if none appeared in the method 1032 * declaration. 1033 */ 1034 public Attribute defaultValue = null; 1035 1036 /** Construct a method symbol, given its flags, name, type and owner. 1037 */ 1038 public MethodSymbol(long flags, Name name, Type type, Symbol owner) { 1039 super(MTH, flags, name, type, owner); 1040 assert owner.type.tag != TYPEVAR : owner + "." + name; 1041 } 1042 1043 /** Clone this symbol with new owner. 1044 */ 1045 public MethodSymbol clone(Symbol newOwner) { 1046 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner); 1047 m.code = code; 1048 return m; 1049 } 1050 1051 /** The Java source which this symbol represents. 1052 */ 1053 public String toString() { 1054 if ((flags() & BLOCK) != 0) { 1055 return owner.name.toString(); 1056 } else { 1057 String s = (name == name.table.names.init) 1058 ? owner.name.toString() 1059 : name.toString(); 1060 if (type != null) { 1061 if (type.tag == FORALL) 1062 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s; 1063 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")"; 1064 } 1065 return s; 1066 } 1067 } 1068 1069 /** find a symbol that this (proxy method) symbol implements. 1070 * @param c The class whose members are searched for 1071 * implementations 1072 */ 1073 public Symbol implemented(TypeSymbol c, Types types) { 1074 Symbol impl = null; 1075 for (List<Type> is = types.interfaces(c.type); 1076 impl == null && is.nonEmpty(); 1077 is = is.tail) { 1078 TypeSymbol i = is.head.tsym; 1079 for (Scope.Entry e = i.members().lookup(name); 1080 impl == null && e.scope != null; 1081 e = e.next()) { 1082 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) && 1083 // FIXME: I suspect the following requires a 1084 // subst() for a parametric return type. 1085 types.isSameType(type.getReturnType(), 1086 types.memberType(owner.type, e.sym).getReturnType())) { 1087 impl = e.sym; 1088 } 1089 if (impl == null) 1090 impl = implemented(i, types); 1091 } 1092 } 1093 return impl; 1094 } 1095 1096 /** Will the erasure of this method be considered by the VM to 1097 * override the erasure of the other when seen from class `origin'? 1098 */ 1099 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) { 1100 if (isConstructor() || _other.kind != MTH) return false; 1101 1102 if (this == _other) return true; 1103 MethodSymbol other = (MethodSymbol)_other; 1104 1105 // check for a direct implementation 1106 if (other.isOverridableIn((TypeSymbol)owner) && 1107 types.asSuper(owner.type, other.owner) != null && 1108 types.isSameType(erasure(types), other.erasure(types))) 1109 return true; 1110 1111 // check for an inherited implementation 1112 return 1113 (flags() & ABSTRACT) == 0 && 1114 other.isOverridableIn(origin) && 1115 this.isMemberOf(origin, types) && 1116 types.isSameType(erasure(types), other.erasure(types)); 1117 } 1118 1119 /** The implementation of this (abstract) symbol in class origin, 1120 * from the VM's point of view, null if method does not have an 1121 * implementation in class. 1122 * @param origin The class of which the implementation is a member. 1123 */ 1124 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) { 1125 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) { 1126 for (Scope.Entry e = c.members().lookup(name); 1127 e.scope != null; 1128 e = e.next()) { 1129 if (e.sym.kind == MTH && 1130 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types)) 1131 return (MethodSymbol)e.sym; 1132 } 1133 } 1134 return null; 1135 } 1136 1137 /** Does this symbol override `other' symbol, when both are seen as 1138 * members of class `origin'? It is assumed that _other is a member 1139 * of origin. 1140 * 1141 * It is assumed that both symbols have the same name. The static 1142 * modifier is ignored for this test. 1143 * 1144 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 1145 */ 1146 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { 1147 if (isConstructor() || _other.kind != MTH) return false; 1148 1149 if (this == _other) return true; 1150 MethodSymbol other = (MethodSymbol)_other; 1151 1152 // check for a direct implementation 1153 if (other.isOverridableIn((TypeSymbol)owner) && 1154 types.asSuper(owner.type, other.owner) != null) { 1155 Type mt = types.memberType(owner.type, this); 1156 Type ot = types.memberType(owner.type, other); 1157 if (types.isSubSignature(mt, ot)) { 1158 if (!checkResult) 1159 return true; 1160 if (types.returnTypeSubstitutable(mt, ot)) 1161 return true; 1162 } 1163 } 1164 1165 // check for an inherited implementation 1166 if ((flags() & ABSTRACT) != 0 || 1167 (other.flags() & ABSTRACT) == 0 || 1168 !other.isOverridableIn(origin) || 1169 !this.isMemberOf(origin, types)) 1170 return false; 1171 1172 // assert types.asSuper(origin.type, other.owner) != null; 1173 Type mt = types.memberType(origin.type, this); 1174 Type ot = types.memberType(origin.type, other); 1175 return 1176 types.isSubSignature(mt, ot) && 1177 (!checkResult || types.resultSubtype(mt, ot, Warner.noWarnings)); 1178 } 1179 1180 private boolean isOverridableIn(TypeSymbol origin) { 1181 // JLS3 8.4.6.1 1182 switch ((int)(flags_field & Flags.AccessFlags)) { 1183 case Flags.PRIVATE: 1184 return false; 1185 case Flags.PUBLIC: 1186 return true; 1187 case Flags.PROTECTED: 1188 return (origin.flags() & INTERFACE) == 0; 1189 case 0: 1190 // for package private: can only override in the same 1191 // package 1192 return 1193 this.packge() == origin.packge() && 1194 (origin.flags() & INTERFACE) == 0; 1195 default: 1196 return false; 1197 } 1198 } 1199 1200 /** The implementation of this (abstract) symbol in class origin; 1201 * null if none exists. Synthetic methods are not considered 1202 * as possible implementations. 1203 */ 1204 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { 1205 MethodSymbol res = types.implementation(this, origin, types, checkResult); 1206 if (res != null) 1207 return res; 1208 // if origin is derived from a raw type, we might have missed 1209 // an implementation because we do not know enough about instantiations. 1210 // in this case continue with the supertype as origin. 1211 if (types.isDerivedRaw(origin.type)) 1212 return implementation(types.supertype(origin.type).tsym, types, checkResult); 1213 else 1214 return null; 1215 } 1216 1217 public List<VarSymbol> params() { 1218 owner.complete(); 1219 if (params == null) { 1220 // If ClassReader.saveParameterNames has been set true, then 1221 // savedParameterNames will be set to a list of names that 1222 // matches the types in type.getParameterTypes(). If any names 1223 // were not found in the class file, those names in the list will 1224 // be set to the empty name. 1225 // If ClassReader.saveParameterNames has been set false, then 1226 // savedParameterNames will be null. 1227 List<Name> paramNames = savedParameterNames; 1228 savedParameterNames = null; 1229 // discard the provided names if the list of names is the wrong size. 1230 if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) 1231 paramNames = List.nil(); 1232 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>(); 1233 List<Name> remaining = paramNames; 1234 // assert: remaining and paramNames are both empty or both 1235 // have same cardinality as type.getParameterTypes() 1236 int i = 0; 1237 for (Type t : type.getParameterTypes()) { 1238 Name paramName; 1239 if (remaining.isEmpty()) { 1240 // no names for any parameters available 1241 paramName = createArgName(i, paramNames); 1242 } else { 1243 paramName = remaining.head; 1244 remaining = remaining.tail; 1245 if (paramName.isEmpty()) { 1246 // no name for this specific parameter 1247 paramName = createArgName(i, paramNames); 1248 } 1249 } 1250 buf.append(new VarSymbol(PARAMETER, paramName, t, this)); 1251 i++; 1252 } 1253 params = buf.toList(); 1254 } 1255 return params; 1256 } 1257 1258 // Create a name for the argument at position 'index' that is not in 1259 // the exclude list. In normal use, either no names will have been 1260 // provided, in which case the exclude list is empty, or all the names 1261 // will have been provided, in which case this method will not be called. 1262 private Name createArgName(int index, List<Name> exclude) { 1263 String prefix = "arg"; 1264 while (true) { 1265 Name argName = name.table.fromString(prefix + index); 1266 if (!exclude.contains(argName)) 1267 return argName; 1268 prefix += "$"; 1269 } 1270 } 1271 1272 public Symbol asMemberOf(Type site, Types types) { 1273 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner); 1274 } 1275 1276 public ElementKind getKind() { 1277 if (name == name.table.names.init) 1278 return ElementKind.CONSTRUCTOR; 1279 else if (name == name.table.names.clinit) 1280 return ElementKind.STATIC_INIT; 1281 else 1282 return ElementKind.METHOD; 1283 } 1284 1285 public Attribute getDefaultValue() { 1286 return defaultValue; 1287 } 1288 1289 public List<VarSymbol> getParameters() { 1290 return params(); 1291 } 1292 1293 public boolean isVarArgs() { 1294 return (flags() & VARARGS) != 0; 1295 } 1296 1297 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1298 return v.visitExecutable(this, p); 1299 } 1300 1301 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1302 return v.visitMethodSymbol(this, p); 1303 } 1304 1305 public Type getReturnType() { 1306 return asType().getReturnType(); 1307 } 1308 1309 public List<Type> getThrownTypes() { 1310 return asType().getThrownTypes(); 1311 } 1312 } 1313 1314 /** A class for predefined operators. 1315 */ 1316 public static class OperatorSymbol extends MethodSymbol { 1317 1318 public int opcode; 1319 1320 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) { 1321 super(PUBLIC | STATIC, name, type, owner); 1322 this.opcode = opcode; 1323 } 1324 1325 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1326 return v.visitOperatorSymbol(this, p); 1327 } 1328 } 1329 1330 /** Symbol completer interface. 1331 */ 1332 public static interface Completer { 1333 void complete(Symbol sym) throws CompletionFailure; 1334 } 1335 1336 public static class CompletionFailure extends RuntimeException { 1337 private static final long serialVersionUID = 0; 1338 public Symbol sym; 1339 1340 /** A diagnostic object describing the failure 1341 */ 1342 public JCDiagnostic diag; 1343 1344 /** A localized string describing the failure. 1345 * @deprecated Use {@code getDetail()} or {@code getMessage()} 1346 */ 1347 @Deprecated 1348 public String errmsg; 1349 1350 public CompletionFailure(Symbol sym, String errmsg) { 1351 this.sym = sym; 1352 this.errmsg = errmsg; 1353 // this.printStackTrace();//DEBUG 1354 } 1355 1356 public CompletionFailure(Symbol sym, JCDiagnostic diag) { 1357 this.sym = sym; 1358 this.diag = diag; 1359 // this.printStackTrace();//DEBUG 1360 } 1361 1362 public JCDiagnostic getDiagnostic() { 1363 return diag; 1364 } 1365 1366 @Override 1367 public String getMessage() { 1368 if (diag != null) 1369 return diag.getMessage(null); 1370 else 1371 return errmsg; 1372 } 1373 1374 public Object getDetailValue() { 1375 return (diag != null ? diag : errmsg); 1376 } 1377 1378 @Override 1379 public CompletionFailure initCause(Throwable cause) { 1380 super.initCause(cause); 1381 return this; 1382 } 1383 1384 } 1385 1386 /** 1387 * A visitor for symbols. A visitor is used to implement operations 1388 * (or relations) on symbols. Most common operations on types are 1389 * binary relations and this interface is designed for binary 1390 * relations, that is, operations on the form 1391 * Symbol × P → R. 1392 * <!-- In plain text: Type x P -> R --> 1393 * 1394 * @param <R> the return type of the operation implemented by this 1395 * visitor; use Void if no return type is needed. 1396 * @param <P> the type of the second argument (the first being the 1397 * symbol itself) of the operation implemented by this visitor; use 1398 * Void if a second argument is not needed. 1399 */ 1400 public interface Visitor<R,P> { 1401 R visitClassSymbol(ClassSymbol s, P arg); 1402 R visitMethodSymbol(MethodSymbol s, P arg); 1403 R visitPackageSymbol(PackageSymbol s, P arg); 1404 R visitOperatorSymbol(OperatorSymbol s, P arg); 1405 R visitVarSymbol(VarSymbol s, P arg); 1406 R visitTypeSymbol(TypeSymbol s, P arg); 1407 R visitSymbol(Symbol s, P arg); 1408 } 1409 }