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