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