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