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