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