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