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