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