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