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