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