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