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