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