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