1 /* 2 * Copyright (c) 1999, 2013, 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.util.Set; 29 import java.util.concurrent.Callable; 30 31 import javax.lang.model.element.*; 32 import javax.tools.JavaFileObject; 33 34 import com.sun.tools.javac.code.Type.*; 35 import com.sun.tools.javac.comp.Attr; 36 import com.sun.tools.javac.comp.AttrContext; 37 import com.sun.tools.javac.comp.Env; 38 import com.sun.tools.javac.jvm.*; 39 import com.sun.tools.javac.model.*; 40 import com.sun.tools.javac.tree.JCTree; 41 import com.sun.tools.javac.util.*; 42 import com.sun.tools.javac.util.Name; 43 import static com.sun.tools.javac.code.Flags.*; 44 import static com.sun.tools.javac.code.Kinds.*; 45 import static com.sun.tools.javac.code.TypeTag.CLASS; 46 import static com.sun.tools.javac.code.TypeTag.FORALL; 47 import static com.sun.tools.javac.code.TypeTag.TYPEVAR; 48 49 /** Root class for Java symbols. It contains subclasses 50 * for specific sorts of symbols, such as variables, methods and operators, 51 * types, packages. Each subclass is represented as a static inner class 52 * inside Symbol. 53 * 54 * <p><b>This is NOT part of any supported API. 55 * If you write code that depends on this, you do so at your own risk. 56 * This code and its internal interfaces are subject to change or 57 * deletion without notice.</b> 58 */ 59 public abstract class Symbol implements Element { 60 // public Throwable debug = new Throwable(); 61 62 /** The kind of this symbol. 63 * @see Kinds 64 */ 65 public int kind; 66 67 /** The flags of this symbol. 68 */ 69 public long flags_field; 70 71 /** An accessor method for the flags of this symbol. 72 * Flags of class symbols should be accessed through the accessor 73 * method to make sure that the class symbol is loaded. 74 */ 75 public long flags() { return flags_field; } 76 77 /** The attributes of this symbol are contained in this 78 * Annotations. The Annotations instance is NOT immutable. 79 */ 80 public final Annotations annotations = new Annotations(this); 81 82 /** An accessor method for the attributes of this symbol. 83 * Attributes of class symbols should be accessed through the accessor 84 * method to make sure that the class symbol is loaded. 85 */ 86 public List<Attribute.Compound> getRawAttributes() { 87 return annotations.getDeclarationAttributes(); 88 } 89 90 /** An accessor method for the type attributes of this symbol. 91 * Attributes of class symbols should be accessed through the accessor 92 * method to make sure that the class symbol is loaded. 93 */ 94 public List<Attribute.TypeCompound> getRawTypeAttributes() { 95 return annotations.getTypeAttributes(); 96 } 97 98 /** Fetch a particular annotation from a symbol. */ 99 public Attribute.Compound attribute(Symbol anno) { 100 for (Attribute.Compound a : getRawAttributes()) { 101 if (a.type.tsym == anno) return a; 102 } 103 return null; 104 } 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 */ 120 public Completer completer; 121 122 /** A cache for the type erasure of this symbol. 123 */ 124 public Type erasure_field; 125 126 /** Construct a symbol with given kind, flags, name, type and owner. 127 */ 128 public Symbol(int kind, long flags, Name name, Type type, Symbol owner) { 129 this.kind = kind; 130 this.flags_field = flags; 131 this.type = type; 132 this.owner = owner; 133 this.completer = null; 134 this.erasure_field = null; 135 this.name = name; 136 } 137 138 /** Clone this symbol with new owner. 139 * Legal only for fields and methods. 140 */ 141 public Symbol clone(Symbol newOwner) { 142 throw new AssertionError(); 143 } 144 145 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 146 return v.visitSymbol(this, p); 147 } 148 149 /** The Java source which this symbol represents. 150 * A description of this symbol; overrides Object. 151 */ 152 public String toString() { 153 return name.toString(); 154 } 155 156 /** A Java source description of the location of this symbol; used for 157 * error reporting. 158 * 159 * @return null if the symbol is a package or a toplevel class defined in 160 * the default package; otherwise, the owner symbol is returned 161 */ 162 public Symbol location() { 163 if (owner.name == null || (owner.name.isEmpty() && 164 (owner.flags() & BLOCK) == 0 && owner.kind != PCK && owner.kind != TYP)) { 165 return null; 166 } 167 return owner; 168 } 169 170 public Symbol location(Type site, Types types) { 171 if (owner.name == null || owner.name.isEmpty()) { 172 return location(); 173 } 174 if (owner.type.hasTag(CLASS)) { 175 Type ownertype = types.asOuterSuper(site, owner); 176 if (ownertype != null) return ownertype.tsym; 177 } 178 return owner; 179 } 180 181 public Symbol baseSymbol() { 182 return this; 183 } 184 185 /** The symbol's erased type. 186 */ 187 public Type erasure(Types types) { 188 if (erasure_field == null) 189 erasure_field = types.erasure(type); 190 return erasure_field; 191 } 192 193 /** The external type of a symbol. This is the symbol's erased type 194 * except for constructors of inner classes which get the enclosing 195 * instance class added as first argument. 196 */ 197 public Type externalType(Types types) { 198 Type t = erasure(types); 199 if (name == name.table.names.init && owner.hasOuterInstance()) { 200 Type outerThisType = types.erasure(owner.type.getEnclosingType()); 201 return new MethodType(t.getParameterTypes().prepend(outerThisType), 202 t.getReturnType(), 203 t.getThrownTypes(), 204 t.tsym); 205 } else { 206 return t; 207 } 208 } 209 210 public boolean isStatic() { 211 return 212 (flags() & STATIC) != 0 || 213 (owner.flags() & INTERFACE) != 0 && kind != MTH; 214 } 215 216 public boolean isInterface() { 217 return (flags() & INTERFACE) != 0; 218 } 219 220 /** Is this symbol declared (directly or indirectly) local 221 * to a method or variable initializer? 222 * Also includes fields of inner classes which are in 223 * turn local to a method or variable initializer. 224 */ 225 public boolean isLocal() { 226 return 227 (owner.kind & (VAR | MTH)) != 0 || 228 (owner.kind == TYP && owner.isLocal()); 229 } 230 231 /** Has this symbol an empty name? This includes anonymous 232 * inner classses. 233 */ 234 public boolean isAnonymous() { 235 return name.isEmpty(); 236 } 237 238 /** Is this symbol a constructor? 239 */ 240 public boolean isConstructor() { 241 return name == name.table.names.init; 242 } 243 244 /** The fully qualified name of this symbol. 245 * This is the same as the symbol's name except for class symbols, 246 * which are handled separately. 247 */ 248 public Name getQualifiedName() { 249 return name; 250 } 251 252 /** The fully qualified name of this symbol after converting to flat 253 * representation. This is the same as the symbol's name except for 254 * class symbols, which are handled separately. 255 */ 256 public Name flatName() { 257 return getQualifiedName(); 258 } 259 260 /** If this is a class or package, its members, otherwise null. 261 */ 262 public Scope members() { 263 return null; 264 } 265 266 /** A class is an inner class if it it has an enclosing instance class. 267 */ 268 public boolean isInner() { 269 return type.getEnclosingType().hasTag(CLASS); 270 } 271 272 /** An inner class has an outer instance if it is not an interface 273 * it has an enclosing instance class which might be referenced from the class. 274 * Nested classes can see instance members of their enclosing class. 275 * Their constructors carry an additional this$n parameter, inserted 276 * implicitly by the compiler. 277 * 278 * @see #isInner 279 */ 280 public boolean hasOuterInstance() { 281 return 282 type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | NOOUTERTHIS)) == 0; 283 } 284 285 /** The closest enclosing class of this symbol's declaration. 286 */ 287 public ClassSymbol enclClass() { 288 Symbol c = this; 289 while (c != null && 290 ((c.kind & TYP) == 0 || !c.type.hasTag(CLASS))) { 291 c = c.owner; 292 } 293 return (ClassSymbol)c; 294 } 295 296 /** The outermost class which indirectly owns this symbol. 297 */ 298 public ClassSymbol outermostClass() { 299 Symbol sym = this; 300 Symbol prev = null; 301 while (sym.kind != PCK) { 302 prev = sym; 303 sym = sym.owner; 304 } 305 return (ClassSymbol) prev; 306 } 307 308 /** The package which indirectly owns this symbol. 309 */ 310 public PackageSymbol packge() { 311 Symbol sym = this; 312 while (sym.kind != PCK) { 313 sym = sym.owner; 314 } 315 return (PackageSymbol) sym; 316 } 317 318 /** Is this symbol a subclass of `base'? Only defined for ClassSymbols. 319 */ 320 public boolean isSubClass(Symbol base, Types types) { 321 throw new AssertionError("isSubClass " + this); 322 } 323 324 /** Fully check membership: hierarchy, protection, and hiding. 325 * Does not exclude methods not inherited due to overriding. 326 */ 327 public boolean isMemberOf(TypeSymbol clazz, Types types) { 328 return 329 owner == clazz || 330 clazz.isSubClass(owner, types) && 331 isInheritedIn(clazz, types) && 332 !hiddenIn((ClassSymbol)clazz, types); 333 } 334 335 /** Is this symbol the same as or enclosed by the given class? */ 336 public boolean isEnclosedBy(ClassSymbol clazz) { 337 for (Symbol sym = this; sym.kind != PCK; sym = sym.owner) 338 if (sym == clazz) return true; 339 return false; 340 } 341 342 /** Check for hiding. Note that this doesn't handle multiple 343 * (interface) inheritance. */ 344 private boolean hiddenIn(ClassSymbol clazz, Types types) { 345 if (kind == MTH && (flags() & STATIC) == 0) return false; 346 while (true) { 347 if (owner == clazz) return false; 348 Scope.Entry e = clazz.members().lookup(name); 349 while (e.scope != null) { 350 if (e.sym == this) return false; 351 if (e.sym.kind == kind && 352 (kind != MTH || 353 (e.sym.flags() & STATIC) != 0 && 354 types.isSubSignature(e.sym.type, type))) 355 return true; 356 e = e.next(); 357 } 358 Type superType = types.supertype(clazz.type); 359 if (!superType.hasTag(CLASS)) return false; 360 clazz = (ClassSymbol)superType.tsym; 361 } 362 } 363 364 /** Is this symbol inherited into a given class? 365 * PRE: If symbol's owner is a interface, 366 * it is already assumed that the interface is a superinterface 367 * of given class. 368 * @param clazz The class for which we want to establish membership. 369 * This must be a subclass of the member's owner. 370 */ 371 public boolean isInheritedIn(Symbol clazz, Types types) { 372 switch ((int)(flags_field & Flags.AccessFlags)) { 373 default: // error recovery 374 case PUBLIC: 375 return true; 376 case PRIVATE: 377 return this.owner == clazz; 378 case PROTECTED: 379 // we model interfaces as extending Object 380 return (clazz.flags() & INTERFACE) == 0; 381 case 0: 382 PackageSymbol thisPackage = this.packge(); 383 for (Symbol sup = clazz; 384 sup != null && sup != this.owner; 385 sup = types.supertype(sup.type).tsym) { 386 while (sup.type.hasTag(TYPEVAR)) 387 sup = sup.type.getUpperBound().tsym; 388 if (sup.type.isErroneous()) 389 return true; // error recovery 390 if ((sup.flags() & COMPOUND) != 0) 391 continue; 392 if (sup.packge() != thisPackage) 393 return false; 394 } 395 return (clazz.flags() & INTERFACE) == 0; 396 } 397 } 398 399 /** The (variable or method) symbol seen as a member of given 400 * class type`site' (this might change the symbol's type). 401 * This is used exclusively for producing diagnostics. 402 */ 403 public Symbol asMemberOf(Type site, Types types) { 404 throw new AssertionError(); 405 } 406 407 /** Does this method symbol override `other' symbol, when both are seen as 408 * members of class `origin'? It is assumed that _other is a member 409 * of origin. 410 * 411 * It is assumed that both symbols have the same name. The static 412 * modifier is ignored for this test. 413 * 414 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 415 */ 416 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { 417 return false; 418 } 419 420 /** Complete the elaboration of this symbol's definition. 421 */ 422 public void complete() throws CompletionFailure { 423 if (completer != null) { 424 Completer c = completer; 425 completer = null; 426 c.complete(this); 427 } 428 } 429 430 /** True if the symbol represents an entity that exists. 431 */ 432 public boolean exists() { 433 return true; 434 } 435 436 public Type asType() { 437 return type; 438 } 439 440 public Symbol getEnclosingElement() { 441 return owner; 442 } 443 444 public ElementKind getKind() { 445 return ElementKind.OTHER; // most unkind 446 } 447 448 public Set<Modifier> getModifiers() { 449 long flags = flags(); 450 return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags); 451 } 452 453 public Name getSimpleName() { 454 return name; 455 } 456 457 /** 458 * This is the implementation for {@code 459 * javax.lang.model.element.Element.getAnnotationMirrors()}. 460 */ 461 public final List<? extends AnnotationMirror> getAnnotationMirrors() { 462 return getRawAttributes(); 463 } 464 465 /** 466 * TODO: Should there be a {@code 467 * javax.lang.model.element.Element.getTypeAnnotationMirrors()}. 468 */ 469 public final List<Attribute.TypeCompound> getTypeAnnotationMirrors() { 470 return getRawTypeAttributes(); 471 } 472 473 /** 474 * @deprecated this method should never be used by javac internally. 475 */ 476 @Deprecated 477 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) { 478 return JavacElements.getAnnotation(this, annoType); 479 } 480 481 // This method is part of the javax.lang.model API, do not use this in javac code. 482 public <A extends java.lang.annotation.Annotation> A[] getAnnotations(Class<A> annoType) { 483 return JavacElements.getAnnotations(this, annoType); 484 } 485 486 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList 487 public java.util.List<Symbol> getEnclosedElements() { 488 return List.nil(); 489 } 490 491 public List<TypeSymbol> getTypeParameters() { 492 ListBuffer<TypeSymbol> l = ListBuffer.lb(); 493 for (Type t : type.getTypeArguments()) { 494 l.append(t.tsym); 495 } 496 return l.toList(); 497 } 498 499 public static class DelegatedSymbol extends Symbol { 500 protected Symbol other; 501 public DelegatedSymbol(Symbol other) { 502 super(other.kind, other.flags_field, other.name, other.type, other.owner); 503 this.other = other; 504 } 505 public String toString() { return other.toString(); } 506 public Symbol location() { return other.location(); } 507 public Symbol location(Type site, Types types) { return other.location(site, types); } 508 public Symbol baseSymbol() { return other; } 509 public Type erasure(Types types) { return other.erasure(types); } 510 public Type externalType(Types types) { return other.externalType(types); } 511 public boolean isLocal() { return other.isLocal(); } 512 public boolean isConstructor() { return other.isConstructor(); } 513 public Name getQualifiedName() { return other.getQualifiedName(); } 514 public Name flatName() { return other.flatName(); } 515 public Scope members() { return other.members(); } 516 public boolean isInner() { return other.isInner(); } 517 public boolean hasOuterInstance() { return other.hasOuterInstance(); } 518 public ClassSymbol enclClass() { return other.enclClass(); } 519 public ClassSymbol outermostClass() { return other.outermostClass(); } 520 public PackageSymbol packge() { return other.packge(); } 521 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); } 522 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); } 523 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); } 524 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); } 525 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); } 526 public void complete() throws CompletionFailure { other.complete(); } 527 528 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 529 return other.accept(v, p); 530 } 531 532 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 533 return v.visitSymbol(other, p); 534 } 535 } 536 537 /** A class for type symbols. Type variables are represented by instances 538 * of this class, classes and packages by instances of subclasses. 539 */ 540 public static class TypeSymbol 541 extends Symbol implements TypeParameterElement { 542 // Implements TypeParameterElement because type parameters don't 543 // have their own TypeSymbol subclass. 544 // TODO: type parameters should have their own TypeSymbol subclass 545 546 public TypeSymbol(long flags, Name name, Type type, Symbol owner) { 547 super(TYP, flags, name, type, owner); 548 } 549 550 /** form a fully qualified name from a name and an owner 551 */ 552 static public Name formFullName(Name name, Symbol owner) { 553 if (owner == null) return name; 554 if (((owner.kind != ERR)) && 555 ((owner.kind & (VAR | MTH)) != 0 556 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR)) 557 )) return name; 558 Name prefix = owner.getQualifiedName(); 559 if (prefix == null || prefix == prefix.table.names.empty) 560 return name; 561 else return prefix.append('.', name); 562 } 563 564 /** form a fully qualified name from a name and an owner, after 565 * converting to flat representation 566 */ 567 static public Name formFlatName(Name name, Symbol owner) { 568 if (owner == null || 569 (owner.kind & (VAR | MTH)) != 0 570 || (owner.kind == TYP && owner.type.hasTag(TYPEVAR)) 571 ) return name; 572 char sep = owner.kind == TYP ? '$' : '.'; 573 Name prefix = owner.flatName(); 574 if (prefix == null || prefix == prefix.table.names.empty) 575 return name; 576 else return prefix.append(sep, name); 577 } 578 579 /** 580 * A total ordering between type symbols that refines the 581 * class inheritance graph. 582 * 583 * Typevariables always precede other kinds of symbols. 584 */ 585 public final boolean precedes(TypeSymbol that, Types types) { 586 if (this == that) 587 return false; 588 if (this.type.tag == that.type.tag) { 589 if (this.type.hasTag(CLASS)) { 590 return 591 types.rank(that.type) < types.rank(this.type) || 592 types.rank(that.type) == types.rank(this.type) && 593 that.getQualifiedName().compareTo(this.getQualifiedName()) < 0; 594 } else if (this.type.hasTag(TYPEVAR)) { 595 return types.isSubtype(this.type, that.type); 596 } 597 } 598 return this.type.hasTag(TYPEVAR); 599 } 600 601 // For type params; overridden in subclasses. 602 public ElementKind getKind() { 603 return ElementKind.TYPE_PARAMETER; 604 } 605 606 public java.util.List<Symbol> getEnclosedElements() { 607 List<Symbol> list = List.nil(); 608 if (kind == TYP && type.hasTag(TYPEVAR)) { 609 return list; 610 } 611 for (Scope.Entry e = members().elems; e != null; e = e.sibling) { 612 if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this) 613 list = list.prepend(e.sym); 614 } 615 return list; 616 } 617 618 // For type params. 619 // Perhaps not needed if getEnclosingElement can be spec'ed 620 // to do the same thing. 621 // TODO: getGenericElement() might not be needed 622 public Symbol getGenericElement() { 623 return owner; 624 } 625 626 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 627 Assert.check(type.hasTag(TYPEVAR)); // else override will be invoked 628 return v.visitTypeParameter(this, p); 629 } 630 631 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 632 return v.visitTypeSymbol(this, p); 633 } 634 635 public List<Type> getBounds() { 636 TypeVar t = (TypeVar)type; 637 Type bound = t.getUpperBound(); 638 if (!bound.isCompound()) 639 return List.of(bound); 640 ClassType ct = (ClassType)bound; 641 if (!ct.tsym.erasure_field.isInterface()) { 642 return ct.interfaces_field.prepend(ct.supertype_field); 643 } else { 644 // No superclass was given in bounds. 645 // In this case, supertype is Object, erasure is first interface. 646 return ct.interfaces_field; 647 } 648 } 649 } 650 651 /** A class for package symbols 652 */ 653 public static class PackageSymbol extends TypeSymbol 654 implements PackageElement { 655 656 public Scope members_field; 657 public Name fullname; 658 public ClassSymbol package_info; // see bug 6443073 659 660 public PackageSymbol(Name name, Type type, Symbol owner) { 661 super(0, name, type, owner); 662 this.kind = PCK; 663 this.members_field = null; 664 this.fullname = formFullName(name, owner); 665 } 666 667 public PackageSymbol(Name name, Symbol owner) { 668 this(name, null, owner); 669 this.type = new PackageType(this); 670 } 671 672 public String toString() { 673 return fullname.toString(); 674 } 675 676 public Name getQualifiedName() { 677 return fullname; 678 } 679 680 public boolean isUnnamed() { 681 return name.isEmpty() && owner != null; 682 } 683 684 public Scope members() { 685 if (completer != null) complete(); 686 return members_field; 687 } 688 689 public long flags() { 690 if (completer != null) complete(); 691 return flags_field; 692 } 693 694 @Override 695 public List<Attribute.Compound> getRawAttributes() { 696 if (completer != null) complete(); 697 if (package_info != null && package_info.completer != null) { 698 package_info.complete(); 699 mergeAttributes(); 700 } 701 return super.getRawAttributes(); 702 } 703 704 private void mergeAttributes() { 705 if (annotations.isEmpty() && 706 !package_info.annotations.isEmpty()) { 707 annotations.setAttributes(package_info.annotations); 708 } 709 } 710 711 /** A package "exists" if a type or package that exists has 712 * been seen within it. 713 */ 714 public boolean exists() { 715 return (flags_field & EXISTS) != 0; 716 } 717 718 public ElementKind getKind() { 719 return ElementKind.PACKAGE; 720 } 721 722 public Symbol getEnclosingElement() { 723 return null; 724 } 725 726 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 727 return v.visitPackage(this, p); 728 } 729 730 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 731 return v.visitPackageSymbol(this, p); 732 } 733 } 734 735 /** A class for class symbols 736 */ 737 public static class ClassSymbol extends TypeSymbol implements TypeElement { 738 739 /** a scope for all class members; variables, methods and inner classes 740 * type parameters are not part of this scope 741 */ 742 public Scope members_field; 743 744 /** the fully qualified name of the class, i.e. pck.outer.inner. 745 * null for anonymous classes 746 */ 747 public Name fullname; 748 749 /** the fully qualified name of the class after converting to flat 750 * representation, i.e. pck.outer$inner, 751 * set externally for local and anonymous classes 752 */ 753 public Name flatname; 754 755 /** the sourcefile where the class came from 756 */ 757 public JavaFileObject sourcefile; 758 759 /** the classfile from where to load this class 760 * this will have extension .class or .java 761 */ 762 public JavaFileObject classfile; 763 764 /** the list of translated local classes (used for generating 765 * InnerClasses attribute) 766 */ 767 public List<ClassSymbol> trans_local; 768 769 /** the constant pool of the class 770 */ 771 public Pool pool; 772 773 public ClassSymbol(long flags, Name name, Type type, Symbol owner) { 774 super(flags, name, type, owner); 775 this.members_field = null; 776 this.fullname = formFullName(name, owner); 777 this.flatname = formFlatName(name, owner); 778 this.sourcefile = null; 779 this.classfile = null; 780 this.pool = null; 781 } 782 783 public ClassSymbol(long flags, Name name, Symbol owner) { 784 this( 785 flags, 786 name, 787 new ClassType(Type.noType, null, null), 788 owner); 789 this.type.tsym = this; 790 } 791 792 /** The Java source which this symbol represents. 793 */ 794 public String toString() { 795 return className(); 796 } 797 798 public long flags() { 799 if (completer != null) complete(); 800 return flags_field; 801 } 802 803 public Scope members() { 804 if (completer != null) complete(); 805 return members_field; 806 } 807 808 @Override 809 public List<Attribute.Compound> getRawAttributes() { 810 if (completer != null) complete(); 811 return super.getRawAttributes(); 812 } 813 814 @Override 815 public List<Attribute.TypeCompound> getRawTypeAttributes() { 816 if (completer != null) complete(); 817 return super.getRawTypeAttributes(); 818 } 819 820 public Type erasure(Types types) { 821 if (erasure_field == null) 822 erasure_field = new ClassType(types.erasure(type.getEnclosingType()), 823 List.<Type>nil(), this); 824 return erasure_field; 825 } 826 827 public String className() { 828 if (name.isEmpty()) 829 return 830 Log.getLocalizedString("anonymous.class", flatname); 831 else 832 return fullname.toString(); 833 } 834 835 public Name getQualifiedName() { 836 return fullname; 837 } 838 839 public Name flatName() { 840 return flatname; 841 } 842 843 public boolean isSubClass(Symbol base, Types types) { 844 if (this == base) { 845 return true; 846 } else if ((base.flags() & INTERFACE) != 0) { 847 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t)) 848 for (List<Type> is = types.interfaces(t); 849 is.nonEmpty(); 850 is = is.tail) 851 if (is.head.tsym.isSubClass(base, types)) return true; 852 } else { 853 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t)) 854 if (t.tsym == base) return true; 855 } 856 return false; 857 } 858 859 /** Complete the elaboration of this symbol's definition. 860 */ 861 public void complete() throws CompletionFailure { 862 try { 863 super.complete(); 864 } catch (CompletionFailure ex) { 865 // quiet error recovery 866 flags_field |= (PUBLIC|STATIC); 867 this.type = new ErrorType(this, Type.noType); 868 throw ex; 869 } 870 } 871 872 public List<Type> getInterfaces() { 873 complete(); 874 if (type instanceof ClassType) { 875 ClassType t = (ClassType)type; 876 if (t.interfaces_field == null) // FIXME: shouldn't be null 877 t.interfaces_field = List.nil(); 878 if (t.all_interfaces_field != null) 879 return Type.getModelTypes(t.all_interfaces_field); 880 return t.interfaces_field; 881 } else { 882 return List.nil(); 883 } 884 } 885 886 public Type getSuperclass() { 887 complete(); 888 if (type instanceof ClassType) { 889 ClassType t = (ClassType)type; 890 if (t.supertype_field == null) // FIXME: shouldn't be null 891 t.supertype_field = Type.noType; 892 // An interface has no superclass; its supertype is Object. 893 return t.isInterface() 894 ? Type.noType 895 : t.supertype_field.getModelType(); 896 } else { 897 return Type.noType; 898 } 899 } 900 901 public ElementKind getKind() { 902 long flags = flags(); 903 if ((flags & ANNOTATION) != 0) 904 return ElementKind.ANNOTATION_TYPE; 905 else if ((flags & INTERFACE) != 0) 906 return ElementKind.INTERFACE; 907 else if ((flags & ENUM) != 0) 908 return ElementKind.ENUM; 909 else 910 return ElementKind.CLASS; 911 } 912 913 public NestingKind getNestingKind() { 914 complete(); 915 if (owner.kind == PCK) 916 return NestingKind.TOP_LEVEL; 917 else if (name.isEmpty()) 918 return NestingKind.ANONYMOUS; 919 else if (owner.kind == MTH) 920 return NestingKind.LOCAL; 921 else 922 return NestingKind.MEMBER; 923 } 924 925 /** 926 * @deprecated this method should never be used by javac internally. 927 */ 928 @Override @Deprecated 929 public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A> annoType) { 930 return JavacElements.getAnnotation(this, annoType); 931 } 932 933 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 934 return v.visitType(this, p); 935 } 936 937 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 938 return v.visitClassSymbol(this, p); 939 } 940 } 941 942 943 /** A class for variable symbols 944 */ 945 public static class VarSymbol extends Symbol implements VariableElement { 946 947 /** The variable's declaration position. 948 */ 949 public int pos = Position.NOPOS; 950 951 /** The variable's address. Used for different purposes during 952 * flow analysis, translation and code generation. 953 * Flow analysis: 954 * If this is a blank final or local variable, its sequence number. 955 * Translation: 956 * If this is a private field, its access number. 957 * Code generation: 958 * If this is a local variable, its logical slot number. 959 */ 960 public int adr = -1; 961 962 /** Construct a variable symbol, given its flags, name, type and owner. 963 */ 964 public VarSymbol(long flags, Name name, Type type, Symbol owner) { 965 super(VAR, flags, name, type, owner); 966 } 967 968 /** Clone this symbol with new owner. 969 */ 970 public VarSymbol clone(Symbol newOwner) { 971 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) { 972 @Override 973 public Symbol baseSymbol() { 974 return VarSymbol.this; 975 } 976 }; 977 v.pos = pos; 978 v.adr = adr; 979 v.data = data; 980 // System.out.println("clone " + v + " in " + newOwner);//DEBUG 981 return v; 982 } 983 984 public String toString() { 985 return name.toString(); 986 } 987 988 public Symbol asMemberOf(Type site, Types types) { 989 return new VarSymbol(flags_field, name, types.memberType(site, this), owner); 990 } 991 992 public ElementKind getKind() { 993 long flags = flags(); 994 if ((flags & PARAMETER) != 0) { 995 if (isExceptionParameter()) 996 return ElementKind.EXCEPTION_PARAMETER; 997 else 998 return ElementKind.PARAMETER; 999 } else if ((flags & ENUM) != 0) { 1000 return ElementKind.ENUM_CONSTANT; 1001 } else if (owner.kind == TYP || owner.kind == ERR) { 1002 return ElementKind.FIELD; 1003 } else if (isResourceVariable()) { 1004 return ElementKind.RESOURCE_VARIABLE; 1005 } else { 1006 return ElementKind.LOCAL_VARIABLE; 1007 } 1008 } 1009 1010 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1011 return v.visitVariable(this, p); 1012 } 1013 1014 public Object getConstantValue() { // Mirror API 1015 return Constants.decode(getConstValue(), type); 1016 } 1017 1018 public void setLazyConstValue(final Env<AttrContext> env, 1019 final Attr attr, 1020 final JCTree.JCExpression initializer) 1021 { 1022 setData(new Callable<Object>() { 1023 public Object call() { 1024 return attr.attribLazyConstantValue(env, initializer, type); 1025 } 1026 }); 1027 } 1028 1029 /** 1030 * The variable's constant value, if this is a constant. 1031 * Before the constant value is evaluated, it points to an 1032 * initalizer environment. If this is not a constant, it can 1033 * be used for other stuff. 1034 */ 1035 private Object data; 1036 1037 public boolean isExceptionParameter() { 1038 return data == ElementKind.EXCEPTION_PARAMETER; 1039 } 1040 1041 public boolean isResourceVariable() { 1042 return data == ElementKind.RESOURCE_VARIABLE; 1043 } 1044 1045 public Object getConstValue() { 1046 // TODO: Consider if getConstValue and getConstantValue can be collapsed 1047 if (data == ElementKind.EXCEPTION_PARAMETER || 1048 data == ElementKind.RESOURCE_VARIABLE) { 1049 return null; 1050 } else if (data instanceof Callable<?>) { 1051 // In this case, this is a final variable, with an as 1052 // yet unevaluated initializer. 1053 Callable<?> eval = (Callable<?>)data; 1054 data = null; // to make sure we don't evaluate this twice. 1055 try { 1056 data = eval.call(); 1057 } catch (Exception ex) { 1058 throw new AssertionError(ex); 1059 } 1060 } 1061 return data; 1062 } 1063 1064 public void setData(Object data) { 1065 Assert.check(!(data instanceof Env<?>), this); 1066 this.data = data; 1067 } 1068 1069 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1070 return v.visitVarSymbol(this, p); 1071 } 1072 } 1073 1074 /** A class for method symbols. 1075 */ 1076 public static class MethodSymbol extends Symbol implements ExecutableElement { 1077 1078 /** The code of the method. */ 1079 public Code code = null; 1080 1081 /** The parameters of the method. */ 1082 public List<VarSymbol> params = null; 1083 1084 /** The names of the parameters */ 1085 public List<Name> savedParameterNames; 1086 1087 /** For an attribute field accessor, its default value if any. 1088 * The value is null if none appeared in the method 1089 * declaration. 1090 */ 1091 public Attribute defaultValue = null; 1092 1093 /** Construct a method symbol, given its flags, name, type and owner. 1094 */ 1095 public MethodSymbol(long flags, Name name, Type type, Symbol owner) { 1096 super(MTH, flags, name, type, owner); 1097 if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name); 1098 } 1099 1100 /** Clone this symbol with new owner. 1101 */ 1102 public MethodSymbol clone(Symbol newOwner) { 1103 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) { 1104 @Override 1105 public Symbol baseSymbol() { 1106 return MethodSymbol.this; 1107 } 1108 }; 1109 m.code = code; 1110 return m; 1111 } 1112 1113 /** The Java source which this symbol represents. 1114 */ 1115 public String toString() { 1116 if ((flags() & BLOCK) != 0) { 1117 return owner.name.toString(); 1118 } else { 1119 String s = (name == name.table.names.init) 1120 ? owner.name.toString() 1121 : name.toString(); 1122 if (type != null) { 1123 if (type.hasTag(FORALL)) 1124 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s; 1125 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")"; 1126 } 1127 return s; 1128 } 1129 } 1130 1131 public boolean isDynamic() { 1132 return false; 1133 } 1134 1135 /** find a symbol that this (proxy method) symbol implements. 1136 * @param c The class whose members are searched for 1137 * implementations 1138 */ 1139 public Symbol implemented(TypeSymbol c, Types types) { 1140 Symbol impl = null; 1141 for (List<Type> is = types.interfaces(c.type); 1142 impl == null && is.nonEmpty(); 1143 is = is.tail) { 1144 TypeSymbol i = is.head.tsym; 1145 impl = implementedIn(i, types); 1146 if (impl == null) 1147 impl = implemented(i, types); 1148 } 1149 return impl; 1150 } 1151 1152 public Symbol implementedIn(TypeSymbol c, Types types) { 1153 Symbol impl = null; 1154 for (Scope.Entry e = c.members().lookup(name); 1155 impl == null && e.scope != null; 1156 e = e.next()) { 1157 if (this.overrides(e.sym, (TypeSymbol)owner, types, true) && 1158 // FIXME: I suspect the following requires a 1159 // subst() for a parametric return type. 1160 types.isSameType(type.getReturnType(), 1161 types.memberType(owner.type, e.sym).getReturnType())) { 1162 impl = e.sym; 1163 } 1164 } 1165 return impl; 1166 } 1167 1168 /** Will the erasure of this method be considered by the VM to 1169 * override the erasure of the other when seen from class `origin'? 1170 */ 1171 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) { 1172 if (isConstructor() || _other.kind != MTH) return false; 1173 1174 if (this == _other) return true; 1175 MethodSymbol other = (MethodSymbol)_other; 1176 1177 // check for a direct implementation 1178 if (other.isOverridableIn((TypeSymbol)owner) && 1179 types.asSuper(owner.type, other.owner) != null && 1180 types.isSameType(erasure(types), other.erasure(types))) 1181 return true; 1182 1183 // check for an inherited implementation 1184 return 1185 (flags() & ABSTRACT) == 0 && 1186 other.isOverridableIn(origin) && 1187 this.isMemberOf(origin, types) && 1188 types.isSameType(erasure(types), other.erasure(types)); 1189 } 1190 1191 /** The implementation of this (abstract) symbol in class origin, 1192 * from the VM's point of view, null if method does not have an 1193 * implementation in class. 1194 * @param origin The class of which the implementation is a member. 1195 */ 1196 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) { 1197 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) { 1198 for (Scope.Entry e = c.members().lookup(name); 1199 e.scope != null; 1200 e = e.next()) { 1201 if (e.sym.kind == MTH && 1202 ((MethodSymbol)e.sym).binaryOverrides(this, origin, types)) 1203 return (MethodSymbol)e.sym; 1204 } 1205 } 1206 return null; 1207 } 1208 1209 /** Does this symbol override `other' symbol, when both are seen as 1210 * members of class `origin'? It is assumed that _other is a member 1211 * of origin. 1212 * 1213 * It is assumed that both symbols have the same name. The static 1214 * modifier is ignored for this test. 1215 * 1216 * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 1217 */ 1218 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { 1219 if (isConstructor() || _other.kind != MTH) return false; 1220 1221 if (this == _other) return true; 1222 MethodSymbol other = (MethodSymbol)_other; 1223 1224 // check for a direct implementation 1225 if (other.isOverridableIn((TypeSymbol)owner) && 1226 types.asSuper(owner.type, other.owner) != null) { 1227 Type mt = types.memberType(owner.type, this); 1228 Type ot = types.memberType(owner.type, other); 1229 if (types.isSubSignature(mt, ot)) { 1230 if (!checkResult) 1231 return true; 1232 if (types.returnTypeSubstitutable(mt, ot)) 1233 return true; 1234 } 1235 } 1236 1237 // check for an inherited implementation 1238 if ((flags() & ABSTRACT) != 0 || 1239 ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) || 1240 !other.isOverridableIn(origin) || 1241 !this.isMemberOf(origin, types)) 1242 return false; 1243 1244 // assert types.asSuper(origin.type, other.owner) != null; 1245 Type mt = types.memberType(origin.type, this); 1246 Type ot = types.memberType(origin.type, other); 1247 return 1248 types.isSubSignature(mt, ot) && 1249 (!checkResult || types.resultSubtype(mt, ot, types.noWarnings)); 1250 } 1251 1252 private boolean isOverridableIn(TypeSymbol origin) { 1253 // JLS 8.4.6.1 1254 switch ((int)(flags_field & Flags.AccessFlags)) { 1255 case Flags.PRIVATE: 1256 return false; 1257 case Flags.PUBLIC: 1258 return !this.owner.isInterface() || 1259 (flags_field & STATIC) == 0; 1260 case Flags.PROTECTED: 1261 return (origin.flags() & INTERFACE) == 0; 1262 case 0: 1263 // for package private: can only override in the same 1264 // package 1265 return 1266 this.packge() == origin.packge() && 1267 (origin.flags() & INTERFACE) == 0; 1268 default: 1269 return false; 1270 } 1271 } 1272 1273 @Override 1274 public boolean isInheritedIn(Symbol clazz, Types types) { 1275 switch ((int)(flags_field & Flags.AccessFlags)) { 1276 case PUBLIC: 1277 return !this.owner.isInterface() || 1278 clazz == owner || 1279 (flags_field & STATIC) == 0; 1280 default: 1281 return super.isInheritedIn(clazz, types); 1282 } 1283 } 1284 1285 /** The implementation of this (abstract) symbol in class origin; 1286 * null if none exists. Synthetic methods are not considered 1287 * as possible implementations. 1288 */ 1289 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) { 1290 return implementation(origin, types, checkResult, implementation_filter); 1291 } 1292 // where 1293 private static final Filter<Symbol> implementation_filter = new Filter<Symbol>() { 1294 public boolean accepts(Symbol s) { 1295 return s.kind == Kinds.MTH && 1296 (s.flags() & SYNTHETIC) == 0; 1297 } 1298 }; 1299 1300 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) { 1301 MethodSymbol res = types.implementation(this, origin, checkResult, implFilter); 1302 if (res != null) 1303 return res; 1304 // if origin is derived from a raw type, we might have missed 1305 // an implementation because we do not know enough about instantiations. 1306 // in this case continue with the supertype as origin. 1307 if (types.isDerivedRaw(origin.type) && !origin.isInterface()) 1308 return implementation(types.supertype(origin.type).tsym, types, checkResult); 1309 else 1310 return null; 1311 } 1312 1313 public List<VarSymbol> params() { 1314 owner.complete(); 1315 if (params == null) { 1316 // If ClassReader.saveParameterNames has been set true, then 1317 // savedParameterNames will be set to a list of names that 1318 // matches the types in type.getParameterTypes(). If any names 1319 // were not found in the class file, those names in the list will 1320 // be set to the empty name. 1321 // If ClassReader.saveParameterNames has been set false, then 1322 // savedParameterNames will be null. 1323 List<Name> paramNames = savedParameterNames; 1324 savedParameterNames = null; 1325 // discard the provided names if the list of names is the wrong size. 1326 if (paramNames == null || paramNames.size() != type.getParameterTypes().size()) { 1327 paramNames = List.nil(); 1328 } 1329 ListBuffer<VarSymbol> buf = new ListBuffer<VarSymbol>(); 1330 List<Name> remaining = paramNames; 1331 // assert: remaining and paramNames are both empty or both 1332 // have same cardinality as type.getParameterTypes() 1333 int i = 0; 1334 for (Type t : type.getParameterTypes()) { 1335 Name paramName; 1336 if (remaining.isEmpty()) { 1337 // no names for any parameters available 1338 paramName = createArgName(i, paramNames); 1339 } else { 1340 paramName = remaining.head; 1341 remaining = remaining.tail; 1342 if (paramName.isEmpty()) { 1343 // no name for this specific parameter 1344 paramName = createArgName(i, paramNames); 1345 } 1346 } 1347 buf.append(new VarSymbol(PARAMETER, paramName, t, this)); 1348 i++; 1349 } 1350 params = buf.toList(); 1351 } 1352 return params; 1353 } 1354 1355 // Create a name for the argument at position 'index' that is not in 1356 // the exclude list. In normal use, either no names will have been 1357 // provided, in which case the exclude list is empty, or all the names 1358 // will have been provided, in which case this method will not be called. 1359 private Name createArgName(int index, List<Name> exclude) { 1360 String prefix = "arg"; 1361 while (true) { 1362 Name argName = name.table.fromString(prefix + index); 1363 if (!exclude.contains(argName)) 1364 return argName; 1365 prefix += "$"; 1366 } 1367 } 1368 1369 public Symbol asMemberOf(Type site, Types types) { 1370 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner); 1371 } 1372 1373 public ElementKind getKind() { 1374 if (name == name.table.names.init) 1375 return ElementKind.CONSTRUCTOR; 1376 else if (name == name.table.names.clinit) 1377 return ElementKind.STATIC_INIT; 1378 else if ((flags() & BLOCK) != 0) 1379 return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT; 1380 else 1381 return ElementKind.METHOD; 1382 } 1383 1384 public boolean isStaticOrInstanceInit() { 1385 return getKind() == ElementKind.STATIC_INIT || 1386 getKind() == ElementKind.INSTANCE_INIT; 1387 } 1388 1389 /** 1390 * A polymorphic signature method (JLS SE 7, 8.4.1) is a method that 1391 * (i) is declared in the java.lang.invoke.MethodHandle class, (ii) takes 1392 * a single variable arity parameter (iii) whose declared type is Object[], 1393 * (iv) has a return type of Object and (v) is native. 1394 */ 1395 public boolean isSignaturePolymorphic(Types types) { 1396 List<Type> argtypes = type.getParameterTypes(); 1397 Type firstElemType = argtypes.nonEmpty() ? 1398 types.elemtype(argtypes.head) : 1399 null; 1400 return owner == types.syms.methodHandleType.tsym && 1401 argtypes.length() == 1 && 1402 firstElemType != null && 1403 types.isSameType(firstElemType, types.syms.objectType) && 1404 types.isSameType(type.getReturnType(), types.syms.objectType) && 1405 (flags() & NATIVE) != 0; 1406 } 1407 1408 public Attribute getDefaultValue() { 1409 return defaultValue; 1410 } 1411 1412 public List<VarSymbol> getParameters() { 1413 return params(); 1414 } 1415 1416 public boolean isVarArgs() { 1417 return (flags() & VARARGS) != 0; 1418 } 1419 1420 public boolean isDefault() { 1421 return (flags() & DEFAULT) != 0; 1422 } 1423 1424 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 1425 return v.visitExecutable(this, p); 1426 } 1427 1428 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1429 return v.visitMethodSymbol(this, p); 1430 } 1431 1432 public Type getReturnType() { 1433 return asType().getReturnType(); 1434 } 1435 1436 public List<Type> getThrownTypes() { 1437 return asType().getThrownTypes(); 1438 } 1439 } 1440 1441 /** A class for invokedynamic method calls. 1442 */ 1443 public static class DynamicMethodSymbol extends MethodSymbol { 1444 1445 public Object[] staticArgs; 1446 public Symbol bsm; 1447 public int bsmKind; 1448 1449 public DynamicMethodSymbol(Name name, Symbol owner, int bsmKind, MethodSymbol bsm, Type type, Object[] staticArgs) { 1450 super(0, name, type, owner); 1451 this.bsm = bsm; 1452 this.bsmKind = bsmKind; 1453 this.staticArgs = staticArgs; 1454 } 1455 1456 @Override 1457 public boolean isDynamic() { 1458 return true; 1459 } 1460 } 1461 1462 /** A class for predefined operators. 1463 */ 1464 public static class OperatorSymbol extends MethodSymbol { 1465 1466 public int opcode; 1467 1468 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) { 1469 super(PUBLIC | STATIC, name, type, owner); 1470 this.opcode = opcode; 1471 } 1472 1473 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) { 1474 return v.visitOperatorSymbol(this, p); 1475 } 1476 } 1477 1478 /** Symbol completer interface. 1479 */ 1480 public static interface Completer { 1481 void complete(Symbol sym) throws CompletionFailure; 1482 } 1483 1484 public static class CompletionFailure extends RuntimeException { 1485 private static final long serialVersionUID = 0; 1486 public Symbol sym; 1487 1488 /** A diagnostic object describing the failure 1489 */ 1490 public JCDiagnostic diag; 1491 1492 /** A localized string describing the failure. 1493 * @deprecated Use {@code getDetail()} or {@code getMessage()} 1494 */ 1495 @Deprecated 1496 public String errmsg; 1497 1498 public CompletionFailure(Symbol sym, String errmsg) { 1499 this.sym = sym; 1500 this.errmsg = errmsg; 1501 // this.printStackTrace();//DEBUG 1502 } 1503 1504 public CompletionFailure(Symbol sym, JCDiagnostic diag) { 1505 this.sym = sym; 1506 this.diag = diag; 1507 // this.printStackTrace();//DEBUG 1508 } 1509 1510 public JCDiagnostic getDiagnostic() { 1511 return diag; 1512 } 1513 1514 @Override 1515 public String getMessage() { 1516 if (diag != null) 1517 return diag.getMessage(null); 1518 else 1519 return errmsg; 1520 } 1521 1522 public Object getDetailValue() { 1523 return (diag != null ? diag : errmsg); 1524 } 1525 1526 @Override 1527 public CompletionFailure initCause(Throwable cause) { 1528 super.initCause(cause); 1529 return this; 1530 } 1531 1532 } 1533 1534 /** 1535 * A visitor for symbols. A visitor is used to implement operations 1536 * (or relations) on symbols. Most common operations on types are 1537 * binary relations and this interface is designed for binary 1538 * relations, that is, operations on the form 1539 * Symbol × P → R. 1540 * <!-- In plain text: Type x P -> R --> 1541 * 1542 * @param <R> the return type of the operation implemented by this 1543 * visitor; use Void if no return type is needed. 1544 * @param <P> the type of the second argument (the first being the 1545 * symbol itself) of the operation implemented by this visitor; use 1546 * Void if a second argument is not needed. 1547 */ 1548 public interface Visitor<R,P> { 1549 R visitClassSymbol(ClassSymbol s, P arg); 1550 R visitMethodSymbol(MethodSymbol s, P arg); 1551 R visitPackageSymbol(PackageSymbol s, P arg); 1552 R visitOperatorSymbol(OperatorSymbol s, P arg); 1553 R visitVarSymbol(VarSymbol s, P arg); 1554 R visitTypeSymbol(TypeSymbol s, P arg); 1555 R visitSymbol(Symbol s, P arg); 1556 } 1557 }