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