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