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