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