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