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