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