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