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