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