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