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