1 /* 2 * Copyright (c) 1999, 2020, 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.lang.annotation.Annotation; 29 import java.lang.annotation.Inherited; 30 import java.util.Collections; 31 import java.util.EnumSet; 32 import java.util.Map; 33 import java.util.Set; 34 import java.util.concurrent.Callable; 35 import java.util.function.Supplier; 36 37 import javax.lang.model.element.Element; 38 import javax.lang.model.element.ElementKind; 39 import javax.lang.model.element.ElementVisitor; 40 import javax.lang.model.element.ExecutableElement; 41 import javax.lang.model.element.Modifier; 42 import javax.lang.model.element.ModuleElement; 43 import javax.lang.model.element.NestingKind; 44 import javax.lang.model.element.PackageElement; 45 import javax.lang.model.element.RecordComponentElement; 46 import javax.lang.model.element.TypeElement; 47 import javax.lang.model.element.TypeParameterElement; 48 import javax.lang.model.element.VariableElement; 49 import javax.tools.JavaFileManager; 50 import javax.tools.JavaFileObject; 51 52 import com.sun.tools.javac.code.Kinds.Kind; 53 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata; 54 import com.sun.tools.javac.code.Type.*; 55 import com.sun.tools.javac.comp.Attr; 56 import com.sun.tools.javac.comp.AttrContext; 57 import com.sun.tools.javac.comp.Env; 58 import com.sun.tools.javac.jvm.*; 59 import com.sun.tools.javac.jvm.PoolConstant; 60 import com.sun.tools.javac.tree.JCTree.JCFieldAccess; 61 import com.sun.tools.javac.tree.JCTree.JCVariableDecl; 62 import com.sun.tools.javac.tree.JCTree.Tag; 63 import com.sun.tools.javac.util.*; 64 import com.sun.tools.javac.util.DefinedBy.Api; 65 import com.sun.tools.javac.util.List; 66 import com.sun.tools.javac.util.Name; 67 68 import static com.sun.tools.javac.code.Flags.*; 69 import static com.sun.tools.javac.code.Kinds.*; 70 import static com.sun.tools.javac.code.Kinds.Kind.*; 71 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; 72 import com.sun.tools.javac.code.Scope.WriteableScope; 73 import static com.sun.tools.javac.code.TypeTag.CLASS; 74 import static com.sun.tools.javac.code.TypeTag.FORALL; 75 import static com.sun.tools.javac.code.TypeTag.TYPEVAR; 76 import static com.sun.tools.javac.jvm.ByteCodes.iadd; 77 import static com.sun.tools.javac.jvm.ByteCodes.ishll; 78 import static com.sun.tools.javac.jvm.ByteCodes.lushrl; 79 import static com.sun.tools.javac.jvm.ByteCodes.lxor; 80 import static com.sun.tools.javac.jvm.ByteCodes.string_add; 81 82 /** Root class for Java symbols. It contains subclasses 83 * for specific sorts of symbols, such as variables, methods and operators, 84 * types, packages. Each subclass is represented as a static inner class 85 * inside Symbol. 86 * 87 * <p><b>This is NOT part of any supported API. 88 * If you write code that depends on this, you do so at your own risk. 89 * This code and its internal interfaces are subject to change or 90 * deletion without notice.</b> 91 */ 92 public abstract class Symbol extends AnnoConstruct implements PoolConstant, Element { 93 94 /** The kind of this symbol. 95 * @see Kinds 96 */ 97 public Kind kind; 98 99 /** The flags of this symbol. 100 */ 101 public long flags_field; 102 103 /** An accessor method for the flags of this symbol. 104 * Flags of class symbols should be accessed through the accessor 105 * method to make sure that the class symbol is loaded. 106 */ flags()107 public long flags() { return flags_field; } 108 109 /** The name of this symbol in Utf8 representation. 110 */ 111 public Name name; 112 113 /** The type of this symbol. 114 */ 115 public Type type; 116 117 /** The owner of this symbol. 118 */ 119 public Symbol owner; 120 121 /** The completer of this symbol. 122 * This should never equal null (NULL_COMPLETER should be used instead). 123 */ 124 public Completer completer; 125 126 /** A cache for the type erasure of this symbol. 127 */ 128 public Type erasure_field; 129 130 // <editor-fold defaultstate="collapsed" desc="annotations"> 131 132 /** The attributes of this symbol are contained in this 133 * SymbolMetadata. The SymbolMetadata instance is NOT immutable. 134 */ 135 protected SymbolMetadata metadata; 136 137 138 /** An accessor method for the attributes of this symbol. 139 * Attributes of class symbols should be accessed through the accessor 140 * method to make sure that the class symbol is loaded. 141 */ getRawAttributes()142 public List<Attribute.Compound> getRawAttributes() { 143 return (metadata == null) 144 ? List.nil() 145 : metadata.getDeclarationAttributes(); 146 } 147 148 /** An accessor method for the type attributes of this symbol. 149 * Attributes of class symbols should be accessed through the accessor 150 * method to make sure that the class symbol is loaded. 151 */ getRawTypeAttributes()152 public List<Attribute.TypeCompound> getRawTypeAttributes() { 153 return (metadata == null) 154 ? List.nil() 155 : metadata.getTypeAttributes(); 156 } 157 158 /** Fetch a particular annotation from a symbol. */ attribute(Symbol anno)159 public Attribute.Compound attribute(Symbol anno) { 160 for (Attribute.Compound a : getRawAttributes()) { 161 if (a.type.tsym == anno) return a; 162 } 163 return null; 164 } 165 annotationsPendingCompletion()166 public boolean annotationsPendingCompletion() { 167 return metadata == null ? false : metadata.pendingCompletion(); 168 } 169 appendAttributes(List<Attribute.Compound> l)170 public void appendAttributes(List<Attribute.Compound> l) { 171 if (l.nonEmpty()) { 172 initedMetadata().append(l); 173 } 174 } 175 appendClassInitTypeAttributes(List<Attribute.TypeCompound> l)176 public void appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) { 177 if (l.nonEmpty()) { 178 initedMetadata().appendClassInitTypeAttributes(l); 179 } 180 } 181 appendInitTypeAttributes(List<Attribute.TypeCompound> l)182 public void appendInitTypeAttributes(List<Attribute.TypeCompound> l) { 183 if (l.nonEmpty()) { 184 initedMetadata().appendInitTypeAttributes(l); 185 } 186 } 187 appendUniqueTypeAttributes(List<Attribute.TypeCompound> l)188 public void appendUniqueTypeAttributes(List<Attribute.TypeCompound> l) { 189 if (l.nonEmpty()) { 190 initedMetadata().appendUniqueTypes(l); 191 } 192 } 193 getClassInitTypeAttributes()194 public List<Attribute.TypeCompound> getClassInitTypeAttributes() { 195 return (metadata == null) 196 ? List.nil() 197 : metadata.getClassInitTypeAttributes(); 198 } 199 getInitTypeAttributes()200 public List<Attribute.TypeCompound> getInitTypeAttributes() { 201 return (metadata == null) 202 ? List.nil() 203 : metadata.getInitTypeAttributes(); 204 } 205 setInitTypeAttributes(List<Attribute.TypeCompound> l)206 public void setInitTypeAttributes(List<Attribute.TypeCompound> l) { 207 initedMetadata().setInitTypeAttributes(l); 208 } 209 setClassInitTypeAttributes(List<Attribute.TypeCompound> l)210 public void setClassInitTypeAttributes(List<Attribute.TypeCompound> l) { 211 initedMetadata().setClassInitTypeAttributes(l); 212 } 213 getDeclarationAttributes()214 public List<Attribute.Compound> getDeclarationAttributes() { 215 return (metadata == null) 216 ? List.nil() 217 : metadata.getDeclarationAttributes(); 218 } 219 hasAnnotations()220 public boolean hasAnnotations() { 221 return (metadata != null && !metadata.isEmpty()); 222 } 223 hasTypeAnnotations()224 public boolean hasTypeAnnotations() { 225 return (metadata != null && !metadata.isTypesEmpty()); 226 } 227 isCompleted()228 public boolean isCompleted() { 229 return completer.isTerminal(); 230 } 231 prependAttributes(List<Attribute.Compound> l)232 public void prependAttributes(List<Attribute.Compound> l) { 233 if (l.nonEmpty()) { 234 initedMetadata().prepend(l); 235 } 236 } 237 resetAnnotations()238 public void resetAnnotations() { 239 initedMetadata().reset(); 240 } 241 setAttributes(Symbol other)242 public void setAttributes(Symbol other) { 243 if (metadata != null || other.metadata != null) { 244 initedMetadata().setAttributes(other.metadata); 245 } 246 } 247 setDeclarationAttributes(List<Attribute.Compound> a)248 public void setDeclarationAttributes(List<Attribute.Compound> a) { 249 if (metadata != null || a.nonEmpty()) { 250 initedMetadata().setDeclarationAttributes(a); 251 } 252 } 253 setTypeAttributes(List<Attribute.TypeCompound> a)254 public void setTypeAttributes(List<Attribute.TypeCompound> a) { 255 if (metadata != null || a.nonEmpty()) { 256 if (metadata == null) 257 metadata = new SymbolMetadata(this); 258 metadata.setTypeAttributes(a); 259 } 260 } 261 initedMetadata()262 private SymbolMetadata initedMetadata() { 263 if (metadata == null) 264 metadata = new SymbolMetadata(this); 265 return metadata; 266 } 267 268 /** This method is intended for debugging only. */ getMetadata()269 public SymbolMetadata getMetadata() { 270 return metadata; 271 } 272 273 // </editor-fold> 274 275 /** Construct a symbol with given kind, flags, name, type and owner. 276 */ Symbol(Kind kind, long flags, Name name, Type type, Symbol owner)277 public Symbol(Kind kind, long flags, Name name, Type type, Symbol owner) { 278 this.kind = kind; 279 this.flags_field = flags; 280 this.type = type; 281 this.owner = owner; 282 this.completer = Completer.NULL_COMPLETER; 283 this.erasure_field = null; 284 this.name = name; 285 } 286 287 @Override poolTag()288 public int poolTag() { 289 throw new AssertionError("Invalid pool entry"); 290 } 291 292 /** Clone this symbol with new owner. 293 * Legal only for fields and methods. 294 */ clone(Symbol newOwner)295 public Symbol clone(Symbol newOwner) { 296 throw new AssertionError(); 297 } 298 accept(Symbol.Visitor<R, P> v, P p)299 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 300 return v.visitSymbol(this, p); 301 } 302 303 /** The Java source which this symbol represents. 304 * A description of this symbol; overrides Object. 305 */ toString()306 public String toString() { 307 return name.toString(); 308 } 309 310 /** A Java source description of the location of this symbol; used for 311 * error reporting. 312 * 313 * @return null if the symbol is a package or a toplevel class defined in 314 * the default package; otherwise, the owner symbol is returned 315 */ location()316 public Symbol location() { 317 if (owner.name == null || (owner.name.isEmpty() && 318 (owner.flags() & BLOCK) == 0 && 319 owner.kind != PCK && 320 owner.kind != TYP)) { 321 return null; 322 } 323 return owner; 324 } 325 location(Type site, Types types)326 public Symbol location(Type site, Types types) { 327 if (owner.name == null || owner.name.isEmpty()) { 328 return location(); 329 } 330 if (owner.type.hasTag(CLASS)) { 331 Type ownertype = types.asOuterSuper(site, owner); 332 if (ownertype != null) return ownertype.tsym; 333 } 334 return owner; 335 } 336 baseSymbol()337 public Symbol baseSymbol() { 338 return this; 339 } 340 341 /** The symbol's erased type. 342 */ erasure(Types types)343 public Type erasure(Types types) { 344 if (erasure_field == null) 345 erasure_field = types.erasure(type); 346 return erasure_field; 347 } 348 349 /** The external type of a symbol. This is the symbol's erased type 350 * except for constructors of inner classes which get the enclosing 351 * instance class added as first argument. 352 */ externalType(Types types)353 public Type externalType(Types types) { 354 Type t = erasure(types); 355 if (name == name.table.names.init && owner.hasOuterInstance()) { 356 Type outerThisType = types.erasure(owner.type.getEnclosingType()); 357 return new MethodType(t.getParameterTypes().prepend(outerThisType), 358 t.getReturnType(), 359 t.getThrownTypes(), 360 t.tsym); 361 } else { 362 return t; 363 } 364 } 365 isDeprecated()366 public boolean isDeprecated() { 367 return (flags_field & DEPRECATED) != 0; 368 } 369 hasDeprecatedAnnotation()370 public boolean hasDeprecatedAnnotation() { 371 return (flags_field & DEPRECATED_ANNOTATION) != 0; 372 } 373 isDeprecatedForRemoval()374 public boolean isDeprecatedForRemoval() { 375 return (flags_field & DEPRECATED_REMOVAL) != 0; 376 } 377 isPreviewApi()378 public boolean isPreviewApi() { 379 return (flags_field & PREVIEW_API) != 0; 380 } 381 isDeprecatableViaAnnotation()382 public boolean isDeprecatableViaAnnotation() { 383 switch (getKind()) { 384 case LOCAL_VARIABLE: 385 case PACKAGE: 386 case PARAMETER: 387 case RESOURCE_VARIABLE: 388 case EXCEPTION_PARAMETER: 389 return false; 390 default: 391 return true; 392 } 393 } 394 isStatic()395 public boolean isStatic() { 396 return 397 (flags() & STATIC) != 0 || 398 (owner.flags() & INTERFACE) != 0 && kind != MTH && 399 name != name.table.names._this; 400 } 401 isInterface()402 public boolean isInterface() { 403 return (flags() & INTERFACE) != 0; 404 } 405 isAbstract()406 public boolean isAbstract() { 407 return (flags_field & ABSTRACT) != 0; 408 } 409 isPrivate()410 public boolean isPrivate() { 411 return (flags_field & Flags.AccessFlags) == PRIVATE; 412 } 413 isPublic()414 public boolean isPublic() { 415 return (flags_field & Flags.AccessFlags) == PUBLIC; 416 } 417 isEnum()418 public boolean isEnum() { 419 return (flags() & ENUM) != 0; 420 } 421 isFinal()422 public boolean isFinal() { 423 return (flags_field & FINAL) != 0; 424 } 425 426 /** Is this symbol declared (directly or indirectly) local 427 * to a method or variable initializer? 428 * Also includes fields of inner classes which are in 429 * turn local to a method or variable initializer. 430 */ isLocal()431 public boolean isLocal() { 432 return 433 (owner.kind.matches(KindSelector.VAL_MTH) || 434 (owner.kind == TYP && owner.isLocal())); 435 } 436 437 /** Has this symbol an empty name? This includes anonymous 438 * inner classes. 439 */ isAnonymous()440 public boolean isAnonymous() { 441 return name.isEmpty(); 442 } 443 444 /** Is this symbol a constructor? 445 */ isConstructor()446 public boolean isConstructor() { 447 return name == name.table.names.init; 448 } 449 isDynamic()450 public boolean isDynamic() { 451 return false; 452 } 453 454 /** The fully qualified name of this symbol. 455 * This is the same as the symbol's name except for class symbols, 456 * which are handled separately. 457 */ getQualifiedName()458 public Name getQualifiedName() { 459 return name; 460 } 461 462 /** The fully qualified name of this symbol after converting to flat 463 * representation. This is the same as the symbol's name except for 464 * class symbols, which are handled separately. 465 */ flatName()466 public Name flatName() { 467 return getQualifiedName(); 468 } 469 470 /** If this is a class or package, its members, otherwise null. 471 */ members()472 public WriteableScope members() { 473 return null; 474 } 475 476 /** A class is an inner class if it it has an enclosing instance class. 477 */ isInner()478 public boolean isInner() { 479 return kind == TYP && type.getEnclosingType().hasTag(CLASS); 480 } 481 482 /** An inner class has an outer instance if it is not an interface 483 * it has an enclosing instance class which might be referenced from the class. 484 * Nested classes can see instance members of their enclosing class. 485 * Their constructors carry an additional this$n parameter, inserted 486 * implicitly by the compiler. 487 * 488 * @see #isInner 489 */ hasOuterInstance()490 public boolean hasOuterInstance() { 491 return 492 type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | NOOUTERTHIS)) == 0; 493 } 494 495 /** The closest enclosing class of this symbol's declaration. 496 * Warning: this (misnamed) method returns the receiver itself 497 * when the receiver is a class (as opposed to its enclosing 498 * class as one may be misled to believe.) 499 */ enclClass()500 public ClassSymbol enclClass() { 501 Symbol c = this; 502 while (c != null && 503 (!c.kind.matches(KindSelector.TYP) || !c.type.hasTag(CLASS))) { 504 c = c.owner; 505 } 506 return (ClassSymbol)c; 507 } 508 509 /** The outermost class which indirectly owns this symbol. 510 */ outermostClass()511 public ClassSymbol outermostClass() { 512 Symbol sym = this; 513 Symbol prev = null; 514 while (sym.kind != PCK) { 515 prev = sym; 516 sym = sym.owner; 517 } 518 return (ClassSymbol) prev; 519 } 520 521 /** The package which indirectly owns this symbol. 522 */ packge()523 public PackageSymbol packge() { 524 Symbol sym = this; 525 while (sym.kind != PCK) { 526 sym = sym.owner; 527 } 528 return (PackageSymbol) sym; 529 } 530 531 /** Is this symbol a subclass of `base'? Only defined for ClassSymbols. 532 */ isSubClass(Symbol base, Types types)533 public boolean isSubClass(Symbol base, Types types) { 534 throw new AssertionError("isSubClass " + this); 535 } 536 537 /** Fully check membership: hierarchy, protection, and hiding. 538 * Does not exclude methods not inherited due to overriding. 539 */ isMemberOf(TypeSymbol clazz, Types types)540 public boolean isMemberOf(TypeSymbol clazz, Types types) { 541 return 542 owner == clazz || 543 clazz.isSubClass(owner, types) && 544 isInheritedIn(clazz, types) && 545 !hiddenIn((ClassSymbol)clazz, types); 546 } 547 548 /** Is this symbol the same as or enclosed by the given class? */ isEnclosedBy(ClassSymbol clazz)549 public boolean isEnclosedBy(ClassSymbol clazz) { 550 for (Symbol sym = this; sym.kind != PCK; sym = sym.owner) 551 if (sym == clazz) return true; 552 return false; 553 } 554 hiddenIn(ClassSymbol clazz, Types types)555 private boolean hiddenIn(ClassSymbol clazz, Types types) { 556 Symbol sym = hiddenInInternal(clazz, types); 557 Assert.check(sym != null, "the result of hiddenInInternal() can't be null"); 558 /* If we find the current symbol then there is no symbol hiding it 559 */ 560 return sym != this; 561 } 562 563 /** This method looks in the supertypes graph that has the current class as the 564 * initial node, till it finds the current symbol or another symbol that hides it. 565 * If the current class has more than one supertype (extends one class and 566 * implements one or more interfaces) then null can be returned, meaning that 567 * a wrong path in the supertypes graph was selected. Null can only be returned 568 * as a temporary value, as a result of the recursive call. 569 */ hiddenInInternal(ClassSymbol currentClass, Types types)570 private Symbol hiddenInInternal(ClassSymbol currentClass, Types types) { 571 if (currentClass == owner) { 572 return this; 573 } 574 for (Symbol sym : currentClass.members().getSymbolsByName(name)) { 575 if (sym.kind == kind && 576 (kind != MTH || 577 (sym.flags() & STATIC) != 0 && 578 types.isSubSignature(sym.type, type))) { 579 return sym; 580 } 581 } 582 Symbol hiddenSym = null; 583 for (Type st : types.interfaces(currentClass.type) 584 .prepend(types.supertype(currentClass.type))) { 585 if (st != null && (st.hasTag(CLASS))) { 586 Symbol sym = hiddenInInternal((ClassSymbol)st.tsym, types); 587 if (sym == this) { 588 return this; 589 } else if (sym != null) { 590 hiddenSym = sym; 591 } 592 } 593 } 594 return hiddenSym; 595 } 596 597 /** Is this symbol accessible in a given class? 598 * PRE: If symbol's owner is a interface, 599 * it is already assumed that the interface is a superinterface 600 * the given class. 601 * @param clazz The class for which we want to establish membership. 602 * This must be a subclass of the member's owner. 603 */ isAccessibleIn(Symbol clazz, Types types)604 public final boolean isAccessibleIn(Symbol clazz, Types types) { 605 switch ((int)(flags_field & Flags.AccessFlags)) { 606 default: // error recovery 607 case PUBLIC: 608 return true; 609 case PRIVATE: 610 return this.owner == clazz; 611 case PROTECTED: 612 // we model interfaces as extending Object 613 return (clazz.flags() & INTERFACE) == 0; 614 case 0: 615 PackageSymbol thisPackage = this.packge(); 616 for (Symbol sup = clazz; 617 sup != null && sup != this.owner; 618 sup = types.supertype(sup.type).tsym) { 619 while (sup.type.hasTag(TYPEVAR)) 620 sup = sup.type.getUpperBound().tsym; 621 if (sup.type.isErroneous()) 622 return true; // error recovery 623 if ((sup.flags() & COMPOUND) != 0) 624 continue; 625 if (sup.packge() != thisPackage) 626 return false; 627 } 628 return (clazz.flags() & INTERFACE) == 0; 629 } 630 } 631 632 /** Is this symbol inherited into a given class? 633 * PRE: If symbol's owner is a interface, 634 * it is already assumed that the interface is a superinterface 635 * of the given class. 636 * @param clazz The class for which we want to establish membership. 637 * This must be a subclass of the member's owner. 638 */ isInheritedIn(Symbol clazz, Types types)639 public boolean isInheritedIn(Symbol clazz, Types types) { 640 return isAccessibleIn(clazz, types); 641 } 642 643 /** The (variable or method) symbol seen as a member of given 644 * class type`site' (this might change the symbol's type). 645 * This is used exclusively for producing diagnostics. 646 */ asMemberOf(Type site, Types types)647 public Symbol asMemberOf(Type site, Types types) { 648 throw new AssertionError(); 649 } 650 651 /** Does this method symbol override `other' symbol, when both are seen as 652 * members of class `origin'? It is assumed that _other is a member 653 * of origin. 654 * 655 * It is assumed that both symbols have the same name. The static 656 * modifier is ignored for this test. 657 * 658 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 659 */ overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult)660 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { 661 return false; 662 } 663 664 /** Complete the elaboration of this symbol's definition. 665 */ complete()666 public void complete() throws CompletionFailure { 667 if (completer != Completer.NULL_COMPLETER) { 668 Completer c = completer; 669 completer = Completer.NULL_COMPLETER; 670 c.complete(this); 671 } 672 } 673 apiComplete()674 public void apiComplete() throws CompletionFailure { 675 try { 676 complete(); 677 } catch (CompletionFailure cf) { 678 cf.dcfh.handleAPICompletionFailure(cf); 679 } 680 } 681 682 /** True if the symbol represents an entity that exists. 683 */ exists()684 public boolean exists() { 685 return true; 686 } 687 688 @DefinedBy(Api.LANGUAGE_MODEL) asType()689 public Type asType() { 690 return type; 691 } 692 693 @DefinedBy(Api.LANGUAGE_MODEL) getEnclosingElement()694 public Symbol getEnclosingElement() { 695 return owner; 696 } 697 698 @DefinedBy(Api.LANGUAGE_MODEL) getKind()699 public ElementKind getKind() { 700 return ElementKind.OTHER; // most unkind 701 } 702 703 @DefinedBy(Api.LANGUAGE_MODEL) getModifiers()704 public Set<Modifier> getModifiers() { 705 apiComplete(); 706 return Flags.asModifierSet(flags()); 707 } 708 709 @DefinedBy(Api.LANGUAGE_MODEL) getSimpleName()710 public Name getSimpleName() { 711 return name; 712 } 713 714 /** 715 * This is the implementation for {@code 716 * javax.lang.model.element.Element.getAnnotationMirrors()}. 717 */ 718 @Override @DefinedBy(Api.LANGUAGE_MODEL) getAnnotationMirrors()719 public List<Attribute.Compound> getAnnotationMirrors() { 720 apiComplete(); 721 return getRawAttributes(); 722 } 723 724 725 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList 726 @DefinedBy(Api.LANGUAGE_MODEL) getEnclosedElements()727 public java.util.List<Symbol> getEnclosedElements() { 728 return List.nil(); 729 } 730 getTypeParameters()731 public List<TypeVariableSymbol> getTypeParameters() { 732 ListBuffer<TypeVariableSymbol> l = new ListBuffer<>(); 733 for (Type t : type.getTypeArguments()) { 734 Assert.check(t.tsym.getKind() == ElementKind.TYPE_PARAMETER); 735 l.append((TypeVariableSymbol)t.tsym); 736 } 737 return l.toList(); 738 } 739 740 public static class DelegatedSymbol<T extends Symbol> extends Symbol { 741 protected T other; DelegatedSymbol(T other)742 public DelegatedSymbol(T other) { 743 super(other.kind, other.flags_field, other.name, other.type, other.owner); 744 this.other = other; 745 } toString()746 public String toString() { return other.toString(); } location()747 public Symbol location() { return other.location(); } location(Type site, Types types)748 public Symbol location(Type site, Types types) { return other.location(site, types); } baseSymbol()749 public Symbol baseSymbol() { return other; } erasure(Types types)750 public Type erasure(Types types) { return other.erasure(types); } externalType(Types types)751 public Type externalType(Types types) { return other.externalType(types); } isLocal()752 public boolean isLocal() { return other.isLocal(); } isConstructor()753 public boolean isConstructor() { return other.isConstructor(); } getQualifiedName()754 public Name getQualifiedName() { return other.getQualifiedName(); } flatName()755 public Name flatName() { return other.flatName(); } members()756 public WriteableScope members() { return other.members(); } isInner()757 public boolean isInner() { return other.isInner(); } hasOuterInstance()758 public boolean hasOuterInstance() { return other.hasOuterInstance(); } enclClass()759 public ClassSymbol enclClass() { return other.enclClass(); } outermostClass()760 public ClassSymbol outermostClass() { return other.outermostClass(); } packge()761 public PackageSymbol packge() { return other.packge(); } isSubClass(Symbol base, Types types)762 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); } isMemberOf(TypeSymbol clazz, Types types)763 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); } isEnclosedBy(ClassSymbol clazz)764 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); } isInheritedIn(Symbol clazz, Types types)765 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); } asMemberOf(Type site, Types types)766 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); } complete()767 public void complete() throws CompletionFailure { other.complete(); } 768 769 @DefinedBy(Api.LANGUAGE_MODEL) accept(ElementVisitor<R, P> v, P p)770 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 771 return other.accept(v, p); 772 } 773 accept(Symbol.Visitor<R, P> v, P p)774 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 775 return v.visitSymbol(other, p); 776 } 777 getUnderlyingSymbol()778 public T getUnderlyingSymbol() { 779 return other; 780 } 781 } 782 783 /** A base class for Symbols representing types. 784 */ 785 public static abstract class TypeSymbol extends Symbol { TypeSymbol(Kind kind, long flags, Name name, Type type, Symbol owner)786 public TypeSymbol(Kind kind, long flags, Name name, Type type, Symbol owner) { 787 super(kind, flags, name, type, owner); 788 } 789 /** form a fully qualified name from a name and an owner 790 */ formFullName(Name name, Symbol owner)791 static public Name formFullName(Name name, Symbol owner) { 792 if (owner == null) return name; 793 if ((owner.kind != ERR) && 794 (owner.kind.matches(KindSelector.VAL_MTH) || 795 (owner.kind == TYP && owner.type.hasTag(TYPEVAR)) 796 )) return name; 797 Name prefix = owner.getQualifiedName(); 798 if (prefix == null || prefix == prefix.table.names.empty) 799 return name; 800 else return prefix.append('.', name); 801 } 802 803 /** form a fully qualified name from a name and an owner, after 804 * converting to flat representation 805 */ formFlatName(Name name, Symbol owner)806 static public Name formFlatName(Name name, Symbol owner) { 807 if (owner == null || owner.kind.matches(KindSelector.VAL_MTH) || 808 (owner.kind == TYP && owner.type.hasTag(TYPEVAR)) 809 ) return name; 810 char sep = owner.kind == TYP ? '$' : '.'; 811 Name prefix = owner.flatName(); 812 if (prefix == null || prefix == prefix.table.names.empty) 813 return name; 814 else return prefix.append(sep, name); 815 } 816 817 /** 818 * A partial ordering between type symbols that refines the 819 * class inheritance graph. 820 * 821 * Type variables always precede other kinds of symbols. 822 */ precedes(TypeSymbol that, Types types)823 public final boolean precedes(TypeSymbol that, Types types) { 824 if (this == that) 825 return false; 826 if (type.hasTag(that.type.getTag())) { 827 if (type.hasTag(CLASS)) { 828 return 829 types.rank(that.type) < types.rank(this.type) || 830 types.rank(that.type) == types.rank(this.type) && 831 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0; 832 } else if (type.hasTag(TYPEVAR)) { 833 return types.isSubtype(this.type, that.type); 834 } 835 } 836 return type.hasTag(TYPEVAR); 837 } 838 839 @Override @DefinedBy(Api.LANGUAGE_MODEL) getEnclosedElements()840 public List<Symbol> getEnclosedElements() { 841 List<Symbol> list = List.nil(); 842 if (kind == TYP && type.hasTag(TYPEVAR)) { 843 return list; 844 } 845 apiComplete(); 846 for (Symbol sym : members().getSymbols(NON_RECURSIVE)) { 847 sym.apiComplete(); 848 if ((sym.flags() & SYNTHETIC) == 0 && sym.owner == this && sym.kind != ERR) { 849 list = list.prepend(sym); 850 } 851 } 852 return list; 853 } 854 getAnnotationTypeMetadata()855 public AnnotationTypeMetadata getAnnotationTypeMetadata() { 856 Assert.error("Only on ClassSymbol"); 857 return null; //unreachable 858 } 859 isAnnotationType()860 public boolean isAnnotationType() { return false; } 861 862 @Override accept(Symbol.Visitor<R, P> v, P p)863 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 864 return v.visitTypeSymbol(this, p); 865 } 866 } 867 868 /** 869 * Type variables are represented by instances of this class. 870 */ 871 public static class TypeVariableSymbol 872 extends TypeSymbol implements TypeParameterElement { 873 TypeVariableSymbol(long flags, Name name, Type type, Symbol owner)874 public TypeVariableSymbol(long flags, Name name, Type type, Symbol owner) { 875 super(TYP, flags, name, type, owner); 876 } 877 878 @DefinedBy(Api.LANGUAGE_MODEL) getKind()879 public ElementKind getKind() { 880 return ElementKind.TYPE_PARAMETER; 881 } 882 883 @Override @DefinedBy(Api.LANGUAGE_MODEL) getGenericElement()884 public Symbol getGenericElement() { 885 return owner; 886 } 887 888 @DefinedBy(Api.LANGUAGE_MODEL) getBounds()889 public List<Type> getBounds() { 890 TypeVar t = (TypeVar)type; 891 Type bound = t.getUpperBound(); 892 if (!bound.isCompound()) 893 return List.of(bound); 894 ClassType ct = (ClassType)bound; 895 if (!ct.tsym.erasure_field.isInterface()) { 896 return ct.interfaces_field.prepend(ct.supertype_field); 897 } else { 898 // No superclass was given in bounds. 899 // In this case, supertype is Object, erasure is first interface. 900 return ct.interfaces_field; 901 } 902 } 903 904 @Override @DefinedBy(Api.LANGUAGE_MODEL) getAnnotationMirrors()905 public List<Attribute.Compound> getAnnotationMirrors() { 906 // Declaration annotations on type variables are stored in type attributes 907 // on the owner of the TypeVariableSymbol 908 List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes(); 909 int index = owner.getTypeParameters().indexOf(this); 910 List<Attribute.Compound> res = List.nil(); 911 for (Attribute.TypeCompound a : candidates) { 912 if (isCurrentSymbolsAnnotation(a, index)) 913 res = res.prepend(a); 914 } 915 916 return res.reverse(); 917 } 918 919 // Helper to getAnnotation[s] 920 @Override getAttribute(Class<A> annoType)921 public <A extends Annotation> Attribute.Compound getAttribute(Class<A> annoType) { 922 String name = annoType.getName(); 923 924 // Declaration annotations on type variables are stored in type attributes 925 // on the owner of the TypeVariableSymbol 926 List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes(); 927 int index = owner.getTypeParameters().indexOf(this); 928 for (Attribute.TypeCompound anno : candidates) 929 if (isCurrentSymbolsAnnotation(anno, index) && 930 name.contentEquals(anno.type.tsym.flatName())) 931 return anno; 932 933 return null; 934 } 935 //where: isCurrentSymbolsAnnotation(Attribute.TypeCompound anno, int index)936 boolean isCurrentSymbolsAnnotation(Attribute.TypeCompound anno, int index) { 937 return (anno.position.type == TargetType.CLASS_TYPE_PARAMETER || 938 anno.position.type == TargetType.METHOD_TYPE_PARAMETER) && 939 anno.position.parameter_index == index; 940 } 941 942 943 @Override @DefinedBy(Api.LANGUAGE_MODEL) accept(ElementVisitor<R, P> v, P p)944 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 945 return v.visitTypeParameter(this, p); 946 } 947 } 948 /** A class for module symbols. 949 */ 950 public static class ModuleSymbol extends TypeSymbol 951 implements ModuleElement { 952 953 public Name version; 954 public JavaFileManager.Location sourceLocation; 955 public JavaFileManager.Location classLocation; 956 public JavaFileManager.Location patchLocation; 957 public JavaFileManager.Location patchOutputLocation; 958 959 /** All directives, in natural order. */ 960 public List<com.sun.tools.javac.code.Directive> directives; 961 public List<com.sun.tools.javac.code.Directive.RequiresDirective> requires; 962 public List<com.sun.tools.javac.code.Directive.ExportsDirective> exports; 963 public List<com.sun.tools.javac.code.Directive.OpensDirective> opens; 964 public List<com.sun.tools.javac.code.Directive.ProvidesDirective> provides; 965 public List<com.sun.tools.javac.code.Directive.UsesDirective> uses; 966 967 public ClassSymbol module_info; 968 969 public PackageSymbol unnamedPackage; 970 public Map<Name, PackageSymbol> visiblePackages; 971 public Set<ModuleSymbol> readModules; 972 public List<Symbol> enclosedPackages = List.nil(); 973 974 public Completer usesProvidesCompleter = Completer.NULL_COMPLETER; 975 public final Set<ModuleFlags> flags = EnumSet.noneOf(ModuleFlags.class); 976 public final Set<ModuleResolutionFlags> resolutionFlags = EnumSet.noneOf(ModuleResolutionFlags.class); 977 978 /** 979 * Create a ModuleSymbol with an associated module-info ClassSymbol. 980 */ create(Name name, Name module_info)981 public static ModuleSymbol create(Name name, Name module_info) { 982 ModuleSymbol msym = new ModuleSymbol(name, null); 983 ClassSymbol info = new ClassSymbol(Flags.MODULE, module_info, msym); 984 info.fullname = formFullName(module_info, msym); 985 info.flatname = info.fullname; 986 info.members_field = WriteableScope.create(info); 987 msym.module_info = info; 988 return msym; 989 } 990 ModuleSymbol(Name name, Symbol owner)991 public ModuleSymbol(Name name, Symbol owner) { 992 super(MDL, 0, name, null, owner); 993 Assert.checkNonNull(name); 994 this.type = new ModuleType(this); 995 } 996 997 @Override poolTag()998 public int poolTag() { 999 return ClassFile.CONSTANT_Module; 1000 } 1001 1002 @Override @DefinedBy(Api.LANGUAGE_MODEL) getSimpleName()1003 public Name getSimpleName() { 1004 return Convert.shortName(name); 1005 } 1006 1007 @Override @DefinedBy(Api.LANGUAGE_MODEL) isOpen()1008 public boolean isOpen() { 1009 return flags.contains(ModuleFlags.OPEN); 1010 } 1011 1012 @Override @DefinedBy(Api.LANGUAGE_MODEL) isUnnamed()1013 public boolean isUnnamed() { 1014 return name.isEmpty() && owner == null; 1015 } 1016 1017 @Override isDeprecated()1018 public boolean isDeprecated() { 1019 return hasDeprecatedAnnotation(); 1020 } 1021 isNoModule()1022 public boolean isNoModule() { 1023 return false; 1024 } 1025 1026 @Override @DefinedBy(Api.LANGUAGE_MODEL) getKind()1027 public ElementKind getKind() { 1028 return ElementKind.MODULE; 1029 } 1030 1031 @Override @DefinedBy(Api.LANGUAGE_MODEL) getDirectives()1032 public java.util.List<Directive> getDirectives() { 1033 apiComplete(); 1034 completeUsesProvides(); 1035 return Collections.unmodifiableList(directives); 1036 } 1037 completeUsesProvides()1038 public void completeUsesProvides() { 1039 if (usesProvidesCompleter != Completer.NULL_COMPLETER) { 1040 Completer c = usesProvidesCompleter; 1041 usesProvidesCompleter = Completer.NULL_COMPLETER; 1042 c.complete(this); 1043 } 1044 } 1045 1046 @Override outermostClass()1047 public ClassSymbol outermostClass() { 1048 return null; 1049 } 1050 1051 @Override toString()1052 public String toString() { 1053 // TODO: the following strings should be localized 1054 // Do this with custom anon subtypes in Symtab 1055 String n = (name == null) ? "<unknown>" 1056 : (name.isEmpty()) ? "<unnamed>" 1057 : String.valueOf(name); 1058 return n; 1059 } 1060 1061 @Override @DefinedBy(Api.LANGUAGE_MODEL) accept(ElementVisitor<R, P> v, P p)1062 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1063 return v.visitModule(this, p); 1064 } 1065 1066 @Override @DefinedBy(Api.LANGUAGE_MODEL) getEnclosedElements()1067 public List<Symbol> getEnclosedElements() { 1068 List<Symbol> list = List.nil(); 1069 for (Symbol sym : enclosedPackages) { 1070 if (sym.members().anyMatch(m -> m.kind == TYP)) 1071 list = list.prepend(sym); 1072 } 1073 return list; 1074 } 1075 reset()1076 public void reset() { 1077 this.directives = null; 1078 this.requires = null; 1079 this.exports = null; 1080 this.provides = null; 1081 this.uses = null; 1082 this.visiblePackages = null; 1083 } 1084 1085 } 1086 1087 public enum ModuleFlags { 1088 OPEN(0x0020), 1089 SYNTHETIC(0x1000), 1090 MANDATED(0x8000); 1091 value(Set<ModuleFlags> s)1092 public static int value(Set<ModuleFlags> s) { 1093 int v = 0; 1094 for (ModuleFlags f: s) 1095 v |= f.value; 1096 return v; 1097 } 1098 ModuleFlags(int value)1099 private ModuleFlags(int value) { 1100 this.value = value; 1101 } 1102 1103 public final int value; 1104 } 1105 1106 public enum ModuleResolutionFlags { 1107 DO_NOT_RESOLVE_BY_DEFAULT(0x0001), 1108 WARN_DEPRECATED(0x0002), 1109 WARN_DEPRECATED_REMOVAL(0x0004), 1110 WARN_INCUBATING(0x0008); 1111 value(Set<ModuleResolutionFlags> s)1112 public static int value(Set<ModuleResolutionFlags> s) { 1113 int v = 0; 1114 for (ModuleResolutionFlags f: s) 1115 v |= f.value; 1116 return v; 1117 } 1118 ModuleResolutionFlags(int value)1119 private ModuleResolutionFlags(int value) { 1120 this.value = value; 1121 } 1122 1123 public final int value; 1124 } 1125 1126 /** A class for package symbols 1127 */ 1128 public static class PackageSymbol extends TypeSymbol 1129 implements PackageElement { 1130 1131 public WriteableScope members_field; 1132 public Name fullname; 1133 public ClassSymbol package_info; // see bug 6443073 1134 public ModuleSymbol modle; 1135 // the file containing the documentation comments for the package 1136 public JavaFileObject sourcefile; 1137 PackageSymbol(Name name, Type type, Symbol owner)1138 public PackageSymbol(Name name, Type type, Symbol owner) { 1139 super(PCK, 0, name, type, owner); 1140 this.members_field = null; 1141 this.fullname = formFullName(name, owner); 1142 } 1143 PackageSymbol(Name name, Symbol owner)1144 public PackageSymbol(Name name, Symbol owner) { 1145 this(name, null, owner); 1146 this.type = new PackageType(this); 1147 } 1148 toString()1149 public String toString() { 1150 return fullname.toString(); 1151 } 1152 1153 @DefinedBy(Api.LANGUAGE_MODEL) getQualifiedName()1154 public Name getQualifiedName() { 1155 return fullname; 1156 } 1157 1158 @DefinedBy(Api.LANGUAGE_MODEL) isUnnamed()1159 public boolean isUnnamed() { 1160 return name.isEmpty() && owner != null; 1161 } 1162 members()1163 public WriteableScope members() { 1164 complete(); 1165 return members_field; 1166 } 1167 1168 @Override poolTag()1169 public int poolTag() { 1170 return ClassFile.CONSTANT_Package; 1171 } 1172 flags()1173 public long flags() { 1174 complete(); 1175 return flags_field; 1176 } 1177 1178 @Override getRawAttributes()1179 public List<Attribute.Compound> getRawAttributes() { 1180 complete(); 1181 if (package_info != null) { 1182 package_info.complete(); 1183 mergeAttributes(); 1184 } 1185 return super.getRawAttributes(); 1186 } 1187 mergeAttributes()1188 private void mergeAttributes() { 1189 if (metadata == null && 1190 package_info.metadata != null) { 1191 metadata = new SymbolMetadata(this); 1192 metadata.setAttributes(package_info.metadata); 1193 } 1194 } 1195 1196 /** A package "exists" if a type or package that exists has 1197 * been seen within it. 1198 */ exists()1199 public boolean exists() { 1200 return (flags_field & EXISTS) != 0; 1201 } 1202 1203 @DefinedBy(Api.LANGUAGE_MODEL) getKind()1204 public ElementKind getKind() { 1205 return ElementKind.PACKAGE; 1206 } 1207 1208 @DefinedBy(Api.LANGUAGE_MODEL) getEnclosingElement()1209 public Symbol getEnclosingElement() { 1210 return modle != null && !modle.isNoModule() ? modle : null; 1211 } 1212 1213 @DefinedBy(Api.LANGUAGE_MODEL) accept(ElementVisitor<R, P> v, P p)1214 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1215 return v.visitPackage(this, p); 1216 } 1217 accept(Symbol.Visitor<R, P> v, P p)1218 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1219 return v.visitPackageSymbol(this, p); 1220 } 1221 1222 /**Resets the Symbol into the state good for next round of annotation processing.*/ reset()1223 public void reset() { 1224 metadata = null; 1225 } 1226 1227 } 1228 1229 public static class RootPackageSymbol extends PackageSymbol { 1230 public final MissingInfoHandler missingInfoHandler; 1231 RootPackageSymbol(Name name, Symbol owner, MissingInfoHandler missingInfoHandler)1232 public RootPackageSymbol(Name name, Symbol owner, MissingInfoHandler missingInfoHandler) { 1233 super(name, owner); 1234 this.missingInfoHandler = missingInfoHandler; 1235 } 1236 1237 } 1238 1239 /** A class for class symbols 1240 */ 1241 public static class ClassSymbol extends TypeSymbol implements TypeElement { 1242 1243 /** a scope for all class members; variables, methods and inner classes 1244 * type parameters are not part of this scope 1245 */ 1246 public WriteableScope members_field; 1247 1248 /** the fully qualified name of the class, i.e. pck.outer.inner. 1249 * null for anonymous classes 1250 */ 1251 public Name fullname; 1252 1253 /** the fully qualified name of the class after converting to flat 1254 * representation, i.e. pck.outer$inner, 1255 * set externally for local and anonymous classes 1256 */ 1257 public Name flatname; 1258 1259 /** the sourcefile where the class came from 1260 */ 1261 public JavaFileObject sourcefile; 1262 1263 /** the classfile from where to load this class 1264 * this will have extension .class or .java 1265 */ 1266 public JavaFileObject classfile; 1267 1268 /** the list of translated local classes (used for generating 1269 * InnerClasses attribute) 1270 */ 1271 public List<ClassSymbol> trans_local; 1272 1273 /** the annotation metadata attached to this class */ 1274 private AnnotationTypeMetadata annotationTypeMetadata; 1275 1276 private List<RecordComponent> recordComponents = List.nil(); 1277 ClassSymbol(long flags, Name name, Type type, Symbol owner)1278 public ClassSymbol(long flags, Name name, Type type, Symbol owner) { 1279 super(TYP, flags, name, type, owner); 1280 this.members_field = null; 1281 this.fullname = formFullName(name, owner); 1282 this.flatname = formFlatName(name, owner); 1283 this.sourcefile = null; 1284 this.classfile = null; 1285 this.annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType(); 1286 } 1287 ClassSymbol(long flags, Name name, Symbol owner)1288 public ClassSymbol(long flags, Name name, Symbol owner) { 1289 this( 1290 flags, 1291 name, 1292 new ClassType(Type.noType, null, null), 1293 owner); 1294 this.type.tsym = this; 1295 } 1296 1297 /** The Java source which this symbol represents. 1298 */ toString()1299 public String toString() { 1300 return className(); 1301 } 1302 flags()1303 public long flags() { 1304 complete(); 1305 return flags_field; 1306 } 1307 members()1308 public WriteableScope members() { 1309 complete(); 1310 return members_field; 1311 } 1312 1313 @Override getRawAttributes()1314 public List<Attribute.Compound> getRawAttributes() { 1315 complete(); 1316 return super.getRawAttributes(); 1317 } 1318 1319 @Override getRawTypeAttributes()1320 public List<Attribute.TypeCompound> getRawTypeAttributes() { 1321 complete(); 1322 return super.getRawTypeAttributes(); 1323 } 1324 erasure(Types types)1325 public Type erasure(Types types) { 1326 if (erasure_field == null) 1327 erasure_field = new ClassType(types.erasure(type.getEnclosingType()), 1328 List.nil(), this, 1329 type.getMetadata()); 1330 return erasure_field; 1331 } 1332 className()1333 public String className() { 1334 if (name.isEmpty()) 1335 return 1336 Log.getLocalizedString("anonymous.class", flatname); 1337 else 1338 return fullname.toString(); 1339 } 1340 1341 @DefinedBy(Api.LANGUAGE_MODEL) getQualifiedName()1342 public Name getQualifiedName() { 1343 return fullname; 1344 } 1345 1346 @Override @DefinedBy(Api.LANGUAGE_MODEL) getEnclosedElements()1347 public List<Symbol> getEnclosedElements() { 1348 List<Symbol> result = super.getEnclosedElements(); 1349 if (!recordComponents.isEmpty()) { 1350 List<RecordComponent> reversed = recordComponents.reverse(); 1351 for (RecordComponent rc : reversed) { 1352 result = result.prepend(rc); 1353 } 1354 } 1355 return result; 1356 } 1357 flatName()1358 public Name flatName() { 1359 return flatname; 1360 } 1361 isSubClass(Symbol base, Types types)1362 public boolean isSubClass(Symbol base, Types types) { 1363 if (this == base) { 1364 return true; 1365 } else if ((base.flags() & INTERFACE) != 0) { 1366 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t)) 1367 for (List<Type> is = types.interfaces(t); 1368 is.nonEmpty(); 1369 is = is.tail) 1370 if (is.head.tsym.isSubClass(base, types)) return true; 1371 } else { 1372 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t)) 1373 if (t.tsym == base) return true; 1374 } 1375 return false; 1376 } 1377 1378 /** Complete the elaboration of this symbol's definition. 1379 */ complete()1380 public void complete() throws CompletionFailure { 1381 Completer origCompleter = completer; 1382 try { 1383 super.complete(); 1384 } catch (CompletionFailure ex) { 1385 ex.dcfh.classSymbolCompleteFailed(this, origCompleter); 1386 // quiet error recovery 1387 flags_field |= (PUBLIC|STATIC); 1388 this.type = new ErrorType(this, Type.noType); 1389 throw ex; 1390 } 1391 } 1392 1393 @DefinedBy(Api.LANGUAGE_MODEL) getInterfaces()1394 public List<Type> getInterfaces() { 1395 apiComplete(); 1396 if (type instanceof ClassType) { 1397 ClassType t = (ClassType)type; 1398 if (t.interfaces_field == null) // FIXME: shouldn't be null 1399 t.interfaces_field = List.nil(); 1400 if (t.all_interfaces_field != null) 1401 return Type.getModelTypes(t.all_interfaces_field); 1402 return t.interfaces_field; 1403 } else { 1404 return List.nil(); 1405 } 1406 } 1407 1408 @DefinedBy(Api.LANGUAGE_MODEL) getSuperclass()1409 public Type getSuperclass() { 1410 apiComplete(); 1411 if (type instanceof ClassType) { 1412 ClassType t = (ClassType)type; 1413 if (t.supertype_field == null) // FIXME: shouldn't be null 1414 t.supertype_field = Type.noType; 1415 // An interface has no superclass; its supertype is Object. 1416 return t.isInterface() 1417 ? Type.noType 1418 : t.supertype_field.getModelType(); 1419 } else { 1420 return Type.noType; 1421 } 1422 } 1423 1424 /** 1425 * Returns the next class to search for inherited annotations or {@code null} 1426 * if the next class can't be found. 1427 */ getSuperClassToSearchForAnnotations()1428 private ClassSymbol getSuperClassToSearchForAnnotations() { 1429 1430 Type sup = getSuperclass(); 1431 1432 if (!sup.hasTag(CLASS) || sup.isErroneous()) 1433 return null; 1434 1435 return (ClassSymbol) sup.tsym; 1436 } 1437 1438 1439 @Override getInheritedAnnotations(Class<A> annoType)1440 protected <A extends Annotation> A[] getInheritedAnnotations(Class<A> annoType) { 1441 1442 ClassSymbol sup = getSuperClassToSearchForAnnotations(); 1443 1444 return sup == null ? super.getInheritedAnnotations(annoType) 1445 : sup.getAnnotationsByType(annoType); 1446 } 1447 1448 1449 @DefinedBy(Api.LANGUAGE_MODEL) 1450 @SuppressWarnings("preview") getKind()1451 public ElementKind getKind() { 1452 apiComplete(); 1453 long flags = flags(); 1454 if ((flags & ANNOTATION) != 0) 1455 return ElementKind.ANNOTATION_TYPE; 1456 else if ((flags & INTERFACE) != 0) 1457 return ElementKind.INTERFACE; 1458 else if ((flags & ENUM) != 0) 1459 return ElementKind.ENUM; 1460 else if ((flags & RECORD) != 0) 1461 return ElementKind.RECORD; 1462 else 1463 return ElementKind.CLASS; 1464 } 1465 1466 @Override @DefinedBy(Api.LANGUAGE_MODEL) getModifiers()1467 public Set<Modifier> getModifiers() { 1468 apiComplete(); 1469 long flags = flags(); 1470 return Flags.asModifierSet(flags & ~DEFAULT); 1471 } 1472 getRecordComponent(VarSymbol field, boolean addIfMissing)1473 public RecordComponent getRecordComponent(VarSymbol field, boolean addIfMissing) { 1474 for (RecordComponent rc : recordComponents) { 1475 if (rc.name == field.name) { 1476 return rc; 1477 } 1478 } 1479 RecordComponent rc = null; 1480 if (addIfMissing) { 1481 recordComponents = recordComponents.append(rc = new RecordComponent(PUBLIC, field.name, field.type, field.owner)); 1482 } 1483 return rc; 1484 } 1485 1486 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1487 @SuppressWarnings("preview") getRecordComponents()1488 public List<? extends RecordComponent> getRecordComponents() { 1489 return recordComponents; 1490 } 1491 1492 @DefinedBy(Api.LANGUAGE_MODEL) getNestingKind()1493 public NestingKind getNestingKind() { 1494 apiComplete(); 1495 if (owner.kind == PCK) 1496 return NestingKind.TOP_LEVEL; 1497 else if (name.isEmpty()) 1498 return NestingKind.ANONYMOUS; 1499 else if (owner.kind == MTH) 1500 return NestingKind.LOCAL; 1501 else 1502 return NestingKind.MEMBER; 1503 } 1504 1505 @Override getAttribute(final Class<A> annoType)1506 protected <A extends Annotation> Attribute.Compound getAttribute(final Class<A> annoType) { 1507 1508 Attribute.Compound attrib = super.getAttribute(annoType); 1509 1510 boolean inherited = annoType.isAnnotationPresent(Inherited.class); 1511 if (attrib != null || !inherited) 1512 return attrib; 1513 1514 // Search supertypes 1515 ClassSymbol superType = getSuperClassToSearchForAnnotations(); 1516 return superType == null ? null 1517 : superType.getAttribute(annoType); 1518 } 1519 1520 @DefinedBy(Api.LANGUAGE_MODEL) accept(ElementVisitor<R, P> v, P p)1521 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1522 return v.visitType(this, p); 1523 } 1524 accept(Symbol.Visitor<R, P> v, P p)1525 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1526 return v.visitClassSymbol(this, p); 1527 } 1528 markAbstractIfNeeded(Types types)1529 public void markAbstractIfNeeded(Types types) { 1530 if (types.enter.getEnv(this) != null && 1531 (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym && 1532 (flags() & (FINAL | ABSTRACT)) == 0) { 1533 if (types.firstUnimplementedAbstract(this) != null) 1534 // add the ABSTRACT flag to an enum 1535 flags_field |= ABSTRACT; 1536 } 1537 } 1538 1539 /**Resets the Symbol into the state good for next round of annotation processing.*/ reset()1540 public void reset() { 1541 kind = TYP; 1542 erasure_field = null; 1543 members_field = null; 1544 flags_field = 0; 1545 if (type instanceof ClassType) { 1546 ClassType t = (ClassType)type; 1547 t.setEnclosingType(Type.noType); 1548 t.rank_field = -1; 1549 t.typarams_field = null; 1550 t.allparams_field = null; 1551 t.supertype_field = null; 1552 t.interfaces_field = null; 1553 t.all_interfaces_field = null; 1554 } 1555 clearAnnotationMetadata(); 1556 } 1557 clearAnnotationMetadata()1558 public void clearAnnotationMetadata() { 1559 metadata = null; 1560 annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType(); 1561 } 1562 1563 @Override getAnnotationTypeMetadata()1564 public AnnotationTypeMetadata getAnnotationTypeMetadata() { 1565 return annotationTypeMetadata; 1566 } 1567 1568 @Override isAnnotationType()1569 public boolean isAnnotationType() { 1570 return (flags_field & Flags.ANNOTATION) != 0; 1571 } 1572 setAnnotationTypeMetadata(AnnotationTypeMetadata a)1573 public void setAnnotationTypeMetadata(AnnotationTypeMetadata a) { 1574 Assert.checkNonNull(a); 1575 Assert.check(!annotationTypeMetadata.isMetadataForAnnotationType()); 1576 this.annotationTypeMetadata = a; 1577 } 1578 isRecord()1579 public boolean isRecord() { 1580 return (flags_field & RECORD) != 0; 1581 } 1582 } 1583 1584 1585 /** A class for variable symbols 1586 */ 1587 public static class VarSymbol extends Symbol implements VariableElement { 1588 1589 /** The variable's declaration position. 1590 */ 1591 public int pos = Position.NOPOS; 1592 1593 /** The variable's address. Used for different purposes during 1594 * flow analysis, translation and code generation. 1595 * Flow analysis: 1596 * If this is a blank final or local variable, its sequence number. 1597 * Translation: 1598 * If this is a private field, its access number. 1599 * Code generation: 1600 * If this is a local variable, its logical slot number. 1601 */ 1602 public int adr = -1; 1603 1604 /** Construct a variable symbol, given its flags, name, type and owner. 1605 */ VarSymbol(long flags, Name name, Type type, Symbol owner)1606 public VarSymbol(long flags, Name name, Type type, Symbol owner) { 1607 super(VAR, flags, name, type, owner); 1608 } 1609 1610 @Override poolTag()1611 public int poolTag() { 1612 return ClassFile.CONSTANT_Fieldref; 1613 } 1614 asMethodHandle(boolean getter)1615 public MethodHandleSymbol asMethodHandle(boolean getter) { 1616 return new MethodHandleSymbol(this, getter); 1617 } 1618 1619 /** Clone this symbol with new owner. 1620 */ clone(Symbol newOwner)1621 public VarSymbol clone(Symbol newOwner) { 1622 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) { 1623 @Override 1624 public Symbol baseSymbol() { 1625 return VarSymbol.this; 1626 } 1627 1628 @Override 1629 public Object poolKey(Types types) { 1630 return new Pair<>(newOwner, baseSymbol()); 1631 } 1632 }; 1633 v.pos = pos; 1634 v.adr = adr; 1635 v.data = data; 1636 // System.out.println("clone " + v + " in " + newOwner);//DEBUG 1637 return v; 1638 } 1639 toString()1640 public String toString() { 1641 return name.toString(); 1642 } 1643 asMemberOf(Type site, Types types)1644 public Symbol asMemberOf(Type site, Types types) { 1645 return new VarSymbol(flags_field, name, types.memberType(site, this), owner); 1646 } 1647 1648 @DefinedBy(Api.LANGUAGE_MODEL) getKind()1649 public ElementKind getKind() { 1650 long flags = flags(); 1651 if ((flags & PARAMETER) != 0) { 1652 if (isExceptionParameter()) 1653 return ElementKind.EXCEPTION_PARAMETER; 1654 else 1655 return ElementKind.PARAMETER; 1656 } else if ((flags & ENUM) != 0) { 1657 return ElementKind.ENUM_CONSTANT; 1658 } else if (owner.kind == TYP || owner.kind == ERR) { 1659 return ElementKind.FIELD; 1660 } else if (isResourceVariable()) { 1661 return ElementKind.RESOURCE_VARIABLE; 1662 } else if ((flags & MATCH_BINDING) != 0) { 1663 @SuppressWarnings("preview") 1664 ElementKind kind = ElementKind.BINDING_VARIABLE; 1665 return kind; 1666 } else { 1667 return ElementKind.LOCAL_VARIABLE; 1668 } 1669 } 1670 1671 @DefinedBy(Api.LANGUAGE_MODEL) accept(ElementVisitor<R, P> v, P p)1672 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1673 return v.visitVariable(this, p); 1674 } 1675 1676 @DefinedBy(Api.LANGUAGE_MODEL) getConstantValue()1677 public Object getConstantValue() { // Mirror API 1678 return Constants.decode(getConstValue(), type); 1679 } 1680 setLazyConstValue(final Env<AttrContext> env, final Attr attr, final JCVariableDecl variable)1681 public void setLazyConstValue(final Env<AttrContext> env, 1682 final Attr attr, 1683 final JCVariableDecl variable) 1684 { 1685 setData((Callable<Object>)() -> attr.attribLazyConstantValue(env, variable, type)); 1686 } 1687 1688 /** 1689 * The variable's constant value, if this is a constant. 1690 * Before the constant value is evaluated, it points to an 1691 * initializer environment. If this is not a constant, it can 1692 * be used for other stuff. 1693 */ 1694 private Object data; 1695 isExceptionParameter()1696 public boolean isExceptionParameter() { 1697 return data == ElementKind.EXCEPTION_PARAMETER; 1698 } 1699 isResourceVariable()1700 public boolean isResourceVariable() { 1701 return data == ElementKind.RESOURCE_VARIABLE; 1702 } 1703 getConstValue()1704 public Object getConstValue() { 1705 // TODO: Consider if getConstValue and getConstantValue can be collapsed 1706 if (data == ElementKind.EXCEPTION_PARAMETER || 1707 data == ElementKind.RESOURCE_VARIABLE) { 1708 return null; 1709 } else if (data instanceof Callable<?>) { 1710 // In this case, this is a final variable, with an as 1711 // yet unevaluated initializer. 1712 Callable<?> eval = (Callable<?>)data; 1713 data = null; // to make sure we don't evaluate this twice. 1714 try { 1715 data = eval.call(); 1716 } catch (Exception ex) { 1717 throw new AssertionError(ex); 1718 } 1719 } 1720 return data; 1721 } 1722 setData(Object data)1723 public void setData(Object data) { 1724 Assert.check(!(data instanceof Env<?>), this); 1725 this.data = data; 1726 } 1727 accept(Symbol.Visitor<R, P> v, P p)1728 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1729 return v.visitVarSymbol(this, p); 1730 } 1731 } 1732 1733 @SuppressWarnings("preview") 1734 public static class RecordComponent extends VarSymbol implements RecordComponentElement { 1735 public MethodSymbol accessor; 1736 1737 /** 1738 * Construct a record component, given its flags, name, type and owner. 1739 */ RecordComponent(long flags, Name name, Type type, Symbol owner)1740 public RecordComponent(long flags, Name name, Type type, Symbol owner) { 1741 super(flags, name, type, owner); 1742 } 1743 1744 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1745 @SuppressWarnings("preview") getKind()1746 public ElementKind getKind() { 1747 return ElementKind.RECORD_COMPONENT; 1748 } 1749 1750 @Override @DefinedBy(Api.LANGUAGE_MODEL) getAccessor()1751 public ExecutableElement getAccessor() { 1752 return accessor; 1753 } 1754 1755 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1756 @SuppressWarnings("preview") accept(ElementVisitor<R, P> v, P p)1757 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1758 return v.visitRecordComponent(this, p); 1759 } 1760 } 1761 1762 public static class ParamSymbol extends VarSymbol { ParamSymbol(long flags, Name name, Type type, Symbol owner)1763 public ParamSymbol(long flags, Name name, Type type, Symbol owner) { 1764 super(flags, name, type, owner); 1765 } 1766 1767 @Override getSimpleName()1768 public Name getSimpleName() { 1769 if ((flags_field & NAME_FILLED) == 0) { 1770 flags_field |= NAME_FILLED; 1771 Symbol rootPack = this; 1772 while (rootPack != null && !(rootPack instanceof RootPackageSymbol)) { 1773 rootPack = rootPack.owner; 1774 } 1775 if (rootPack != null) { 1776 Name inferredName = 1777 ((RootPackageSymbol) rootPack).missingInfoHandler.getParameterName(this); 1778 if (inferredName != null) { 1779 this.name = inferredName; 1780 } 1781 } 1782 } 1783 return super.getSimpleName(); 1784 } 1785 1786 } 1787 1788 public static class BindingSymbol extends VarSymbol { 1789 BindingSymbol(Name name, Type type, Symbol owner)1790 public BindingSymbol(Name name, Type type, Symbol owner) { 1791 super(Flags.FINAL | Flags.HASINIT | Flags.MATCH_BINDING, name, type, owner); 1792 } 1793 isAliasFor(BindingSymbol b)1794 public boolean isAliasFor(BindingSymbol b) { 1795 return aliases().containsAll(b.aliases()); 1796 } 1797 aliases()1798 List<BindingSymbol> aliases() { 1799 return List.of(this); 1800 } 1801 preserveBinding()1802 public void preserveBinding() { 1803 flags_field |= Flags.MATCH_BINDING_TO_OUTER; 1804 } 1805 isPreserved()1806 public boolean isPreserved() { 1807 return (flags_field & Flags.MATCH_BINDING_TO_OUTER) != 0; 1808 } 1809 } 1810 1811 /** A class for method symbols. 1812 */ 1813 public static class MethodSymbol extends Symbol implements ExecutableElement { 1814 1815 /** The code of the method. */ 1816 public Code code = null; 1817 1818 /** The extra (synthetic/mandated) parameters of the method. */ 1819 public List<VarSymbol> extraParams = List.nil(); 1820 1821 /** The captured local variables in an anonymous class */ 1822 public List<VarSymbol> capturedLocals = List.nil(); 1823 1824 /** The parameters of the method. */ 1825 public List<VarSymbol> params = null; 1826 1827 /** For an annotation type element, its default value if any. 1828 * The value is null if none appeared in the method 1829 * declaration. 1830 */ 1831 public Attribute defaultValue = null; 1832 1833 /** Construct a method symbol, given its flags, name, type and owner. 1834 */ MethodSymbol(long flags, Name name, Type type, Symbol owner)1835 public MethodSymbol(long flags, Name name, Type type, Symbol owner) { 1836 super(MTH, flags, name, type, owner); 1837 if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name); 1838 } 1839 1840 /** Clone this symbol with new owner. 1841 */ clone(Symbol newOwner)1842 public MethodSymbol clone(Symbol newOwner) { 1843 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) { 1844 @Override 1845 public Symbol baseSymbol() { 1846 return MethodSymbol.this; 1847 } 1848 1849 @Override 1850 public Object poolKey(Types types) { 1851 return new Pair<>(newOwner, baseSymbol()); 1852 } 1853 }; 1854 m.code = code; 1855 return m; 1856 } 1857 1858 @Override @DefinedBy(Api.LANGUAGE_MODEL) getModifiers()1859 public Set<Modifier> getModifiers() { 1860 long flags = flags(); 1861 return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags); 1862 } 1863 1864 /** The Java source which this symbol represents. 1865 */ toString()1866 public String toString() { 1867 if ((flags() & BLOCK) != 0) { 1868 return owner.name.toString(); 1869 } else { 1870 String s = (name == name.table.names.init) 1871 ? owner.name.toString() 1872 : name.toString(); 1873 if (type != null) { 1874 if (type.hasTag(FORALL)) 1875 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s; 1876 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")"; 1877 } 1878 return s; 1879 } 1880 } 1881 1882 @Override poolTag()1883 public int poolTag() { 1884 return owner.isInterface() ? 1885 ClassFile.CONSTANT_InterfaceMethodref : ClassFile.CONSTANT_Methodref; 1886 } 1887 isHandle()1888 public boolean isHandle() { 1889 return false; 1890 } 1891 1892 asHandle()1893 public MethodHandleSymbol asHandle() { 1894 return new MethodHandleSymbol(this); 1895 } 1896 1897 /** find a symbol that this (proxy method) symbol implements. 1898 * @param c The class whose members are searched for 1899 * implementations 1900 */ implemented(TypeSymbol c, Types types)1901 public Symbol implemented(TypeSymbol c, Types types) { 1902 Symbol impl = null; 1903 for (List<Type> is = types.interfaces(c.type); 1904 impl == null && is.nonEmpty(); 1905 is = is.tail) { 1906 TypeSymbol i = is.head.tsym; 1907 impl = implementedIn(i, types); 1908 if (impl == null) 1909 impl = implemented(i, types); 1910 } 1911 return impl; 1912 } 1913 implementedIn(TypeSymbol c, Types types)1914 public Symbol implementedIn(TypeSymbol c, Types types) { 1915 Symbol impl = null; 1916 for (Symbol sym : c.members().getSymbolsByName(name)) { 1917 if (this.overrides(sym, (TypeSymbol)owner, types, true) && 1918 // FIXME: I suspect the following requires a 1919 // subst() for a parametric return type. 1920 types.isSameType(type.getReturnType(), 1921 types.memberType(owner.type, sym).getReturnType())) { 1922 impl = sym; 1923 } 1924 } 1925 return impl; 1926 } 1927 1928 /** Will the erasure of this method be considered by the VM to 1929 * override the erasure of the other when seen from class `origin'? 1930 */ binaryOverrides(Symbol _other, TypeSymbol origin, Types types)1931 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) { 1932 if (isConstructor() || _other.kind != MTH) return false; 1933 1934 if (this == _other) return true; 1935 MethodSymbol other = (MethodSymbol)_other; 1936 1937 // check for a direct implementation 1938 if (other.isOverridableIn((TypeSymbol)owner) && 1939 types.asSuper(owner.type, other.owner) != null && 1940 types.isSameType(erasure(types), other.erasure(types))) 1941 return true; 1942 1943 // check for an inherited implementation 1944 return 1945 (flags() & ABSTRACT) == 0 && 1946 other.isOverridableIn(origin) && 1947 this.isMemberOf(origin, types) && 1948 types.isSameType(erasure(types), other.erasure(types)); 1949 } 1950 1951 /** The implementation of this (abstract) symbol in class origin, 1952 * from the VM's point of view, null if method does not have an 1953 * implementation in class. 1954 * @param origin The class of which the implementation is a member. 1955 */ binaryImplementation(ClassSymbol origin, Types types)1956 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) { 1957 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) { 1958 for (Symbol sym : c.members().getSymbolsByName(name)) { 1959 if (sym.kind == MTH && 1960 ((MethodSymbol)sym).binaryOverrides(this, origin, types)) 1961 return (MethodSymbol)sym; 1962 } 1963 } 1964 return null; 1965 } 1966 1967 /** Does this symbol override `other' symbol, when both are seen as 1968 * members of class `origin'? It is assumed that _other is a member 1969 * of origin. 1970 * 1971 * It is assumed that both symbols have the same name. The static 1972 * modifier is ignored for this test. 1973 * 1974 * A quirk in the works is that if the receiver is a method symbol for 1975 * an inherited abstract method we answer false summarily all else being 1976 * immaterial. Abstract "own" methods (i.e `this' is a direct member of 1977 * origin) don't get rejected as summarily and are put to test against the 1978 * suitable criteria. 1979 * 1980 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 1981 */ overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult)1982 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { 1983 return overrides(_other, origin, types, checkResult, true); 1984 } 1985 1986 /** Does this symbol override `other' symbol, when both are seen as 1987 * members of class `origin'? It is assumed that _other is a member 1988 * of origin. 1989 * 1990 * Caveat: If `this' is an abstract inherited member of origin, it is 1991 * deemed to override `other' only when `requireConcreteIfInherited' 1992 * is false. 1993 * 1994 * It is assumed that both symbols have the same name. The static 1995 * modifier is ignored for this test. 1996 * 1997 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 1998 */ overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult, boolean requireConcreteIfInherited)1999 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult, 2000 boolean requireConcreteIfInherited) { 2001 if (isConstructor() || _other.kind != MTH) return false; 2002 2003 if (this == _other) return true; 2004 MethodSymbol other = (MethodSymbol)_other; 2005 2006 // check for a direct implementation 2007 if (other.isOverridableIn((TypeSymbol)owner) && 2008 types.asSuper(owner.type, other.owner) != null) { 2009 Type mt = types.memberType(owner.type, this); 2010 Type ot = types.memberType(owner.type, other); 2011 if (types.isSubSignature(mt, ot)) { 2012 if (!checkResult) 2013 return true; 2014 if (types.returnTypeSubstitutable(mt, ot)) 2015 return true; 2016 } 2017 } 2018 2019 // check for an inherited implementation 2020 if (((flags() & ABSTRACT) != 0 && requireConcreteIfInherited) || 2021 ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) || 2022 !other.isOverridableIn(origin) || 2023 !this.isMemberOf(origin, types)) 2024 return false; 2025 2026 // assert types.asSuper(origin.type, other.owner) != null; 2027 Type mt = types.memberType(origin.type, this); 2028 Type ot = types.memberType(origin.type, other); 2029 return 2030 types.isSubSignature(mt, ot) && 2031 (!checkResult || types.resultSubtype(mt, ot, types.noWarnings)); 2032 } 2033 isOverridableIn(TypeSymbol origin)2034 private boolean isOverridableIn(TypeSymbol origin) { 2035 // JLS 8.4.6.1 2036 switch ((int)(flags_field & Flags.AccessFlags)) { 2037 case Flags.PRIVATE: 2038 return false; 2039 case Flags.PUBLIC: 2040 return !this.owner.isInterface() || 2041 (flags_field & STATIC) == 0; 2042 case Flags.PROTECTED: 2043 return (origin.flags() & INTERFACE) == 0; 2044 case 0: 2045 // for package private: can only override in the same 2046 // package 2047 return 2048 this.packge() == origin.packge() && 2049 (origin.flags() & INTERFACE) == 0; 2050 default: 2051 return false; 2052 } 2053 } 2054 2055 @Override isInheritedIn(Symbol clazz, Types types)2056 public boolean isInheritedIn(Symbol clazz, Types types) { 2057 switch ((int)(flags_field & Flags.AccessFlags)) { 2058 case PUBLIC: 2059 return !this.owner.isInterface() || 2060 clazz == owner || 2061 (flags_field & STATIC) == 0; 2062 default: 2063 return super.isInheritedIn(clazz, types); 2064 } 2065 } 2066 isLambdaMethod()2067 public boolean isLambdaMethod() { 2068 return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD; 2069 } 2070 2071 /** override this method to point to the original enclosing method if this method symbol represents a synthetic 2072 * lambda method 2073 */ originalEnclosingMethod()2074 public MethodSymbol originalEnclosingMethod() { 2075 return this; 2076 } 2077 2078 /** The implementation of this (abstract) symbol in class origin; 2079 * null if none exists. Synthetic methods are not considered 2080 * as possible implementations. 2081 */ implementation(TypeSymbol origin, Types types, boolean checkResult)2082 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { 2083 return implementation(origin, types, checkResult, implementation_filter); 2084 } 2085 // where 2086 public static final Filter<Symbol> implementation_filter = s -> 2087 s.kind == MTH && (s.flags() & SYNTHETIC) == 0; 2088 implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter)2089 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) { 2090 MethodSymbol res = types.implementation(this, origin, checkResult, implFilter); 2091 if (res != null) 2092 return res; 2093 // if origin is derived from a raw type, we might have missed 2094 // an implementation because we do not know enough about instantiations. 2095 // in this case continue with the supertype as origin. 2096 if (types.isDerivedRaw(origin.type) && !origin.isInterface()) 2097 return implementation(types.supertype(origin.type).tsym, types, checkResult); 2098 else 2099 return null; 2100 } 2101 params()2102 public List<VarSymbol> params() { 2103 owner.complete(); 2104 if (params == null) { 2105 ListBuffer<VarSymbol> newParams = new ListBuffer<>(); 2106 int i = 0; 2107 for (Type t : type.getParameterTypes()) { 2108 Name paramName = name.table.fromString("arg" + i); 2109 VarSymbol param = new VarSymbol(PARAMETER, paramName, t, this); 2110 newParams.append(param); 2111 i++; 2112 } 2113 params = newParams.toList(); 2114 } 2115 Assert.checkNonNull(params); 2116 return params; 2117 } 2118 asMemberOf(Type site, Types types)2119 public Symbol asMemberOf(Type site, Types types) { 2120 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner); 2121 } 2122 2123 @DefinedBy(Api.LANGUAGE_MODEL) getKind()2124 public ElementKind getKind() { 2125 if (name == name.table.names.init) 2126 return ElementKind.CONSTRUCTOR; 2127 else if (name == name.table.names.clinit) 2128 return ElementKind.STATIC_INIT; 2129 else if ((flags() & BLOCK) != 0) 2130 return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT; 2131 else 2132 return ElementKind.METHOD; 2133 } 2134 isStaticOrInstanceInit()2135 public boolean isStaticOrInstanceInit() { 2136 return getKind() == ElementKind.STATIC_INIT || 2137 getKind() == ElementKind.INSTANCE_INIT; 2138 } 2139 2140 @DefinedBy(Api.LANGUAGE_MODEL) getDefaultValue()2141 public Attribute getDefaultValue() { 2142 return defaultValue; 2143 } 2144 2145 @DefinedBy(Api.LANGUAGE_MODEL) getParameters()2146 public List<VarSymbol> getParameters() { 2147 return params(); 2148 } 2149 2150 @DefinedBy(Api.LANGUAGE_MODEL) isVarArgs()2151 public boolean isVarArgs() { 2152 return (flags() & VARARGS) != 0; 2153 } 2154 2155 @DefinedBy(Api.LANGUAGE_MODEL) isDefault()2156 public boolean isDefault() { 2157 return (flags() & DEFAULT) != 0; 2158 } 2159 2160 @DefinedBy(Api.LANGUAGE_MODEL) accept(ElementVisitor<R, P> v, P p)2161 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 2162 return v.visitExecutable(this, p); 2163 } 2164 accept(Symbol.Visitor<R, P> v, P p)2165 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 2166 return v.visitMethodSymbol(this, p); 2167 } 2168 2169 @DefinedBy(Api.LANGUAGE_MODEL) getReceiverType()2170 public Type getReceiverType() { 2171 Type result = asType().getReceiverType(); 2172 return (result == null) ? Type.noType : result; 2173 } 2174 2175 @DefinedBy(Api.LANGUAGE_MODEL) getReturnType()2176 public Type getReturnType() { 2177 return asType().getReturnType(); 2178 } 2179 2180 @DefinedBy(Api.LANGUAGE_MODEL) getThrownTypes()2181 public List<Type> getThrownTypes() { 2182 return asType().getThrownTypes(); 2183 } 2184 } 2185 2186 /** A class for invokedynamic method calls. 2187 */ 2188 public static class DynamicMethodSymbol extends MethodSymbol implements Dynamic { 2189 2190 public LoadableConstant[] staticArgs; 2191 public MethodHandleSymbol bsm; 2192 DynamicMethodSymbol(Name name, Symbol owner, MethodHandleSymbol bsm, Type type, LoadableConstant[] staticArgs)2193 public DynamicMethodSymbol(Name name, Symbol owner, MethodHandleSymbol bsm, Type type, LoadableConstant[] staticArgs) { 2194 super(0, name, type, owner); 2195 this.bsm = bsm; 2196 this.staticArgs = staticArgs; 2197 } 2198 2199 @Override isDynamic()2200 public boolean isDynamic() { 2201 return true; 2202 } 2203 2204 @Override staticArgs()2205 public LoadableConstant[] staticArgs() { 2206 return staticArgs; 2207 } 2208 2209 @Override bootstrapMethod()2210 public MethodHandleSymbol bootstrapMethod() { 2211 return bsm; 2212 } 2213 2214 @Override poolTag()2215 public int poolTag() { 2216 return ClassFile.CONSTANT_InvokeDynamic; 2217 } 2218 2219 @Override dynamicType()2220 public Type dynamicType() { 2221 return type; 2222 } 2223 } 2224 2225 /** A class for condy. 2226 */ 2227 public static class DynamicVarSymbol extends VarSymbol implements Dynamic, LoadableConstant { 2228 public LoadableConstant[] staticArgs; 2229 public MethodHandleSymbol bsm; 2230 DynamicVarSymbol(Name name, Symbol owner, MethodHandleSymbol bsm, Type type, LoadableConstant[] staticArgs)2231 public DynamicVarSymbol(Name name, Symbol owner, MethodHandleSymbol bsm, Type type, LoadableConstant[] staticArgs) { 2232 super(0, name, type, owner); 2233 this.bsm = bsm; 2234 this.staticArgs = staticArgs; 2235 } 2236 2237 @Override isDynamic()2238 public boolean isDynamic() { 2239 return true; 2240 } 2241 2242 @Override dynamicType()2243 public PoolConstant dynamicType() { 2244 return type; 2245 } 2246 2247 @Override staticArgs()2248 public LoadableConstant[] staticArgs() { 2249 return staticArgs; 2250 } 2251 2252 @Override bootstrapMethod()2253 public LoadableConstant bootstrapMethod() { 2254 return bsm; 2255 } 2256 2257 @Override poolTag()2258 public int poolTag() { 2259 return ClassFile.CONSTANT_Dynamic; 2260 } 2261 } 2262 2263 /** A class for method handles. 2264 */ 2265 public static class MethodHandleSymbol extends MethodSymbol implements LoadableConstant { 2266 2267 private Symbol refSym; 2268 private boolean getter; 2269 MethodHandleSymbol(Symbol msym)2270 public MethodHandleSymbol(Symbol msym) { 2271 this(msym, false); 2272 } 2273 MethodHandleSymbol(Symbol msym, boolean getter)2274 public MethodHandleSymbol(Symbol msym, boolean getter) { 2275 super(msym.flags_field, msym.name, msym.type, msym.owner); 2276 this.refSym = msym; 2277 this.getter = getter; 2278 } 2279 2280 /** 2281 * Returns the kind associated with this method handle. 2282 */ referenceKind()2283 public int referenceKind() { 2284 if (refSym.kind == VAR) { 2285 return getter ? 2286 refSym.isStatic() ? ClassFile.REF_getStatic : ClassFile.REF_getField : 2287 refSym.isStatic() ? ClassFile.REF_putStatic : ClassFile.REF_putField; 2288 } else { 2289 if (refSym.isConstructor()) { 2290 return ClassFile.REF_newInvokeSpecial; 2291 } else { 2292 if (refSym.isStatic()) { 2293 return ClassFile.REF_invokeStatic; 2294 } else if ((refSym.flags() & PRIVATE) != 0) { 2295 return ClassFile.REF_invokeSpecial; 2296 } else if (refSym.enclClass().isInterface()) { 2297 return ClassFile.REF_invokeInterface; 2298 } else { 2299 return ClassFile.REF_invokeVirtual; 2300 } 2301 } 2302 } 2303 } 2304 2305 @Override poolTag()2306 public int poolTag() { 2307 return ClassFile.CONSTANT_MethodHandle; 2308 } 2309 2310 @Override poolKey(Types types)2311 public Object poolKey(Types types) { 2312 return new Pair<>(baseSymbol(), referenceKind()); 2313 } 2314 2315 @Override asHandle()2316 public MethodHandleSymbol asHandle() { 2317 return this; 2318 } 2319 2320 @Override baseSymbol()2321 public Symbol baseSymbol() { 2322 return refSym; 2323 } 2324 2325 2326 @Override isHandle()2327 public boolean isHandle() { 2328 return true; 2329 } 2330 } 2331 2332 /** A class for predefined operators. 2333 */ 2334 public static class OperatorSymbol extends MethodSymbol { 2335 2336 public int opcode; 2337 private int accessCode = Integer.MIN_VALUE; 2338 OperatorSymbol(Name name, Type type, int opcode, Symbol owner)2339 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) { 2340 super(PUBLIC | STATIC, name, type, owner); 2341 this.opcode = opcode; 2342 } 2343 2344 @Override accept(Symbol.Visitor<R, P> v, P p)2345 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 2346 return v.visitOperatorSymbol(this, p); 2347 } 2348 getAccessCode(Tag tag)2349 public int getAccessCode(Tag tag) { 2350 if (accessCode != Integer.MIN_VALUE && !tag.isIncOrDecUnaryOp()) { 2351 return accessCode; 2352 } 2353 accessCode = AccessCode.from(tag, opcode); 2354 return accessCode; 2355 } 2356 2357 /** Access codes for dereferencing, assignment, 2358 * and pre/post increment/decrement. 2359 2360 * All access codes for accesses to the current class are even. 2361 * If a member of the superclass should be accessed instead (because 2362 * access was via a qualified super), add one to the corresponding code 2363 * for the current class, making the number odd. 2364 * This numbering scheme is used by the backend to decide whether 2365 * to issue an invokevirtual or invokespecial call. 2366 * 2367 * @see Gen#visitSelect(JCFieldAccess tree) 2368 */ 2369 public enum AccessCode { 2370 UNKNOWN(-1, Tag.NO_TAG), 2371 DEREF(0, Tag.NO_TAG), 2372 ASSIGN(2, Tag.ASSIGN), 2373 PREINC(4, Tag.PREINC), 2374 PREDEC(6, Tag.PREDEC), 2375 POSTINC(8, Tag.POSTINC), 2376 POSTDEC(10, Tag.POSTDEC), 2377 FIRSTASGOP(12, Tag.NO_TAG); 2378 2379 public final int code; 2380 public final Tag tag; 2381 public static final int numberOfAccessCodes = (lushrl - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code + 2; 2382 AccessCode(int code, Tag tag)2383 AccessCode(int code, Tag tag) { 2384 this.code = code; 2385 this.tag = tag; 2386 } 2387 getFromCode(int code)2388 static public AccessCode getFromCode(int code) { 2389 for (AccessCode aCodes : AccessCode.values()) { 2390 if (aCodes.code == code) { 2391 return aCodes; 2392 } 2393 } 2394 return UNKNOWN; 2395 } 2396 from(Tag tag, int opcode)2397 static int from(Tag tag, int opcode) { 2398 /** Map bytecode of binary operation to access code of corresponding 2399 * assignment operation. This is always an even number. 2400 */ 2401 switch (tag) { 2402 case PREINC: 2403 return AccessCode.PREINC.code; 2404 case PREDEC: 2405 return AccessCode.PREDEC.code; 2406 case POSTINC: 2407 return AccessCode.POSTINC.code; 2408 case POSTDEC: 2409 return AccessCode.POSTDEC.code; 2410 } 2411 if (iadd <= opcode && opcode <= lxor) { 2412 return (opcode - iadd) * 2 + FIRSTASGOP.code; 2413 } else if (opcode == string_add) { 2414 return (lxor + 1 - iadd) * 2 + FIRSTASGOP.code; 2415 } else if (ishll <= opcode && opcode <= lushrl) { 2416 return (opcode - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code; 2417 } 2418 return -1; 2419 } 2420 } 2421 } 2422 2423 /** Symbol completer interface. 2424 */ 2425 public static interface Completer { 2426 2427 /** Dummy completer to be used when the symbol has been completed or 2428 * does not need completion. 2429 */ 2430 public final static Completer NULL_COMPLETER = new Completer() { 2431 public void complete(Symbol sym) { } 2432 public boolean isTerminal() { return true; } 2433 }; 2434 complete(Symbol sym)2435 void complete(Symbol sym) throws CompletionFailure; 2436 2437 /** Returns true if this completer is <em>terminal</em>. A terminal 2438 * completer is used as a place holder when the symbol is completed. 2439 * Calling complete on a terminal completer will not affect the symbol. 2440 * 2441 * The dummy NULL_COMPLETER and the GraphDependencies completer are 2442 * examples of terminal completers. 2443 * 2444 * @return true iff this completer is terminal 2445 */ isTerminal()2446 default boolean isTerminal() { 2447 return false; 2448 } 2449 } 2450 2451 public static class CompletionFailure extends RuntimeException { 2452 private static final long serialVersionUID = 0; 2453 public final transient DeferredCompletionFailureHandler dcfh; 2454 public transient Symbol sym; 2455 2456 /** A diagnostic object describing the failure 2457 */ 2458 private transient JCDiagnostic diag; 2459 2460 private transient Supplier<JCDiagnostic> diagSupplier; 2461 CompletionFailure(Symbol sym, Supplier<JCDiagnostic> diagSupplier, DeferredCompletionFailureHandler dcfh)2462 public CompletionFailure(Symbol sym, Supplier<JCDiagnostic> diagSupplier, DeferredCompletionFailureHandler dcfh) { 2463 this.dcfh = dcfh; 2464 this.sym = sym; 2465 this.diagSupplier = diagSupplier; 2466 // this.printStackTrace();//DEBUG 2467 } 2468 getDiagnostic()2469 public JCDiagnostic getDiagnostic() { 2470 if (diag == null && diagSupplier != null) { 2471 diag = diagSupplier.get(); 2472 } 2473 return diag; 2474 } 2475 2476 @Override getMessage()2477 public String getMessage() { 2478 return getDiagnostic().getMessage(null); 2479 } 2480 getDetailValue()2481 public JCDiagnostic getDetailValue() { 2482 return getDiagnostic(); 2483 } 2484 2485 @Override initCause(Throwable cause)2486 public CompletionFailure initCause(Throwable cause) { 2487 super.initCause(cause); 2488 return this; 2489 } 2490 resetDiagnostic(Supplier<JCDiagnostic> diagSupplier)2491 public void resetDiagnostic(Supplier<JCDiagnostic> diagSupplier) { 2492 this.diagSupplier = diagSupplier; 2493 this.diag = null; 2494 } 2495 2496 } 2497 2498 /** 2499 * A visitor for symbols. A visitor is used to implement operations 2500 * (or relations) on symbols. Most common operations on types are 2501 * binary relations and this interface is designed for binary 2502 * relations, that is, operations on the form 2503 * Symbol × P → R. 2504 * <!-- In plain text: Type x P -> R --> 2505 * 2506 * @param <R> the return type of the operation implemented by this 2507 * visitor; use Void if no return type is needed. 2508 * @param <P> the type of the second argument (the first being the 2509 * symbol itself) of the operation implemented by this visitor; use 2510 * Void if a second argument is not needed. 2511 */ 2512 public interface Visitor<R,P> { visitClassSymbol(ClassSymbol s, P arg)2513 R visitClassSymbol(ClassSymbol s, P arg); visitMethodSymbol(MethodSymbol s, P arg)2514 R visitMethodSymbol(MethodSymbol s, P arg); visitPackageSymbol(PackageSymbol s, P arg)2515 R visitPackageSymbol(PackageSymbol s, P arg); visitOperatorSymbol(OperatorSymbol s, P arg)2516 R visitOperatorSymbol(OperatorSymbol s, P arg); visitVarSymbol(VarSymbol s, P arg)2517 R visitVarSymbol(VarSymbol s, P arg); visitTypeSymbol(TypeSymbol s, P arg)2518 R visitTypeSymbol(TypeSymbol s, P arg); visitSymbol(Symbol s, P arg)2519 R visitSymbol(Symbol s, P arg); 2520 } 2521 } 2522