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