1 /* 2 * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.javac.code; 27 28 import java.lang.annotation.Annotation; 29 import java.lang.annotation.Inherited; 30 import java.util.Collections; 31 import java.util.EnumSet; 32 import java.util.HashMap; 33 import java.util.Map; 34 import java.util.Set; 35 import java.util.concurrent.Callable; 36 import java.util.function.Supplier; 37 import java.util.function.Predicate; 38 39 import javax.lang.model.element.Element; 40 import javax.lang.model.element.ElementKind; 41 import javax.lang.model.element.ElementVisitor; 42 import javax.lang.model.element.ExecutableElement; 43 import javax.lang.model.element.Modifier; 44 import javax.lang.model.element.ModuleElement; 45 import javax.lang.model.element.NestingKind; 46 import javax.lang.model.element.PackageElement; 47 import javax.lang.model.element.RecordComponentElement; 48 import javax.lang.model.element.TypeElement; 49 import javax.lang.model.element.TypeParameterElement; 50 import javax.lang.model.element.VariableElement; 51 import javax.tools.JavaFileManager; 52 import javax.tools.JavaFileObject; 53 54 import com.sun.tools.javac.code.Kinds.Kind; 55 import com.sun.tools.javac.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 this.getQualifiedName().compareTo(that.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 @SuppressWarnings("this-escape") 1041 public ModuleSymbol(Name name, Symbol owner) { 1042 super(MDL, 0, name, null, owner); 1043 Assert.checkNonNull(name); 1044 this.type = new ModuleType(this); 1045 } 1046 1047 @Override 1048 public int poolTag() { 1049 return ClassFile.CONSTANT_Module; 1050 } 1051 1052 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1053 public Name getSimpleName() { 1054 return Convert.shortName(name); 1055 } 1056 1057 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1058 public boolean isOpen() { 1059 return flags.contains(ModuleFlags.OPEN); 1060 } 1061 1062 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1063 public boolean isUnnamed() { 1064 return name.isEmpty() && owner == null; 1065 } 1066 1067 @Override 1068 public boolean isDeprecated() { 1069 return hasDeprecatedAnnotation(); 1070 } 1071 1072 public boolean isNoModule() { 1073 return false; 1074 } 1075 1076 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1077 public ElementKind getKind() { 1078 return ElementKind.MODULE; 1079 } 1080 1081 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1082 public java.util.List<Directive> getDirectives() { 1083 apiComplete(); 1084 completeUsesProvides(); 1085 return Collections.unmodifiableList(directives); 1086 } 1087 1088 public void completeUsesProvides() { 1089 if (usesProvidesCompleter != Completer.NULL_COMPLETER) { 1090 Completer c = usesProvidesCompleter; 1091 usesProvidesCompleter = Completer.NULL_COMPLETER; 1092 c.complete(this); 1093 } 1094 } 1095 1096 @Override 1097 public ClassSymbol outermostClass() { 1098 return null; 1099 } 1100 1101 @Override 1102 public String toString() { 1103 // TODO: the following strings should be localized 1104 // Do this with custom anon subtypes in Symtab 1105 String n = (name == null) ? "<unknown>" 1106 : (name.isEmpty()) ? "<unnamed>" 1107 : String.valueOf(name); 1108 return n; 1109 } 1110 1111 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1112 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1113 return v.visitModule(this, p); 1114 } 1115 1116 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1117 public List<Symbol> getEnclosedElements() { 1118 List<Symbol> list = List.nil(); 1119 for (Symbol sym : enclosedPackages) { 1120 if (sym.members().anyMatch(m -> m.kind == TYP)) 1121 list = list.prepend(sym); 1122 } 1123 return list; 1124 } 1125 1126 public void reset() { 1127 this.directives = null; 1128 this.requires = null; 1129 this.exports = null; 1130 this.provides = null; 1131 this.uses = null; 1132 this.visiblePackages = null; 1133 } 1134 1135 } 1136 1137 public enum ModuleFlags { 1138 OPEN(0x0020), 1139 SYNTHETIC(0x1000), 1140 MANDATED(0x8000); 1141 1142 public static int value(Set<ModuleFlags> s) { 1143 int v = 0; 1144 for (ModuleFlags f: s) 1145 v |= f.value; 1146 return v; 1147 } 1148 1149 private ModuleFlags(int value) { 1150 this.value = value; 1151 } 1152 1153 public final int value; 1154 } 1155 1156 public enum ModuleResolutionFlags { 1157 DO_NOT_RESOLVE_BY_DEFAULT(0x0001), 1158 WARN_DEPRECATED(0x0002), 1159 WARN_DEPRECATED_REMOVAL(0x0004), 1160 WARN_INCUBATING(0x0008); 1161 1162 public static int value(Set<ModuleResolutionFlags> s) { 1163 int v = 0; 1164 for (ModuleResolutionFlags f: s) 1165 v |= f.value; 1166 return v; 1167 } 1168 1169 private ModuleResolutionFlags(int value) { 1170 this.value = value; 1171 } 1172 1173 public final int value; 1174 } 1175 1176 /** A class for package symbols 1177 */ 1178 public static class PackageSymbol extends TypeSymbol 1179 implements PackageElement { 1180 1181 public WriteableScope members_field; 1182 public Name fullname; 1183 public ClassSymbol package_info; // see bug 6443073 1184 public ModuleSymbol modle; 1185 // the file containing the documentation comments for the package 1186 public JavaFileObject sourcefile; 1187 1188 public PackageSymbol(Name name, Type type, Symbol owner) { 1189 super(PCK, 0, name, type, owner); 1190 this.members_field = null; 1191 this.fullname = formFullName(name, owner); 1192 } 1193 1194 @SuppressWarnings("this-escape") 1195 public PackageSymbol(Name name, Symbol owner) { 1196 this(name, null, owner); 1197 this.type = new PackageType(this); 1198 } 1199 1200 public String toString() { 1201 return fullname.toString(); 1202 } 1203 1204 @DefinedBy(Api.LANGUAGE_MODEL) 1205 public Name getQualifiedName() { 1206 return fullname; 1207 } 1208 1209 @DefinedBy(Api.LANGUAGE_MODEL) 1210 public boolean isUnnamed() { 1211 return name.isEmpty() && owner != null; 1212 } 1213 1214 public WriteableScope members() { 1215 complete(); 1216 return members_field; 1217 } 1218 1219 @Override 1220 public int poolTag() { 1221 return ClassFile.CONSTANT_Package; 1222 } 1223 1224 public long flags() { 1225 complete(); 1226 return flags_field; 1227 } 1228 1229 @Override 1230 public List<Attribute.Compound> getRawAttributes() { 1231 complete(); 1232 if (package_info != null) { 1233 package_info.complete(); 1234 mergeAttributes(); 1235 } 1236 return super.getRawAttributes(); 1237 } 1238 1239 private void mergeAttributes() { 1240 if (metadata == null && 1241 package_info.metadata != null) { 1242 metadata = new SymbolMetadata(this); 1243 metadata.setAttributes(package_info.metadata); 1244 } 1245 } 1246 1247 /** A package "exists" if a type or package that exists has 1248 * been seen within it. 1249 */ 1250 public boolean exists() { 1251 return (flags_field & EXISTS) != 0; 1252 } 1253 1254 @DefinedBy(Api.LANGUAGE_MODEL) 1255 public ElementKind getKind() { 1256 return ElementKind.PACKAGE; 1257 } 1258 1259 @DefinedBy(Api.LANGUAGE_MODEL) 1260 public Symbol getEnclosingElement() { 1261 return modle != null && !modle.isNoModule() ? modle : null; 1262 } 1263 1264 @DefinedBy(Api.LANGUAGE_MODEL) 1265 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1266 return v.visitPackage(this, p); 1267 } 1268 1269 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1270 return v.visitPackageSymbol(this, p); 1271 } 1272 1273 /**Resets the Symbol into the state good for next round of annotation processing.*/ 1274 public void reset() { 1275 metadata = null; 1276 } 1277 1278 } 1279 1280 public static class RootPackageSymbol extends PackageSymbol { 1281 public final MissingInfoHandler missingInfoHandler; 1282 public final boolean allowPrivateInvokeVirtual; 1283 1284 public RootPackageSymbol(Name name, Symbol owner, 1285 MissingInfoHandler missingInfoHandler, 1286 boolean allowPrivateInvokeVirtual) { 1287 super(name, owner); 1288 this.missingInfoHandler = missingInfoHandler; 1289 this.allowPrivateInvokeVirtual = allowPrivateInvokeVirtual; 1290 } 1291 1292 } 1293 1294 /** A class for class symbols 1295 */ 1296 @SuppressWarnings("preview") // isUnnamed() 1297 public static class ClassSymbol extends TypeSymbol implements TypeElement { 1298 1299 /** a scope for all class members; variables, methods and inner classes 1300 * type parameters are not part of this scope 1301 */ 1302 public WriteableScope members_field; 1303 1304 /** the fully qualified name of the class, i.e. pck.outer.inner. 1305 * null for anonymous classes 1306 */ 1307 public Name fullname; 1308 1309 /** the fully qualified name of the class after converting to flat 1310 * representation, i.e. pck.outer$inner, 1311 * set externally for local and anonymous classes 1312 */ 1313 public Name flatname; 1314 1315 /** the sourcefile where the class came from 1316 */ 1317 public JavaFileObject sourcefile; 1318 1319 /** the classfile from where to load this class 1320 * this will have extension .class or .java 1321 */ 1322 public JavaFileObject classfile; 1323 1324 /** the list of translated local classes (used for generating 1325 * InnerClasses attribute) 1326 */ 1327 public List<ClassSymbol> trans_local; 1328 1329 /** the annotation metadata attached to this class */ 1330 private AnnotationTypeMetadata annotationTypeMetadata; 1331 1332 /* the list of any of record components, only non empty if the class is a record 1333 * and it has at least one record component 1334 */ 1335 private List<RecordComponent> recordComponents = List.nil(); 1336 1337 // sealed classes related fields 1338 /** The classes, or interfaces, permitted to extend this class, or interface 1339 */ 1340 public List<Symbol> permitted; 1341 1342 public boolean isPermittedExplicit = false; 1343 1344 public ClassSymbol(long flags, Name name, Type type, Symbol owner) { 1345 super(TYP, flags, name, type, owner); 1346 this.members_field = null; 1347 this.fullname = formFullName(name, owner); 1348 this.flatname = formFlatName(name, owner); 1349 this.sourcefile = null; 1350 this.classfile = null; 1351 this.annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType(); 1352 this.permitted = List.nil(); 1353 } 1354 1355 public ClassSymbol(long flags, Name name, Symbol owner) { 1356 this( 1357 flags, 1358 name, 1359 new ClassType(Type.noType, null, null, List.nil(), Flavor.X_Typeof_X), 1360 owner); 1361 this.type.tsym = this; 1362 } 1363 1364 /** The Java source which this symbol represents. 1365 */ 1366 public String toString() { 1367 return className(); 1368 } 1369 1370 public long flags() { 1371 complete(); 1372 return flags_field; 1373 } 1374 1375 public WriteableScope members() { 1376 complete(); 1377 return members_field; 1378 } 1379 1380 @Override 1381 public List<Attribute.Compound> getRawAttributes() { 1382 complete(); 1383 return super.getRawAttributes(); 1384 } 1385 1386 @Override 1387 public List<Attribute.TypeCompound> getRawTypeAttributes() { 1388 complete(); 1389 return super.getRawTypeAttributes(); 1390 } 1391 1392 public Type erasure(Types types) { 1393 if (erasure_field == null) 1394 erasure_field = new ClassType(types.erasure(type.getEnclosingType()), 1395 List.nil(), this, 1396 type.getMetadata(), 1397 type.getFlavor()); 1398 return erasure_field; 1399 } 1400 1401 public String className() { 1402 if (name.isEmpty()) 1403 return 1404 Log.getLocalizedString("anonymous.class", flatname); 1405 else 1406 return fullname.toString(); 1407 } 1408 1409 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1410 public Name getQualifiedName() { 1411 return isUnnamed() ? fullname.subName(0, 0) /* empty name */ : fullname; 1412 } 1413 1414 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1415 public Name getSimpleName() { 1416 return name; 1417 } 1418 1419 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1420 public List<Symbol> getEnclosedElements() { 1421 List<Symbol> result = super.getEnclosedElements(); 1422 if (!recordComponents.isEmpty()) { 1423 List<RecordComponent> reversed = recordComponents.reverse(); 1424 for (RecordComponent rc : reversed) { 1425 result = result.prepend(rc); 1426 } 1427 } 1428 return result; 1429 } 1430 1431 public Name flatName() { 1432 return flatname; 1433 } 1434 1435 public boolean isSubClass(Symbol base, Types types) { 1436 if (this == base) { 1437 return true; 1438 } else if ((base.flags() & INTERFACE) != 0) { 1439 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t)) 1440 for (List<Type> is = types.interfaces(t); 1441 is.nonEmpty(); 1442 is = is.tail) 1443 if (is.head.tsym.isSubClass(base, types)) return true; 1444 } else { 1445 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t)) 1446 if (t.tsym == base) return true; 1447 } 1448 return false; 1449 } 1450 1451 /** Complete the elaboration of this symbol's definition. 1452 */ 1453 public void complete() throws CompletionFailure { 1454 Completer origCompleter = completer; 1455 try { 1456 super.complete(); 1457 } catch (CompletionFailure ex) { 1458 ex.dcfh.classSymbolCompleteFailed(this, origCompleter); 1459 // quiet error recovery 1460 flags_field |= (PUBLIC|STATIC); 1461 this.type = new ErrorType(this, Type.noType); 1462 throw ex; 1463 } finally { 1464 if (this.type != null && this.type.hasTag(CLASS)) { 1465 ClassType ct = (ClassType) this.type; 1466 ct.flavor = ct.flavor.metamorphose((this.flags_field & PRIMITIVE_CLASS) != 0); 1467 if (!this.type.isIntersection() && this.erasure_field != null && this.erasure_field.hasTag(CLASS)) { 1468 ((ClassType) this.erasure_field).flavor = ct.flavor; 1469 } 1470 } 1471 } 1472 } 1473 1474 @DefinedBy(Api.LANGUAGE_MODEL) 1475 public List<Type> getInterfaces() { 1476 apiComplete(); 1477 if (type instanceof ClassType classType) { 1478 if (classType.interfaces_field == null) // FIXME: shouldn't be null 1479 classType.interfaces_field = List.nil(); 1480 if (classType.all_interfaces_field != null) 1481 return Type.getModelTypes(classType.all_interfaces_field); 1482 return classType.interfaces_field; 1483 } else { 1484 return List.nil(); 1485 } 1486 } 1487 1488 @DefinedBy(Api.LANGUAGE_MODEL) 1489 public Type getSuperclass() { 1490 apiComplete(); 1491 if (type instanceof ClassType classType) { 1492 if (classType.supertype_field == null) // FIXME: shouldn't be null 1493 classType.supertype_field = Type.noType; 1494 // An interface has no superclass; its supertype is Object. 1495 return classType.isInterface() 1496 ? Type.noType 1497 : classType.supertype_field.getModelType(); 1498 } else { 1499 return Type.noType; 1500 } 1501 } 1502 1503 /** 1504 * Returns the next class to search for inherited annotations or {@code null} 1505 * if the next class can't be found. 1506 */ 1507 private ClassSymbol getSuperClassToSearchForAnnotations() { 1508 1509 Type sup = getSuperclass(); 1510 1511 if (!sup.hasTag(CLASS) || sup.isErroneous()) 1512 return null; 1513 1514 return (ClassSymbol) sup.tsym; 1515 } 1516 1517 1518 @Override 1519 protected <A extends Annotation> A[] getInheritedAnnotations(Class<A> annoType) { 1520 1521 ClassSymbol sup = getSuperClassToSearchForAnnotations(); 1522 1523 return sup == null ? super.getInheritedAnnotations(annoType) 1524 : sup.getAnnotationsByType(annoType); 1525 } 1526 1527 1528 @DefinedBy(Api.LANGUAGE_MODEL) 1529 public ElementKind getKind() { 1530 apiComplete(); 1531 long flags = flags(); 1532 if ((flags & ANNOTATION) != 0) 1533 return ElementKind.ANNOTATION_TYPE; 1534 else if ((flags & INTERFACE) != 0) 1535 return ElementKind.INTERFACE; 1536 else if ((flags & ENUM) != 0) 1537 return ElementKind.ENUM; 1538 else if ((flags & RECORD) != 0) 1539 return ElementKind.RECORD; 1540 else 1541 return ElementKind.CLASS; 1542 } 1543 1544 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1545 public Set<Modifier> getModifiers() { 1546 apiComplete(); 1547 long flags = flags(); 1548 return Flags.asModifierSet(flags & ~DEFAULT); 1549 } 1550 1551 public RecordComponent getRecordComponent(VarSymbol field) { 1552 for (RecordComponent rc : recordComponents) { 1553 if (rc.name == field.name) { 1554 return rc; 1555 } 1556 } 1557 return null; 1558 } 1559 1560 public RecordComponent findRecordComponentToRemove(JCVariableDecl var) { 1561 RecordComponent toRemove = null; 1562 for (RecordComponent rc : recordComponents) { 1563 /* it could be that a record erroneously declares two record components with the same name, in that 1564 * case we need to use the position to disambiguate 1565 */ 1566 if (rc.name == var.name && var.pos == rc.pos) { 1567 toRemove = rc; 1568 } 1569 } 1570 return toRemove; 1571 } 1572 1573 /* creates a record component if non is related to the given variable and recreates a brand new one 1574 * in other case 1575 */ 1576 public RecordComponent createRecordComponent(RecordComponent existing, JCVariableDecl rcDecl, VarSymbol varSym) { 1577 RecordComponent rc = null; 1578 if (existing != null) { 1579 recordComponents = List.filter(recordComponents, existing); 1580 recordComponents = recordComponents.append(rc = new RecordComponent(varSym, existing.ast, existing.isVarargs)); 1581 } else { 1582 // Didn't find the record component: create one. 1583 recordComponents = recordComponents.append(rc = new RecordComponent(varSym, rcDecl)); 1584 } 1585 return rc; 1586 } 1587 1588 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1589 public List<? extends RecordComponent> getRecordComponents() { 1590 return recordComponents; 1591 } 1592 1593 public void setRecordComponents(List<RecordComponent> recordComponents) { 1594 this.recordComponents = recordComponents; 1595 } 1596 1597 @DefinedBy(Api.LANGUAGE_MODEL) 1598 public NestingKind getNestingKind() { 1599 apiComplete(); 1600 if (owner.kind == PCK) // Handles unnamed classes as well 1601 return NestingKind.TOP_LEVEL; 1602 else if (name.isEmpty()) 1603 return NestingKind.ANONYMOUS; 1604 else if (owner.kind == MTH) 1605 return NestingKind.LOCAL; 1606 else 1607 return NestingKind.MEMBER; 1608 } 1609 1610 @Override 1611 protected <A extends Annotation> Attribute.Compound getAttribute(final Class<A> annoType) { 1612 1613 Attribute.Compound attrib = super.getAttribute(annoType); 1614 1615 boolean inherited = annoType.isAnnotationPresent(Inherited.class); 1616 if (attrib != null || !inherited) 1617 return attrib; 1618 1619 // Search supertypes 1620 ClassSymbol superType = getSuperClassToSearchForAnnotations(); 1621 return superType == null ? null 1622 : superType.getAttribute(annoType); 1623 } 1624 1625 @DefinedBy(Api.LANGUAGE_MODEL) 1626 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1627 return v.visitType(this, p); 1628 } 1629 1630 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1631 return v.visitClassSymbol(this, p); 1632 } 1633 1634 public void markAbstractIfNeeded(Types types) { 1635 if (types.enter.getEnv(this) != null && 1636 (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym && 1637 (flags() & (FINAL | ABSTRACT)) == 0) { 1638 if (types.firstUnimplementedAbstract(this) != null) 1639 // add the ABSTRACT flag to an enum 1640 flags_field |= ABSTRACT; 1641 } 1642 } 1643 1644 /**Resets the Symbol into the state good for next round of annotation processing.*/ 1645 public void reset() { 1646 kind = TYP; 1647 erasure_field = null; 1648 members_field = null; 1649 flags_field = 0; 1650 if (type instanceof ClassType classType) { 1651 classType.setEnclosingType(Type.noType); 1652 classType.rank_field = -1; 1653 classType.typarams_field = null; 1654 classType.allparams_field = null; 1655 classType.supertype_field = null; 1656 classType.interfaces_field = null; 1657 classType.all_interfaces_field = null; 1658 classType.flavor = Flavor.X_Typeof_X; 1659 } 1660 clearAnnotationMetadata(); 1661 } 1662 1663 public void clearAnnotationMetadata() { 1664 metadata = null; 1665 annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType(); 1666 } 1667 1668 @Override 1669 public AnnotationTypeMetadata getAnnotationTypeMetadata() { 1670 return annotationTypeMetadata; 1671 } 1672 1673 @Override 1674 public boolean isAnnotationType() { 1675 return (flags_field & Flags.ANNOTATION) != 0; 1676 } 1677 1678 public void setAnnotationTypeMetadata(AnnotationTypeMetadata a) { 1679 Assert.checkNonNull(a); 1680 Assert.check(!annotationTypeMetadata.isMetadataForAnnotationType()); 1681 this.annotationTypeMetadata = a; 1682 } 1683 1684 public boolean isRecord() { 1685 return (flags_field & RECORD) != 0; 1686 } 1687 1688 @DefinedBy(Api.LANGUAGE_MODEL) 1689 public List<Type> getPermittedSubclasses() { 1690 return permitted.map(s -> s.type); 1691 } 1692 1693 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1694 public boolean isUnnamed() { 1695 return (flags_field & Flags.UNNAMED_CLASS) != 0 ; 1696 } 1697 } 1698 1699 1700 /** A class for variable symbols 1701 */ 1702 @SuppressWarnings("preview") 1703 public static class VarSymbol extends Symbol implements VariableElement { 1704 1705 /** The variable's declaration position. 1706 */ 1707 public int pos = Position.NOPOS; 1708 1709 /** The variable's address. Used for different purposes during 1710 * flow analysis, translation and code generation. 1711 * Flow analysis: 1712 * If this is a blank final or local variable, its sequence number. 1713 * Translation: 1714 * If this is a private field, its access number. 1715 * Code generation: 1716 * If this is a local variable, its logical slot number. 1717 */ 1718 public int adr = -1; 1719 1720 /** Construct a variable symbol, given its flags, name, type and owner. 1721 */ 1722 public VarSymbol(long flags, Name name, Type type, Symbol owner) { 1723 super(VAR, flags, name, type, owner); 1724 } 1725 1726 @Override 1727 public int poolTag() { 1728 return ClassFile.CONSTANT_Fieldref; 1729 } 1730 1731 public MethodHandleSymbol asMethodHandle(boolean getter) { 1732 return new MethodHandleSymbol(this, getter); 1733 } 1734 1735 /** Clone this symbol with new owner. 1736 */ 1737 public VarSymbol clone(Symbol newOwner) { 1738 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) { 1739 @Override 1740 public Symbol baseSymbol() { 1741 return VarSymbol.this; 1742 } 1743 1744 @Override 1745 public Object poolKey(Types types) { 1746 return new Pair<>(newOwner, baseSymbol()); 1747 } 1748 }; 1749 v.pos = pos; 1750 v.adr = adr; 1751 v.data = data; 1752 // System.out.println("clone " + v + " in " + newOwner);//DEBUG 1753 return v; 1754 } 1755 1756 public String toString() { 1757 return name.toString(); 1758 } 1759 1760 public Symbol asMemberOf(Type site, Types types) { 1761 return new VarSymbol(flags_field, name, types.memberType(site, this), owner); 1762 } 1763 1764 @DefinedBy(Api.LANGUAGE_MODEL) 1765 public ElementKind getKind() { 1766 long flags = flags(); 1767 if ((flags & PARAMETER) != 0) { 1768 if (isExceptionParameter()) 1769 return ElementKind.EXCEPTION_PARAMETER; 1770 else 1771 return ElementKind.PARAMETER; 1772 } else if ((flags & ENUM) != 0) { 1773 return ElementKind.ENUM_CONSTANT; 1774 } else if (owner.kind == TYP || owner.kind == ERR) { 1775 return ElementKind.FIELD; 1776 } else if (isResourceVariable()) { 1777 return ElementKind.RESOURCE_VARIABLE; 1778 } else if ((flags & MATCH_BINDING) != 0) { 1779 ElementKind kind = ElementKind.BINDING_VARIABLE; 1780 return kind; 1781 } else { 1782 return ElementKind.LOCAL_VARIABLE; 1783 } 1784 } 1785 1786 @DefinedBy(Api.LANGUAGE_MODEL) 1787 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1788 return v.visitVariable(this, p); 1789 } 1790 1791 @DefinedBy(Api.LANGUAGE_MODEL) 1792 public Object getConstantValue() { // Mirror API 1793 return Constants.decode(getConstValue(), type); 1794 } 1795 1796 public void setLazyConstValue(final Env<AttrContext> env, 1797 final Attr attr, 1798 final JCVariableDecl variable) 1799 { 1800 setData((Callable<Object>)() -> attr.attribLazyConstantValue(env, variable, type)); 1801 } 1802 1803 /** 1804 * The variable's constant value, if this is a constant. 1805 * Before the constant value is evaluated, it points to an 1806 * initializer environment. If this is not a constant, it can 1807 * be used for other stuff. 1808 */ 1809 private Object data; 1810 1811 public boolean isExceptionParameter() { 1812 return data == ElementKind.EXCEPTION_PARAMETER; 1813 } 1814 1815 public boolean isResourceVariable() { 1816 return data == ElementKind.RESOURCE_VARIABLE; 1817 } 1818 1819 public Object getConstValue() { 1820 // TODO: Consider if getConstValue and getConstantValue can be collapsed 1821 if (data == ElementKind.EXCEPTION_PARAMETER || 1822 data == ElementKind.RESOURCE_VARIABLE) { 1823 return null; 1824 } else if (data instanceof Callable<?> callableData) { 1825 // In this case, this is a final variable, with an as 1826 // yet unevaluated initializer. 1827 data = null; // to make sure we don't evaluate this twice. 1828 try { 1829 data = callableData.call(); 1830 } catch (Exception ex) { 1831 throw new AssertionError(ex); 1832 } 1833 } 1834 return data; 1835 } 1836 1837 public void setData(Object data) { 1838 Assert.check(!(data instanceof Env<?>), this); 1839 this.data = data; 1840 } 1841 1842 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1843 return v.visitVarSymbol(this, p); 1844 } 1845 1846 public boolean isUnnamedVariable() { 1847 return name.isEmpty(); 1848 } 1849 } 1850 1851 public static class RecordComponent extends VarSymbol implements RecordComponentElement { 1852 public MethodSymbol accessor; 1853 public JCTree.JCMethodDecl accessorMeth; 1854 1855 /* if the user happens to erroneously declare two components with the same name, we need a way to differentiate 1856 * them, the code will fail anyway but we need to keep the information for better error recovery 1857 */ 1858 private final int pos; 1859 1860 private final boolean isVarargs; 1861 1862 private JCVariableDecl ast; 1863 1864 /** 1865 * Construct a record component, given its flags, name, type and owner. 1866 */ 1867 public RecordComponent(Name name, Type type, Symbol owner) { 1868 super(PUBLIC, name, type, owner); 1869 pos = -1; 1870 ast = null; 1871 isVarargs = false; 1872 } 1873 1874 public RecordComponent(VarSymbol field, JCVariableDecl ast) { 1875 this(field, ast, field.type.hasTag(TypeTag.ARRAY) && ((ArrayType)field.type).isVarargs()); 1876 } 1877 1878 public RecordComponent(VarSymbol field, JCVariableDecl ast, boolean isVarargs) { 1879 super(PUBLIC, field.name, field.type, field.owner); 1880 this.ast = ast; 1881 this.pos = field.pos; 1882 /* it is better to store the original information for this one, instead of relying 1883 * on the info in the type of the symbol. This is because on the presence of APs 1884 * the symbol will be blown out and we won't be able to know if the original 1885 * record component was declared varargs or not. 1886 */ 1887 this.isVarargs = isVarargs; 1888 } 1889 1890 public List<JCAnnotation> getOriginalAnnos() { return this.ast == null ? List.nil() : this.ast.mods.annotations; } 1891 1892 public JCVariableDecl declarationFor() { return this.ast; } 1893 1894 public boolean isVarargs() { 1895 return isVarargs; 1896 } 1897 1898 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1899 public ElementKind getKind() { 1900 return ElementKind.RECORD_COMPONENT; 1901 } 1902 1903 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1904 public ExecutableElement getAccessor() { 1905 return accessor; 1906 } 1907 1908 @Override @DefinedBy(Api.LANGUAGE_MODEL) 1909 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1910 return v.visitRecordComponent(this, p); 1911 } 1912 } 1913 1914 public static class ParamSymbol extends VarSymbol { 1915 public ParamSymbol(long flags, Name name, Type type, Symbol owner) { 1916 super(flags, name, type, owner); 1917 } 1918 1919 @Override 1920 public Name getSimpleName() { 1921 if ((flags_field & NAME_FILLED) == 0) { 1922 flags_field |= NAME_FILLED; 1923 Symbol rootPack = this; 1924 while (rootPack != null && !(rootPack instanceof RootPackageSymbol)) { 1925 rootPack = rootPack.owner; 1926 } 1927 if (rootPack != null) { 1928 Name inferredName = 1929 ((RootPackageSymbol) rootPack).missingInfoHandler.getParameterName(this); 1930 if (inferredName != null) { 1931 this.name = inferredName; 1932 } 1933 } 1934 } 1935 return super.getSimpleName(); 1936 } 1937 1938 } 1939 1940 public static class BindingSymbol extends VarSymbol { 1941 1942 public BindingSymbol(long flags, Name name, Type type, Symbol owner) { 1943 super(flags | Flags.HASINIT | Flags.MATCH_BINDING, name, type, owner); 1944 } 1945 1946 public boolean isAliasFor(BindingSymbol b) { 1947 return aliases().containsAll(b.aliases()); 1948 } 1949 1950 List<BindingSymbol> aliases() { 1951 return List.of(this); 1952 } 1953 1954 public void preserveBinding() { 1955 flags_field |= Flags.MATCH_BINDING_TO_OUTER; 1956 } 1957 1958 public boolean isPreserved() { 1959 return (flags_field & Flags.MATCH_BINDING_TO_OUTER) != 0; 1960 } 1961 } 1962 1963 /** A class for method symbols. 1964 */ 1965 public static class MethodSymbol extends Symbol implements ExecutableElement { 1966 1967 /** The code of the method. */ 1968 public Code code = null; 1969 1970 /** The extra (synthetic/mandated) parameters of the method. */ 1971 public List<VarSymbol> extraParams = List.nil(); 1972 1973 /** The captured local variables in an anonymous class */ 1974 public List<VarSymbol> capturedLocals = List.nil(); 1975 1976 /** The parameters of the method. */ 1977 public List<VarSymbol> params = null; 1978 1979 /** For an annotation type element, its default value if any. 1980 * The value is null if none appeared in the method 1981 * declaration. 1982 */ 1983 public Attribute defaultValue = null; 1984 1985 /** Construct a method symbol, given its flags, name, type and owner. 1986 */ 1987 public MethodSymbol(long flags, Name name, Type type, Symbol owner) { 1988 super(MTH, flags, name, type, owner); 1989 if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name); 1990 } 1991 1992 /** Clone this symbol with new owner. 1993 */ 1994 public MethodSymbol clone(Symbol newOwner) { 1995 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) { 1996 @Override 1997 public Symbol baseSymbol() { 1998 return MethodSymbol.this; 1999 } 2000 2001 @Override 2002 public Object poolKey(Types types) { 2003 return new Pair<>(newOwner, baseSymbol()); 2004 } 2005 }; 2006 m.code = code; 2007 return m; 2008 } 2009 2010 @Override @DefinedBy(Api.LANGUAGE_MODEL) 2011 public Set<Modifier> getModifiers() { 2012 long flags = flags(); 2013 return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags); 2014 } 2015 2016 /** The Java source which this symbol represents. 2017 */ 2018 public String toString() { 2019 if ((flags() & BLOCK) != 0) { 2020 return owner.name.toString(); 2021 } else { 2022 String s = isInitOrVNew() 2023 ? owner.name.toString() 2024 : name.toString(); 2025 if (type != null) { 2026 if (type.hasTag(FORALL)) 2027 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s; 2028 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")"; 2029 } 2030 return s; 2031 } 2032 } 2033 2034 @Override 2035 public int poolTag() { 2036 return owner.isInterface() ? 2037 ClassFile.CONSTANT_InterfaceMethodref : ClassFile.CONSTANT_Methodref; 2038 } 2039 2040 public boolean isHandle() { 2041 return false; 2042 } 2043 2044 2045 public MethodHandleSymbol asHandle() { 2046 return new MethodHandleSymbol(this); 2047 } 2048 2049 /** find a symbol that this (proxy method) symbol implements. 2050 * @param c The class whose members are searched for 2051 * implementations 2052 */ 2053 public Symbol implemented(TypeSymbol c, Types types) { 2054 Symbol impl = null; 2055 for (List<Type> is = types.interfaces(c.type); 2056 impl == null && is.nonEmpty(); 2057 is = is.tail) { 2058 TypeSymbol i = is.head.tsym; 2059 impl = implementedIn(i, types); 2060 if (impl == null) 2061 impl = implemented(i, types); 2062 } 2063 return impl; 2064 } 2065 2066 public Symbol implementedIn(TypeSymbol c, Types types) { 2067 Symbol impl = null; 2068 for (Symbol sym : c.members().getSymbolsByName(name)) { 2069 if (this.overrides(sym, (TypeSymbol)owner, types, true) && 2070 // FIXME: I suspect the following requires a 2071 // subst() for a parametric return type. 2072 types.isSameType(type.getReturnType(), 2073 types.memberType(owner.type, sym).getReturnType())) { 2074 impl = sym; 2075 } 2076 } 2077 return impl; 2078 } 2079 2080 /** Will the erasure of this method be considered by the VM to 2081 * override the erasure of the other when seen from class `origin'? 2082 */ 2083 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) { 2084 if (isInitOrVNew() || _other.kind != MTH) return false; 2085 2086 if (this == _other) return true; 2087 MethodSymbol other = (MethodSymbol)_other; 2088 2089 // check for a direct implementation 2090 if (other.isOverridableIn((TypeSymbol)owner) && 2091 types.asSuper(owner.type.referenceProjectionOrSelf(), other.owner) != null && 2092 types.isSameType(erasure(types), other.erasure(types))) 2093 return true; 2094 2095 // check for an inherited implementation 2096 return 2097 (flags() & ABSTRACT) == 0 && 2098 other.isOverridableIn(origin) && 2099 this.isMemberOf(origin, types) && 2100 types.isSameType(erasure(types), other.erasure(types)); 2101 } 2102 2103 /** The implementation of this (abstract) symbol in class origin, 2104 * from the VM's point of view, null if method does not have an 2105 * implementation in class. 2106 * @param origin The class of which the implementation is a member. 2107 */ 2108 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) { 2109 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) { 2110 for (Symbol sym : c.members().getSymbolsByName(name)) { 2111 if (sym.kind == MTH && 2112 ((MethodSymbol)sym).binaryOverrides(this, origin, types)) 2113 return (MethodSymbol)sym; 2114 } 2115 } 2116 return null; 2117 } 2118 2119 /** Does this symbol override `other' symbol, when both are seen as 2120 * members of class `origin'? It is assumed that _other is a member 2121 * of origin. 2122 * 2123 * It is assumed that both symbols have the same name. The static 2124 * modifier is ignored for this test. 2125 * 2126 * A quirk in the works is that if the receiver is a method symbol for 2127 * an inherited abstract method we answer false summarily all else being 2128 * immaterial. Abstract "own" methods (i.e `this' is a direct member of 2129 * origin) don't get rejected as summarily and are put to test against the 2130 * suitable criteria. 2131 * 2132 * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4 2133 */ 2134 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { 2135 return overrides(_other, origin, types, checkResult, true); 2136 } 2137 2138 /** Does this symbol override `other' symbol, when both are seen as 2139 * members of class `origin'? It is assumed that _other is a member 2140 * of origin. 2141 * 2142 * Caveat: If `this' is an abstract inherited member of origin, it is 2143 * deemed to override `other' only when `requireConcreteIfInherited' 2144 * is false. 2145 * 2146 * It is assumed that both symbols have the same name. The static 2147 * modifier is ignored for this test. 2148 * 2149 * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4 2150 */ 2151 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult, 2152 boolean requireConcreteIfInherited) { 2153 if (isInitOrVNew() || _other.kind != MTH) return false; 2154 2155 if (this == _other) return true; 2156 MethodSymbol other = (MethodSymbol)_other; 2157 2158 // check for a direct implementation 2159 if (other.isOverridableIn((TypeSymbol)owner) && 2160 types.asSuper(owner.type.referenceProjectionOrSelf(), other.owner) != null) { 2161 Type mt = types.memberType(owner.type, this); 2162 Type ot = types.memberType(owner.type, other); 2163 if (types.isSubSignature(mt, ot)) { 2164 if (!checkResult) 2165 return true; 2166 if (types.returnTypeSubstitutable(mt, ot)) 2167 return true; 2168 } 2169 } 2170 2171 // check for an inherited implementation 2172 if (((flags() & ABSTRACT) != 0 && requireConcreteIfInherited) || 2173 ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) || 2174 !other.isOverridableIn(origin) || 2175 !this.isMemberOf(origin, types)) 2176 return false; 2177 2178 // assert types.asSuper(origin.type, other.owner) != null; 2179 Type mt = types.memberType(origin.type, this); 2180 Type ot = types.memberType(origin.type, other); 2181 return 2182 types.isSubSignature(mt, ot) && 2183 (!checkResult || types.resultSubtype(mt, ot, types.noWarnings)); 2184 } 2185 2186 private boolean isOverridableIn(TypeSymbol origin) { 2187 // JLS 8.4.8.1 2188 switch ((int)(flags_field & Flags.AccessFlags)) { 2189 case Flags.PRIVATE: 2190 return false; 2191 case Flags.PUBLIC: 2192 return !this.owner.isInterface() || 2193 (flags_field & STATIC) == 0; 2194 case Flags.PROTECTED: 2195 return (origin.flags() & INTERFACE) == 0; 2196 case 0: 2197 // for package private: can only override in the same 2198 // package 2199 return 2200 this.packge() == origin.packge() && 2201 (origin.flags() & INTERFACE) == 0; 2202 default: 2203 return false; 2204 } 2205 } 2206 2207 @Override 2208 public boolean isInheritedIn(Symbol clazz, Types types) { 2209 switch ((int)(flags_field & Flags.AccessFlags)) { 2210 case PUBLIC: 2211 return !this.owner.isInterface() || 2212 clazz == owner || 2213 (flags_field & STATIC) == 0; 2214 default: 2215 return super.isInheritedIn(clazz, types); 2216 } 2217 } 2218 2219 public boolean isLambdaMethod() { 2220 return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD; 2221 } 2222 2223 /** override this method to point to the original enclosing method if this method symbol represents a synthetic 2224 * lambda method 2225 */ 2226 public MethodSymbol originalEnclosingMethod() { 2227 return this; 2228 } 2229 2230 /** The implementation of this (abstract) symbol in class origin; 2231 * null if none exists. Synthetic methods are not considered 2232 * as possible implementations. 2233 */ 2234 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { 2235 return implementation(origin, types, checkResult, implementation_filter); 2236 } 2237 // where 2238 public static final Predicate<Symbol> implementation_filter = s -> 2239 s.kind == MTH && (s.flags() & SYNTHETIC) == 0; 2240 2241 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Predicate<Symbol> implFilter) { 2242 MethodSymbol res = types.implementation(this, origin, checkResult, implFilter); 2243 if (res != null) 2244 return res; 2245 // if origin is derived from a raw type, we might have missed 2246 // an implementation because we do not know enough about instantiations. 2247 // in this case continue with the supertype as origin. 2248 if (types.isDerivedRaw(origin.type) && !origin.isInterface()) 2249 return implementation(types.supertype(origin.type).tsym, types, checkResult); 2250 else 2251 return null; 2252 } 2253 2254 public List<VarSymbol> params() { 2255 owner.complete(); 2256 if (params == null) { 2257 ListBuffer<VarSymbol> newParams = new ListBuffer<>(); 2258 int i = 0; 2259 for (Type t : type.getParameterTypes()) { 2260 Name paramName = name.table.fromString("arg" + i); 2261 VarSymbol param = new VarSymbol(PARAMETER, paramName, t, this); 2262 newParams.append(param); 2263 i++; 2264 } 2265 params = newParams.toList(); 2266 } 2267 Assert.checkNonNull(params); 2268 return params; 2269 } 2270 2271 public Symbol asMemberOf(Type site, Types types) { 2272 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner); 2273 } 2274 2275 @DefinedBy(Api.LANGUAGE_MODEL) 2276 public ElementKind getKind() { 2277 if (isInitOrVNew()) 2278 return ElementKind.CONSTRUCTOR; 2279 else if (name == name.table.names.clinit) 2280 return ElementKind.STATIC_INIT; 2281 else if ((flags() & BLOCK) != 0) 2282 return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT; 2283 else 2284 return ElementKind.METHOD; 2285 } 2286 2287 public boolean isStaticOrInstanceInit() { 2288 return getKind() == ElementKind.STATIC_INIT || 2289 getKind() == ElementKind.INSTANCE_INIT; 2290 } 2291 2292 @DefinedBy(Api.LANGUAGE_MODEL) 2293 public Attribute getDefaultValue() { 2294 return defaultValue; 2295 } 2296 2297 @DefinedBy(Api.LANGUAGE_MODEL) 2298 public List<VarSymbol> getParameters() { 2299 return params(); 2300 } 2301 2302 @DefinedBy(Api.LANGUAGE_MODEL) 2303 public boolean isVarArgs() { 2304 return (flags() & VARARGS) != 0; 2305 } 2306 2307 @DefinedBy(Api.LANGUAGE_MODEL) 2308 public boolean isDefault() { 2309 return (flags() & DEFAULT) != 0; 2310 } 2311 2312 @DefinedBy(Api.LANGUAGE_MODEL) 2313 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 2314 return v.visitExecutable(this, p); 2315 } 2316 2317 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 2318 return v.visitMethodSymbol(this, p); 2319 } 2320 2321 @DefinedBy(Api.LANGUAGE_MODEL) 2322 public Type getReceiverType() { 2323 return asType().getReceiverType(); 2324 } 2325 2326 @DefinedBy(Api.LANGUAGE_MODEL) 2327 public Type getReturnType() { 2328 return asType().getReturnType(); 2329 } 2330 2331 @DefinedBy(Api.LANGUAGE_MODEL) 2332 public List<Type> getThrownTypes() { 2333 return asType().getThrownTypes(); 2334 } 2335 } 2336 2337 /** A class for invokedynamic method calls. 2338 */ 2339 public static class DynamicMethodSymbol extends MethodSymbol implements Dynamic { 2340 2341 public LoadableConstant[] staticArgs; 2342 public MethodHandleSymbol bsm; 2343 2344 public DynamicMethodSymbol(Name name, Symbol owner, MethodHandleSymbol bsm, Type type, LoadableConstant[] staticArgs) { 2345 super(0, name, type, owner); 2346 this.bsm = bsm; 2347 this.staticArgs = staticArgs; 2348 } 2349 2350 @Override 2351 public Name name() { 2352 return name; 2353 } 2354 2355 @Override 2356 public boolean isDynamic() { 2357 return true; 2358 } 2359 2360 @Override 2361 public LoadableConstant[] staticArgs() { 2362 return staticArgs; 2363 } 2364 2365 @Override 2366 public MethodHandleSymbol bootstrapMethod() { 2367 return bsm; 2368 } 2369 2370 @Override 2371 public int poolTag() { 2372 return ClassFile.CONSTANT_InvokeDynamic; 2373 } 2374 2375 @Override 2376 public Type dynamicType() { 2377 return type; 2378 } 2379 } 2380 2381 /** A class for condy. 2382 */ 2383 public static class DynamicVarSymbol extends VarSymbol implements Dynamic, LoadableConstant { 2384 public LoadableConstant[] staticArgs; 2385 public MethodHandleSymbol bsm; 2386 2387 public DynamicVarSymbol(Name name, Symbol owner, MethodHandleSymbol bsm, Type type, LoadableConstant[] staticArgs) { 2388 super(0, name, type, owner); 2389 this.bsm = bsm; 2390 this.staticArgs = staticArgs; 2391 } 2392 2393 @Override 2394 public Name name() { 2395 return name; 2396 } 2397 2398 @Override 2399 public boolean isDynamic() { 2400 return true; 2401 } 2402 2403 @Override 2404 public PoolConstant dynamicType() { 2405 return type; 2406 } 2407 2408 @Override 2409 public LoadableConstant[] staticArgs() { 2410 return staticArgs; 2411 } 2412 2413 @Override 2414 public LoadableConstant bootstrapMethod() { 2415 return bsm; 2416 } 2417 2418 @Override 2419 public int poolTag() { 2420 return ClassFile.CONSTANT_Dynamic; 2421 } 2422 } 2423 2424 /** A class for method handles. 2425 */ 2426 public static class MethodHandleSymbol extends MethodSymbol implements LoadableConstant { 2427 2428 private Symbol refSym; 2429 private boolean getter; 2430 2431 public MethodHandleSymbol(Symbol msym) { 2432 this(msym, false); 2433 } 2434 2435 public MethodHandleSymbol(Symbol msym, boolean getter) { 2436 super(msym.flags_field, msym.name, msym.type, msym.owner); 2437 this.refSym = msym; 2438 this.getter = getter; 2439 } 2440 2441 /** 2442 * Returns the kind associated with this method handle. 2443 */ 2444 public int referenceKind() { 2445 if (refSym.kind == VAR) { 2446 return getter ? 2447 refSym.isStatic() ? ClassFile.REF_getStatic : ClassFile.REF_getField : 2448 refSym.isStatic() ? ClassFile.REF_putStatic : ClassFile.REF_putField; 2449 } else { 2450 if (refSym.isInitOrVNew()) { 2451 return ClassFile.REF_newInvokeSpecial; 2452 } else { 2453 if (refSym.isStatic()) { 2454 return ClassFile.REF_invokeStatic; 2455 } else if ((refSym.flags() & PRIVATE) != 0 && !allowPrivateInvokeVirtual()) { 2456 return ClassFile.REF_invokeSpecial; 2457 } else if (refSym.enclClass().isInterface()) { 2458 return ClassFile.REF_invokeInterface; 2459 } else { 2460 return ClassFile.REF_invokeVirtual; 2461 } 2462 } 2463 } 2464 } 2465 2466 private boolean allowPrivateInvokeVirtual() { 2467 Symbol rootPack = this; 2468 while (rootPack != null && !(rootPack instanceof RootPackageSymbol)) { 2469 rootPack = rootPack.owner; 2470 } 2471 return rootPack != null && ((RootPackageSymbol) rootPack).allowPrivateInvokeVirtual; 2472 } 2473 @Override 2474 public int poolTag() { 2475 return ClassFile.CONSTANT_MethodHandle; 2476 } 2477 2478 @Override 2479 public Object poolKey(Types types) { 2480 return new Pair<>(baseSymbol(), referenceKind()); 2481 } 2482 2483 @Override 2484 public MethodHandleSymbol asHandle() { 2485 return this; 2486 } 2487 2488 @Override 2489 public Symbol baseSymbol() { 2490 return refSym; 2491 } 2492 2493 2494 @Override 2495 public boolean isHandle() { 2496 return true; 2497 } 2498 } 2499 2500 /** A class for predefined operators. 2501 */ 2502 public static class OperatorSymbol extends MethodSymbol { 2503 2504 public int opcode; 2505 private int accessCode = Integer.MIN_VALUE; 2506 2507 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) { 2508 super(PUBLIC | STATIC, name, type, owner); 2509 this.opcode = opcode; 2510 } 2511 2512 @Override 2513 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 2514 return v.visitOperatorSymbol(this, p); 2515 } 2516 2517 public int getAccessCode(Tag tag) { 2518 if (accessCode != Integer.MIN_VALUE && !tag.isIncOrDecUnaryOp()) { 2519 return accessCode; 2520 } 2521 accessCode = AccessCode.from(tag, opcode); 2522 return accessCode; 2523 } 2524 2525 /** Access codes for dereferencing, assignment, 2526 * and pre/post increment/decrement. 2527 2528 * All access codes for accesses to the current class are even. 2529 * If a member of the superclass should be accessed instead (because 2530 * access was via a qualified super), add one to the corresponding code 2531 * for the current class, making the number odd. 2532 * This numbering scheme is used by the backend to decide whether 2533 * to issue an invokevirtual or invokespecial call. 2534 * 2535 * @see Gen#visitSelect(JCFieldAccess tree) 2536 */ 2537 public enum AccessCode { 2538 UNKNOWN(-1, Tag.NO_TAG), 2539 DEREF(0, Tag.NO_TAG), 2540 ASSIGN(2, Tag.ASSIGN), 2541 PREINC(4, Tag.PREINC), 2542 PREDEC(6, Tag.PREDEC), 2543 POSTINC(8, Tag.POSTINC), 2544 POSTDEC(10, Tag.POSTDEC), 2545 FIRSTASGOP(12, Tag.NO_TAG); 2546 2547 public final int code; 2548 public final Tag tag; 2549 public static final int numberOfAccessCodes = (lushrl - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code + 2; 2550 2551 AccessCode(int code, Tag tag) { 2552 this.code = code; 2553 this.tag = tag; 2554 } 2555 2556 public static AccessCode getFromCode(int code) { 2557 for (AccessCode aCodes : AccessCode.values()) { 2558 if (aCodes.code == code) { 2559 return aCodes; 2560 } 2561 } 2562 return UNKNOWN; 2563 } 2564 2565 static int from(Tag tag, int opcode) { 2566 /** Map bytecode of binary operation to access code of corresponding 2567 * assignment operation. This is always an even number. 2568 */ 2569 switch (tag) { 2570 case PREINC: 2571 return AccessCode.PREINC.code; 2572 case PREDEC: 2573 return AccessCode.PREDEC.code; 2574 case POSTINC: 2575 return AccessCode.POSTINC.code; 2576 case POSTDEC: 2577 return AccessCode.POSTDEC.code; 2578 } 2579 if (iadd <= opcode && opcode <= lxor) { 2580 return (opcode - iadd) * 2 + FIRSTASGOP.code; 2581 } else if (opcode == string_add) { 2582 return (lxor + 1 - iadd) * 2 + FIRSTASGOP.code; 2583 } else if (ishll <= opcode && opcode <= lushrl) { 2584 return (opcode - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code; 2585 } 2586 return -1; 2587 } 2588 } 2589 } 2590 2591 /** Symbol completer interface. 2592 */ 2593 public static interface Completer { 2594 2595 /** Dummy completer to be used when the symbol has been completed or 2596 * does not need completion. 2597 */ 2598 public static final Completer NULL_COMPLETER = new Completer() { 2599 public void complete(Symbol sym) { } 2600 public boolean isTerminal() { return true; } 2601 }; 2602 2603 void complete(Symbol sym) throws CompletionFailure; 2604 2605 /** Returns true if this completer is <em>terminal</em>. A terminal 2606 * completer is used as a place holder when the symbol is completed. 2607 * Calling complete on a terminal completer will not affect the symbol. 2608 * 2609 * The dummy NULL_COMPLETER and the GraphDependencies completer are 2610 * examples of terminal completers. 2611 * 2612 * @return true iff this completer is terminal 2613 */ 2614 default boolean isTerminal() { 2615 return false; 2616 } 2617 } 2618 2619 public static class CompletionFailure extends RuntimeException { 2620 private static final long serialVersionUID = 0; 2621 public final transient DeferredCompletionFailureHandler dcfh; 2622 public transient Symbol sym; 2623 2624 /** A diagnostic object describing the failure 2625 */ 2626 private transient JCDiagnostic diag; 2627 2628 private transient Supplier<JCDiagnostic> diagSupplier; 2629 2630 public CompletionFailure(Symbol sym, Supplier<JCDiagnostic> diagSupplier, DeferredCompletionFailureHandler dcfh) { 2631 this.dcfh = dcfh; 2632 this.sym = sym; 2633 this.diagSupplier = diagSupplier; 2634 // this.printStackTrace();//DEBUG 2635 } 2636 2637 public JCDiagnostic getDiagnostic() { 2638 if (diag == null && diagSupplier != null) { 2639 diag = diagSupplier.get(); 2640 } 2641 return diag; 2642 } 2643 2644 @Override 2645 public String getMessage() { 2646 return getDiagnostic().getMessage(null); 2647 } 2648 2649 public JCDiagnostic getDetailValue() { 2650 return getDiagnostic(); 2651 } 2652 2653 @Override 2654 public CompletionFailure initCause(Throwable cause) { 2655 super.initCause(cause); 2656 return this; 2657 } 2658 2659 public void resetDiagnostic(Supplier<JCDiagnostic> diagSupplier) { 2660 this.diagSupplier = diagSupplier; 2661 this.diag = null; 2662 } 2663 2664 } 2665 2666 /** 2667 * A visitor for symbols. A visitor is used to implement operations 2668 * (or relations) on symbols. Most common operations on types are 2669 * binary relations and this interface is designed for binary 2670 * relations, that is, operations on the form 2671 * Symbol × P → R. 2672 * <!-- In plain text: Type x P -> R --> 2673 * 2674 * @param <R> the return type of the operation implemented by this 2675 * visitor; use Void if no return type is needed. 2676 * @param <P> the type of the second argument (the first being the 2677 * symbol itself) of the operation implemented by this visitor; use 2678 * Void if a second argument is not needed. 2679 */ 2680 public interface Visitor<R,P> { 2681 R visitClassSymbol(ClassSymbol s, P arg); 2682 R visitMethodSymbol(MethodSymbol s, P arg); 2683 R visitPackageSymbol(PackageSymbol s, P arg); 2684 R visitOperatorSymbol(OperatorSymbol s, P arg); 2685 R visitVarSymbol(VarSymbol s, P arg); 2686 R visitTypeSymbol(TypeSymbol s, P arg); 2687 R visitSymbol(Symbol s, P arg); 2688 } 2689 }