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