1 /*
   2  * Copyright (c) 1999, 2021, 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.util.ArrayDeque;
  30 import java.util.Collections;
  31 import java.util.EnumMap;
  32 import java.util.Map;
  33 import java.util.function.Predicate;
  34 
  35 import javax.lang.model.type.*;
  36 
  37 import com.sun.tools.javac.code.Symbol.*;
  38 import com.sun.tools.javac.code.Type.ClassType.Flavor;
  39 import com.sun.tools.javac.code.TypeMetadata.Entry;
  40 import com.sun.tools.javac.code.Types.TypeMapping;
  41 import com.sun.tools.javac.code.Types.UniqueType;
  42 import com.sun.tools.javac.comp.Infer.IncorporationAction;
  43 import com.sun.tools.javac.jvm.ClassFile;
  44 import com.sun.tools.javac.jvm.PoolConstant;
  45 import com.sun.tools.javac.util.*;
  46 import com.sun.tools.javac.util.DefinedBy.Api;
  47 
  48 import static com.sun.tools.javac.code.BoundKind.*;
  49 import static com.sun.tools.javac.code.Flags.*;
  50 import static com.sun.tools.javac.code.Kinds.Kind.*;
  51 import static com.sun.tools.javac.code.TypeTag.*;
  52 
  53 /** This class represents Java types. The class itself defines the behavior of
  54  *  the following types:
  55  *  <pre>
  56  *  base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
  57  *  type `void' (tag: VOID),
  58  *  the bottom type (tag: BOT),
  59  *  the missing type (tag: NONE).
  60  *  </pre>
  61  *  <p>The behavior of the following types is defined in subclasses, which are
  62  *  all static inner classes of this class:
  63  *  <pre>
  64  *  class types (tag: CLASS, class: ClassType),
  65  *  array types (tag: ARRAY, class: ArrayType),
  66  *  method types (tag: METHOD, class: MethodType),
  67  *  package types (tag: PACKAGE, class: PackageType),
  68  *  type variables (tag: TYPEVAR, class: TypeVar),
  69  *  type arguments (tag: WILDCARD, class: WildcardType),
  70  *  generic method types (tag: FORALL, class: ForAll),
  71  *  the error type (tag: ERROR, class: ErrorType).
  72  *  </pre>
  73  *
  74  *  <p><b>This is NOT part of any supported API.
  75  *  If you write code that depends on this, you do so at your own risk.
  76  *  This code and its internal interfaces are subject to change or
  77  *  deletion without notice.</b>
  78  *
  79  *  @see TypeTag
  80  */
  81 public abstract class Type extends AnnoConstruct implements TypeMirror, PoolConstant {
  82 
  83     /**
  84      * Type metadata,  Should be {@code null} for the default value.
  85      *
  86      * Note: it is an invariant that for any {@code TypeMetadata}
  87      * class, a given {@code Type} may have at most one metadata array
  88      * entry of that class.
  89      */
  90     protected final TypeMetadata metadata;
  91 
  92     public TypeMetadata getMetadata() {
  93         return metadata;
  94     }
  95 
  96     public Entry getMetadataOfKind(final Entry.Kind kind) {
  97         return metadata != null ? metadata.get(kind) : null;
  98     }
  99 
 100     /** Constant type: no type at all. */
 101     public static final JCNoType noType = new JCNoType() {
 102         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 103         public String toString() {
 104             return "none";
 105         }
 106     };
 107 
 108     /** Constant type: special type to be used during recovery of deferred expressions. */
 109     public static final JCNoType recoveryType = new JCNoType(){
 110         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 111         public String toString() {
 112             return "recovery";
 113         }
 114     };
 115 
 116     /** Constant type: special type to be used for marking stuck trees. */
 117     public static final JCNoType stuckType = new JCNoType() {
 118         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 119         public String toString() {
 120             return "stuck";
 121         }
 122     };
 123 
 124     /** If this switch is turned on, the names of type variables
 125      *  and anonymous classes are printed with hashcodes appended.
 126      */
 127     public static boolean moreInfo = false;
 128 
 129     /** The defining class / interface / package / type variable.
 130      */
 131     public TypeSymbol tsym;
 132 
 133     @Override
 134     public int poolTag() {
 135         throw new AssertionError("Invalid pool entry");
 136     }
 137 
 138     @Override
 139     public Object poolKey(Types types) {
 140         return new UniqueType(this, types);
 141     }
 142 
 143     /**
 144      * Checks if the current type tag is equal to the given tag.
 145      * @return true if tag is equal to the current type tag.
 146      */
 147     public boolean hasTag(TypeTag tag) {
 148         return tag == getTag();
 149     }
 150 
 151     /**
 152      * Returns the current type tag.
 153      * @return the value of the current type tag.
 154      */
 155     public abstract TypeTag getTag();
 156 
 157     public boolean isNumeric() {
 158         return false;
 159     }
 160 
 161     public boolean isIntegral() {
 162         return false;
 163     }
 164 
 165     public boolean isPrimitive() {
 166         return false;
 167     }
 168 
 169     public boolean isPrimitiveOrVoid() {
 170         return false;
 171     }
 172 
 173     public boolean isReference() {
 174         return false;
 175     }
 176 
 177     public boolean isNullOrReference() {
 178         return false;
 179     }
 180 
 181     public boolean isPartial() {
 182         return false;
 183     }
 184 
 185     /**
 186      * The constant value of this type, null if this type does not
 187      * have a constant value attribute. Only primitive types and
 188      * strings (ClassType) can have a constant value attribute.
 189      * @return the constant value attribute of this type
 190      */
 191     public Object constValue() {
 192         return null;
 193     }
 194 
 195     /** Is this a constant type whose value is false?
 196      */
 197     public boolean isFalse() {
 198         return false;
 199     }
 200 
 201     /** Is this a constant type whose value is true?
 202      */
 203     public boolean isTrue() {
 204         return false;
 205     }
 206 
 207     /**
 208      * Get the representation of this type used for modelling purposes.
 209      * By default, this is itself. For ErrorType, a different value
 210      * may be provided.
 211      */
 212     public Type getModelType() {
 213         return this;
 214     }
 215 
 216     public static List<Type> getModelTypes(List<Type> ts) {
 217         ListBuffer<Type> lb = new ListBuffer<>();
 218         for (Type t: ts)
 219             lb.append(t.getModelType());
 220         return lb.toList();
 221     }
 222 
 223     /**For ErrorType, returns the original type, otherwise returns the type itself.
 224      */
 225     public Type getOriginalType() {
 226         return this;
 227     }
 228 
 229     public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
 230 
 231     /** Define a type given its tag, type symbol, and type annotations
 232      */
 233 
 234     public Type(TypeSymbol tsym, TypeMetadata metadata) {
 235         Assert.checkNonNull(metadata);
 236         this.tsym = tsym;
 237         this.metadata = metadata;
 238     }
 239 
 240     public boolean isPrimitiveClass() {
 241         return false;
 242     }
 243 
 244     /**
 245      * Return the `flavor' associated with a ClassType.
 246      * @see ClassType.Flavor
 247      */
 248     public Flavor getFlavor() {
 249         throw new AssertionError("Unexpected call to getFlavor() on a Type that is not a ClassType: " + this);
 250     }
 251 
 252     /**
 253      * @return true IFF the receiver is a reference projection type of a *value favoring* primitive class
 254      * and false otherwise.
 255      */
 256     public boolean isReferenceProjection() {
 257         return false;
 258     }
 259 
 260     /**
 261      * @return true IFF the receiver is a primitive reference type and false otherwise.
 262      */
 263     public boolean isPrimitiveReferenceType() {
 264         return false;
 265     }
 266 
 267     /**
 268      * @return true IFF the receiver is a value projection of a *reference favoring* primitive class type
 269      * and false otherwise.
 270      */
 271     public boolean isValueProjection() {
 272         return false;
 273     }
 274 
 275     /**
 276      * Returns the ClassType representing the primitive value type
 277      * of this type, if the class of this type is a primitive class
 278      * null otherwise
 279      */
 280     public ClassType asValueType() {
 281         return null;
 282     }
 283 
 284     /**
 285      * @return the reference projection type IFF the receiver is a primitive class type
 286      * and null otherwise
 287      */
 288     public Type referenceProjection() {
 289         return null;
 290     }
 291 
 292     /**
 293      * @return the reference projection type IFF the receiver is a primitive class type or self otherwise.
 294      */
 295     public Type referenceProjectionOrSelf() {
 296         Type projection = referenceProjection();
 297         return projection != null ? projection : this;
 298     }
 299 
 300     /**
 301      * A subclass of {@link Types.TypeMapping} which applies a mapping recursively to the subterms
 302      * of a given type expression. This mapping returns the original type is no changes occurred
 303      * when recursively mapping the original type's subterms.
 304      */
 305     public static abstract class StructuralTypeMapping<S> extends Types.TypeMapping<S> {
 306 
 307         @Override
 308         public Type visitClassType(ClassType t, S s) {
 309             Type outer = t.getEnclosingType();
 310             Type outer1 = visit(outer, s);
 311             List<Type> typarams = t.getTypeArguments();
 312             List<Type> typarams1 = visit(typarams, s);
 313             if (outer1 == outer && typarams1 == typarams) return t;
 314             else return new ClassType(outer1, typarams1, t.tsym, t.metadata, t.getFlavor()) {
 315                 @Override
 316                 protected boolean needsStripping() {
 317                     return true;
 318                 }
 319             };
 320         }
 321 
 322         @Override
 323         public Type visitWildcardType(WildcardType wt, S s) {
 324             Type t = wt.type;
 325             if (t != null)
 326                 t = visit(t, s);
 327             if (t == wt.type)
 328                 return wt;
 329             else
 330                 return new WildcardType(t, wt.kind, wt.tsym, wt.bound, wt.metadata) {
 331                     @Override
 332                     protected boolean needsStripping() {
 333                         return true;
 334                     }
 335                 };
 336         }
 337 
 338         @Override
 339         public Type visitArrayType(ArrayType t, S s) {
 340             Type elemtype = t.elemtype;
 341             Type elemtype1 = visit(elemtype, s);
 342             if (elemtype1 == elemtype) return t;
 343             else return new ArrayType(elemtype1, t.tsym, t.metadata) {
 344                 @Override
 345                 protected boolean needsStripping() {
 346                     return true;
 347                 }
 348             };
 349         }
 350 
 351         @Override
 352         public Type visitMethodType(MethodType t, S s) {
 353             List<Type> argtypes = t.argtypes;
 354             Type restype = t.restype;
 355             List<Type> thrown = t.thrown;
 356             List<Type> argtypes1 = visit(argtypes, s);
 357             Type restype1 = visit(restype, s);
 358             List<Type> thrown1 = visit(thrown, s);
 359             if (argtypes1 == argtypes &&
 360                 restype1 == restype &&
 361                 thrown1 == thrown) return t;
 362             else return new MethodType(argtypes1, restype1, thrown1, t.tsym) {
 363                 @Override
 364                 protected boolean needsStripping() {
 365                     return true;
 366                 }
 367             };
 368         }
 369 
 370         @Override
 371         public Type visitForAll(ForAll t, S s) {
 372             return visit(t.qtype, s);
 373         }
 374     }
 375 
 376     /** map a type function over all immediate descendants of this type
 377      */
 378     public <Z> Type map(TypeMapping<Z> mapping, Z arg) {
 379         return mapping.visit(this, arg);
 380     }
 381 
 382     /** map a type function over all immediate descendants of this type (no arg version)
 383      */
 384     public <Z> Type map(TypeMapping<Z> mapping) {
 385         return mapping.visit(this, null);
 386     }
 387 
 388     /** Define a constant type, of the same kind as this type
 389      *  and with given constant value
 390      */
 391     public Type constType(Object constValue) {
 392         throw new AssertionError();
 393     }
 394 
 395     /**
 396      * If this is a constant type, return its underlying type.
 397      * Otherwise, return the type itself.
 398      */
 399     public Type baseType() {
 400         return this;
 401     }
 402 
 403     /**
 404      * Returns the original version of this type, before metadata were added. This routine is meant
 405      * for internal use only (i.e. {@link Type#equalsIgnoreMetadata(Type)}, {@link Type#stripMetadata});
 406      * it should not be used outside this class.
 407      */
 408     protected Type typeNoMetadata() {
 409         return metadata == TypeMetadata.EMPTY ? this : baseType();
 410     }
 411 
 412     /**
 413      * Create a new copy of this type but with the specified TypeMetadata.
 414      */
 415     public abstract Type cloneWithMetadata(TypeMetadata metadata);
 416 
 417     /**
 418      * Does this type require annotation stripping for API clients?
 419      */
 420     protected boolean needsStripping() {
 421         return false;
 422     }
 423 
 424     /**
 425      * Strip all metadata associated with this type - this could return a new clone of the type.
 426      * This routine is only used to present the correct annotated types back to the users when types
 427      * are accessed through compiler APIs; it should not be used anywhere in the compiler internals
 428      * as doing so might result in performance penalties.
 429      */
 430     public Type stripMetadataIfNeeded() {
 431         return needsStripping() ?
 432                 accept(stripMetadata, null) :
 433                 this;
 434     }
 435 
 436     public Type stripMetadata() {
 437         return accept(stripMetadata, null);
 438     }
 439     //where
 440         private static final TypeMapping<Void> stripMetadata = new StructuralTypeMapping<Void>() {
 441             @Override
 442             public Type visitClassType(ClassType t, Void aVoid) {
 443                 return super.visitClassType((ClassType)t.typeNoMetadata(), aVoid);
 444             }
 445 
 446             @Override
 447             public Type visitArrayType(ArrayType t, Void aVoid) {
 448                 return super.visitArrayType((ArrayType)t.typeNoMetadata(), aVoid);
 449             }
 450 
 451             @Override
 452             public Type visitTypeVar(TypeVar t, Void aVoid) {
 453                 return super.visitTypeVar((TypeVar)t.typeNoMetadata(), aVoid);
 454             }
 455 
 456             @Override
 457             public Type visitWildcardType(WildcardType wt, Void aVoid) {
 458                 return super.visitWildcardType((WildcardType)wt.typeNoMetadata(), aVoid);
 459             }
 460         };
 461 
 462     public Type annotatedType(final List<Attribute.TypeCompound> annos) {
 463         final Entry annoMetadata = new TypeMetadata.Annotations(annos);
 464         return cloneWithMetadata(metadata.combine(annoMetadata));
 465     }
 466 
 467     public boolean isAnnotated() {
 468         final TypeMetadata.Annotations metadata =
 469             (TypeMetadata.Annotations)getMetadataOfKind(Entry.Kind.ANNOTATIONS);
 470 
 471         return null != metadata && !metadata.getAnnotations().isEmpty();
 472     }
 473 
 474     @Override @DefinedBy(Api.LANGUAGE_MODEL)
 475     public List<Attribute.TypeCompound> getAnnotationMirrors() {
 476         final TypeMetadata.Annotations metadata =
 477             (TypeMetadata.Annotations)getMetadataOfKind(Entry.Kind.ANNOTATIONS);
 478 
 479         return metadata == null ? List.nil() : metadata.getAnnotations();
 480     }
 481 
 482 
 483     @Override @DefinedBy(Api.LANGUAGE_MODEL)
 484     public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
 485         return null;
 486     }
 487 
 488 
 489     @Override @DefinedBy(Api.LANGUAGE_MODEL)
 490     public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
 491         @SuppressWarnings("unchecked")
 492         A[] tmp = (A[]) java.lang.reflect.Array.newInstance(annotationType, 0);
 493         return tmp;
 494     }
 495 
 496     /** Return the base types of a list of types.
 497      */
 498     public static List<Type> baseTypes(List<Type> ts) {
 499         if (ts.nonEmpty()) {
 500             Type t = ts.head.baseType();
 501             List<Type> baseTypes = baseTypes(ts.tail);
 502             if (t != ts.head || baseTypes != ts.tail)
 503                 return baseTypes.prepend(t);
 504         }
 505         return ts;
 506     }
 507 
 508     protected void appendAnnotationsString(StringBuilder sb,
 509                                          boolean prefix) {
 510         if (isAnnotated()) {
 511             if (prefix) {
 512                 sb.append(" ");
 513             }
 514             sb.append(getAnnotationMirrors());
 515             sb.append(" ");
 516         }
 517     }
 518 
 519     protected void appendAnnotationsString(StringBuilder sb) {
 520         appendAnnotationsString(sb, false);
 521     }
 522 
 523     /** The Java source which this type represents.
 524      */
 525     @DefinedBy(Api.LANGUAGE_MODEL)
 526     public String toString() {
 527         StringBuilder sb = new StringBuilder();
 528         appendAnnotationsString(sb);
 529         if (tsym == null || tsym.name == null) {
 530             sb.append("<none>");
 531         } else {
 532             sb.append(tsym.name.toString());
 533         }
 534         if (moreInfo && hasTag(TYPEVAR)) {
 535             sb.append(hashCode());
 536         }
 537         return sb.toString();
 538     }
 539 
 540     /**
 541      * The Java source which this type list represents.  A List is
 542      * represented as a comma-separated listing of the elements in
 543      * that list.
 544      */
 545     public static String toString(List<Type> ts) {
 546         if (ts.isEmpty()) {
 547             return "";
 548         } else {
 549             StringBuilder buf = new StringBuilder();
 550             buf.append(ts.head.toString());
 551             for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail)
 552                 buf.append(",").append(l.head.toString());
 553             return buf.toString();
 554         }
 555     }
 556 
 557     /**
 558      * The constant value of this type, converted to String
 559      */
 560     public String stringValue() {
 561         Object cv = Assert.checkNonNull(constValue());
 562         return cv.toString();
 563     }
 564 
 565     /**
 566      * Override this method with care. For most Type instances this should behave as ==.
 567      */
 568     @Override @DefinedBy(Api.LANGUAGE_MODEL)
 569     public boolean equals(Object t) {
 570         return this == t;
 571     }
 572 
 573     public boolean equalsIgnoreMetadata(Type t) {
 574         return typeNoMetadata().equals(t.typeNoMetadata());
 575     }
 576 
 577     @Override @DefinedBy(Api.LANGUAGE_MODEL)
 578     public int hashCode() {
 579         return super.hashCode();
 580     }
 581 
 582     public String argtypes(boolean varargs) {
 583         List<Type> args = getParameterTypes();
 584         if (!varargs) return args.toString();
 585         StringBuilder buf = new StringBuilder();
 586         while (args.tail.nonEmpty()) {
 587             buf.append(args.head);
 588             args = args.tail;
 589             buf.append(',');
 590         }
 591         if (args.head.hasTag(ARRAY)) {
 592             buf.append(((ArrayType)args.head).elemtype);
 593             if (args.head.getAnnotationMirrors().nonEmpty()) {
 594                 buf.append(args.head.getAnnotationMirrors());
 595             }
 596             buf.append("...");
 597         } else {
 598             buf.append(args.head);
 599         }
 600         return buf.toString();
 601     }
 602 
 603     /** Access methods.
 604      */
 605     public List<Type>        getTypeArguments()  { return List.nil(); }
 606     public Type              getEnclosingType()  { return null; }
 607     public List<Type>        getParameterTypes() { return List.nil(); }
 608     public Type              getReturnType()     { return null; }
 609     public Type              getReceiverType()   { return null; }
 610     public List<Type>        getThrownTypes()    { return List.nil(); }
 611     public Type              getUpperBound()     { return null; }
 612     public Type              getLowerBound()     { return null; }
 613 
 614     /** Navigation methods, these will work for classes, type variables,
 615      *  foralls, but will return null for arrays and methods.
 616      */
 617 
 618    /** Return all parameters of this type and all its outer types in order
 619     *  outer (first) to inner (last).
 620     */
 621     public List<Type> allparams() { return List.nil(); }
 622 
 623     /** Does this type contain "error" elements?
 624      */
 625     public boolean isErroneous() {
 626         return false;
 627     }
 628 
 629     public static boolean isErroneous(List<Type> ts) {
 630         for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
 631             if (l.head.isErroneous()) return true;
 632         return false;
 633     }
 634 
 635     /** Is this type parameterized?
 636      *  A class type is parameterized if it has some parameters.
 637      *  An array type is parameterized if its element type is parameterized.
 638      *  All other types are not parameterized.
 639      */
 640     public boolean isParameterized() {
 641         return false;
 642     }
 643 
 644     /** Is this type a raw type?
 645      *  A class type is a raw type if it misses some of its parameters.
 646      *  An array type is a raw type if its element type is raw.
 647      *  All other types are not raw.
 648      *  Type validation will ensure that the only raw types
 649      *  in a program are types that miss all their type variables.
 650      */
 651     public boolean isRaw() {
 652         return false;
 653     }
 654 
 655     /**
 656      * A compound type is a special class type whose supertypes are used to store a list
 657      * of component types. There are two kinds of compound types: (i) intersection types
 658      * {@see IntersectionClassType} and (ii) union types {@see UnionClassType}.
 659      */
 660     public boolean isCompound() {
 661         return false;
 662     }
 663 
 664     public boolean isIntersection() {
 665         return false;
 666     }
 667 
 668     public boolean isUnion() {
 669         return false;
 670     }
 671 
 672     public boolean isInterface() {
 673         return (tsym.flags() & INTERFACE) != 0;
 674     }
 675 
 676     public boolean isFinal() {
 677         return (tsym.flags() & FINAL) != 0;
 678     }
 679 
 680     /**
 681      * Does this type contain occurrences of type t?
 682      */
 683     public boolean contains(Type t) {
 684         return t.equalsIgnoreMetadata(this);
 685     }
 686 
 687     public static boolean contains(List<Type> ts, Type t) {
 688         for (List<Type> l = ts;
 689              l.tail != null /*inlined: l.nonEmpty()*/;
 690              l = l.tail)
 691             if (l.head.contains(t)) return true;
 692         return false;
 693     }
 694 
 695     /** Does this type contain an occurrence of some type in 'ts'?
 696      */
 697     public boolean containsAny(List<Type> ts) {
 698         for (Type t : ts)
 699             if (this.contains(t)) return true;
 700         return false;
 701     }
 702 
 703     public static boolean containsAny(List<Type> ts1, List<Type> ts2) {
 704         for (Type t : ts1)
 705             if (t.containsAny(ts2)) return true;
 706         return false;
 707     }
 708 
 709     public static List<Type> filter(List<Type> ts, Predicate<Type> tf) {
 710         ListBuffer<Type> buf = new ListBuffer<>();
 711         for (Type t : ts) {
 712             if (tf.test(t)) {
 713                 buf.append(t);
 714             }
 715         }
 716         return buf.toList();
 717     }
 718 
 719     public boolean isSuperBound() { return false; }
 720     public boolean isExtendsBound() { return false; }
 721     public boolean isUnbound() { return false; }
 722     public Type withTypeVar(Type t) { return this; }
 723 
 724     /** The underlying method type of this type.
 725      */
 726     public MethodType asMethodType() { throw new AssertionError(); }
 727 
 728     /** Complete loading all classes in this type.
 729      */
 730     public void complete() {}
 731 
 732     public TypeSymbol asElement() {
 733         return tsym;
 734     }
 735 
 736     @Override @DefinedBy(Api.LANGUAGE_MODEL)
 737     public TypeKind getKind() {
 738         return TypeKind.OTHER;
 739     }
 740 
 741     @Override @DefinedBy(Api.LANGUAGE_MODEL)
 742     public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 743         throw new AssertionError();
 744     }
 745 
 746     public static class JCPrimitiveType extends Type
 747             implements javax.lang.model.type.PrimitiveType {
 748 
 749         TypeTag tag;
 750 
 751         public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
 752             this(tag, tsym, TypeMetadata.EMPTY);
 753         }
 754 
 755         private JCPrimitiveType(TypeTag tag, TypeSymbol tsym, TypeMetadata metadata) {
 756             super(tsym, metadata);
 757             this.tag = tag;
 758             Assert.check(tag.isPrimitive);
 759         }
 760 
 761         @Override
 762         public JCPrimitiveType cloneWithMetadata(TypeMetadata md) {
 763             return new JCPrimitiveType(tag, tsym, md) {
 764                 @Override
 765                 public Type baseType() { return JCPrimitiveType.this.baseType(); }
 766             };
 767         }
 768 
 769         @Override
 770         public boolean isNumeric() {
 771             return tag != BOOLEAN;
 772         }
 773 
 774         @Override
 775         public boolean isIntegral() {
 776             switch (tag) {
 777                 case CHAR:
 778                 case BYTE:
 779                 case SHORT:
 780                 case INT:
 781                 case LONG:
 782                     return true;
 783                 default:
 784                     return false;
 785             }
 786         }
 787 
 788         @Override
 789         public boolean isPrimitive() {
 790             return true;
 791         }
 792 
 793         @Override
 794         public TypeTag getTag() {
 795             return tag;
 796         }
 797 
 798         @Override
 799         public boolean isPrimitiveOrVoid() {
 800             return true;
 801         }
 802 
 803         /** Define a constant type, of the same kind as this type
 804          *  and with given constant value
 805          */
 806         @Override
 807         public Type constType(Object constValue) {
 808             final Object value = constValue;
 809             return new JCPrimitiveType(tag, tsym, metadata) {
 810                     @Override
 811                     public Object constValue() {
 812                         return value;
 813                     }
 814                     @Override
 815                     public Type baseType() {
 816                         return tsym.type;
 817                     }
 818                 };
 819         }
 820 
 821         /**
 822          * The constant value of this type, converted to String
 823          */
 824         @Override
 825         public String stringValue() {
 826             Object cv = Assert.checkNonNull(constValue());
 827             if (tag == BOOLEAN) {
 828                 return ((Integer) cv).intValue() == 0 ? "false" : "true";
 829             }
 830             else if (tag == CHAR) {
 831                 return String.valueOf((char) ((Integer) cv).intValue());
 832             }
 833             else {
 834                 return cv.toString();
 835             }
 836         }
 837 
 838         /** Is this a constant type whose value is false?
 839          */
 840         @Override
 841         public boolean isFalse() {
 842             return
 843                 tag == BOOLEAN &&
 844                 constValue() != null &&
 845                 ((Integer)constValue()).intValue() == 0;
 846         }
 847 
 848         /** Is this a constant type whose value is true?
 849          */
 850         @Override
 851         public boolean isTrue() {
 852             return
 853                 tag == BOOLEAN &&
 854                 constValue() != null &&
 855                 ((Integer)constValue()).intValue() != 0;
 856         }
 857 
 858         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 859         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 860             return v.visitPrimitive(this, p);
 861         }
 862 
 863         @Override @DefinedBy(Api.LANGUAGE_MODEL)
 864         public TypeKind getKind() {
 865             switch (tag) {
 866                 case BYTE:      return TypeKind.BYTE;
 867                 case CHAR:      return TypeKind.CHAR;
 868                 case SHORT:     return TypeKind.SHORT;
 869                 case INT:       return TypeKind.INT;
 870                 case LONG:      return TypeKind.LONG;
 871                 case FLOAT:     return TypeKind.FLOAT;
 872                 case DOUBLE:    return TypeKind.DOUBLE;
 873                 case BOOLEAN:   return TypeKind.BOOLEAN;
 874             }
 875             throw new AssertionError();
 876         }
 877 
 878     }
 879 
 880     public static class WildcardType extends Type
 881             implements javax.lang.model.type.WildcardType {
 882 
 883         public Type type;
 884         public BoundKind kind;
 885         public TypeVar bound;
 886 
 887         @Override
 888         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
 889             return v.visitWildcardType(this, s);
 890         }
 891 
 892         public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
 893             this(type, kind, tsym, null, TypeMetadata.EMPTY);
 894         }
 895 
 896         public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
 897                             TypeMetadata metadata) {
 898             this(type, kind, tsym, null, metadata);
 899         }
 900 
 901         public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
 902                             TypeVar bound) {
 903             this(type, kind, tsym, bound, TypeMetadata.EMPTY);
 904         }
 905 
 906         public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
 907                             TypeVar bound, TypeMetadata metadata) {
 908             super(tsym, metadata);
 909             this.type = Assert.checkNonNull(type);
 910             this.kind = kind;
 911             this.bound = bound;
 912         }
 913 
 914         @Override
 915         public WildcardType cloneWithMetadata(TypeMetadata md) {
 916             return new WildcardType(type, kind, tsym, bound, md) {
 917                 @Override
 918                 public Type baseType() { return WildcardType.this.baseType(); }
 919             };
 920         }
 921 
 922         @Override
 923         public TypeTag getTag() {
 924             return WILDCARD;
 925         }
 926 
 927         @Override
 928         public boolean contains(Type t) {
 929             return kind != UNBOUND && type.contains(t);
 930         }
 931 
 932         public boolean isSuperBound() {
 933             return kind == SUPER ||
 934                 kind == UNBOUND;
 935         }
 936         public boolean isExtendsBound() {
 937             return kind == EXTENDS ||
 938                 kind == UNBOUND;
 939         }
 940         public boolean isUnbound() {
 941             // is it `?` or `? extends Object`?
 942             return kind == UNBOUND ||
 943                     (kind == EXTENDS && type.tsym.flatName() == type.tsym.name.table.names.java_lang_Object);
 944         }
 945 
 946         @Override
 947         public boolean isReference() {
 948             return true;
 949         }
 950 
 951         @Override
 952         public boolean isNullOrReference() {
 953             return true;
 954         }
 955 
 956         @Override
 957         public Type withTypeVar(Type t) {
 958             //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
 959             if (bound == t)
 960                 return this;
 961             bound = (TypeVar)t;
 962             return this;
 963         }
 964 
 965         boolean isPrintingBound = false;
 966         @DefinedBy(Api.LANGUAGE_MODEL)
 967         public String toString() {
 968             StringBuilder s = new StringBuilder();
 969             appendAnnotationsString(s);
 970             s.append(kind.toString());
 971             if (kind != UNBOUND)
 972                 s.append(type);
 973             if (moreInfo && bound != null && !isPrintingBound)
 974                 try {
 975                     isPrintingBound = true;
 976                     s.append("{:").append(bound.getUpperBound()).append(":}");
 977                 } finally {
 978                     isPrintingBound = false;
 979                 }
 980             return s.toString();
 981         }
 982 
 983         @DefinedBy(Api.LANGUAGE_MODEL)
 984         public Type getExtendsBound() {
 985             if (kind == EXTENDS)
 986                 return type;
 987             else
 988                 return null;
 989         }
 990 
 991         @DefinedBy(Api.LANGUAGE_MODEL)
 992         public Type getSuperBound() {
 993             if (kind == SUPER)
 994                 return type;
 995             else
 996                 return null;
 997         }
 998 
 999         @DefinedBy(Api.LANGUAGE_MODEL)
1000         public TypeKind getKind() {
1001             return TypeKind.WILDCARD;
1002         }
1003 
1004         @DefinedBy(Api.LANGUAGE_MODEL)
1005         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1006             return v.visitWildcard(this, p);
1007         }
1008     }
1009 
1010     public static class ConstantPoolQType implements PoolConstant {
1011 
1012         public final Type type;
1013         final Types types;
1014 
1015         public ConstantPoolQType(Type type, Types types) {
1016             this.type = type;
1017             this.types = types;
1018         }
1019 
1020         @Override
1021         public Object poolKey(Types types) {
1022             return this;
1023         }
1024 
1025         @Override
1026         public int poolTag() {
1027             return ClassFile.CONSTANT_Class;
1028         }
1029 
1030         public int hashCode() {
1031             return types.hashCode(type);
1032         }
1033 
1034         public boolean equals(Object obj) {
1035             return (obj instanceof ConstantPoolQType) &&
1036                     types.isSameType(type, ((ConstantPoolQType)obj).type);
1037         }
1038 
1039         public String toString() {
1040             return type.toString();
1041         }
1042     }
1043 
1044     public static class ClassType extends Type implements DeclaredType, LoadableConstant,
1045                                                           javax.lang.model.type.ErrorType {
1046 
1047         /**
1048          * The 'flavor' of a ClassType indicates its reference/primitive projectionness
1049          * viewed against the default nature of the associated class.
1050          */
1051         public enum Flavor {
1052 
1053             /**
1054              * Classic reference type. Also reference projection type of a reference-favoring aka
1055              * reference-default primitive class type
1056              */
1057             L_TypeOf_L,
1058 
1059             /**
1060              * A primitive reference type:  (Assosiated primitive class could be either
1061              * reference default or value-default)
1062              */
1063             L_TypeOf_Q,
1064 
1065             /**
1066              * Value projection type of a primitive-favoring aka primitive-default
1067              * plain vanilla primitive class type,
1068              */
1069             Q_TypeOf_Q,
1070 
1071             /**
1072              * Value projection type of a reference-favoring aka
1073              * reference-default primitive class type
1074              */
1075             Q_TypeOf_L,
1076 
1077             /**
1078              * Reference projection type of a class type of an as yet unknown default provenance, 'X' will be
1079              * discovered to be 'L' or 'Q' in "due course" and mutated suitably.
1080              */
1081             L_TypeOf_X,
1082 
1083             /**
1084              * Value projection type of a class type of an as yet unknown default provenance, 'X' will be
1085              * discovered to be 'L' or 'Q' in "due course" and mutated suitably.
1086              */
1087             Q_TypeOf_X,
1088 
1089             /**
1090              *  As yet unknown projection type of an as yet unknown default provenance class. Is also
1091              *  the terminal flavor for package-info/module-info files.
1092              */
1093             X_Typeof_X,
1094 
1095             /**
1096              *  An error type - we don't care to discriminate them any further.
1097              */
1098              E_Typeof_X;
1099 
1100             // We don't seem to need X_Typeof_L or X_Typeof_Q so far.
1101 
1102             // Transform a larval form into a more evolved form
1103             public Flavor metamorphose(long classFlags) {
1104 
1105                 boolean isPrimtiveClass = (classFlags & PRIMITIVE_CLASS) != 0;
1106                 boolean isReferenceFavoring = (classFlags & REFERENCE_FAVORING) != 0;
1107 
1108                 switch (this) {
1109 
1110                     case E_Typeof_X:  // stunted form
1111                     case L_TypeOf_L:
1112                     case L_TypeOf_Q:
1113                     case Q_TypeOf_L:
1114                     case Q_TypeOf_Q:
1115                             // These are fully evolved sealed forms or stunted - no futher transformation
1116                             return this;
1117                     case L_TypeOf_X:
1118                             return isPrimtiveClass ? L_TypeOf_Q : L_TypeOf_L;
1119                     case Q_TypeOf_X:
1120                             return isReferenceFavoring ? Q_TypeOf_L : Q_TypeOf_Q;
1121                     case X_Typeof_X:
1122                             return isPrimtiveClass ? (isReferenceFavoring ? L_TypeOf_Q : Q_TypeOf_Q) : L_TypeOf_L;
1123                     default:
1124                             throw new AssertionError("Unexpected class type flavor");
1125                 }
1126             }
1127         }
1128 
1129         /** The enclosing type of this type. If this is the type of an inner
1130          *  class, outer_field refers to the type of its enclosing
1131          *  instance class, in all other cases it refers to noType.
1132          */
1133         private Type outer_field;
1134 
1135         /** The type parameters of this type (to be set once class is loaded).
1136          */
1137         public List<Type> typarams_field;
1138 
1139         /** A cache variable for the type parameters of this type,
1140          *  appended to all parameters of its enclosing class.
1141          *  @see #allparams
1142          */
1143         public List<Type> allparams_field;
1144 
1145         /** The supertype of this class (to be set once class is loaded).
1146          */
1147         public Type supertype_field;
1148 
1149         /** The interfaces of this class (to be set once class is loaded).
1150          */
1151         public List<Type> interfaces_field;
1152 
1153         /** All the interfaces of this class, including missing ones.
1154          */
1155         public List<Type> all_interfaces_field;
1156 
1157         /** The 'other' projection: If 'this' is type of a primitive class, then 'projection' is the
1158          *  reference projection type and vice versa. Lazily initialized, not to be accessed directly.
1159         */
1160         public ClassType projection;
1161 
1162         /** Is this L of default {L, Q, X} or Q of default {L, Q, X} ?
1163          */
1164         public Flavor flavor;
1165 
1166         /*
1167          * Use of this constructor is kinda sorta deprecated, use the other constructor
1168          * that forces the call site to consider and include the class type flavor.
1169          */
1170         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
1171             this(outer, typarams, tsym, TypeMetadata.EMPTY, Flavor.L_TypeOf_L);
1172         }
1173 
1174         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
1175                          TypeMetadata metadata, Flavor flavor) {
1176             super(tsym, metadata);
1177             this.outer_field = outer;
1178             this.typarams_field = typarams;
1179             this.allparams_field = null;
1180             this.supertype_field = null;
1181             this.interfaces_field = null;
1182             this.flavor = flavor;
1183         }
1184 
1185         public int poolTag() {
1186             return ClassFile.CONSTANT_Class;
1187         }
1188 
1189         @Override
1190         public ClassType cloneWithMetadata(TypeMetadata md) {
1191             return new ClassType(outer_field, typarams_field, tsym, md, flavor) {
1192                 @Override
1193                 public Type baseType() { return ClassType.this.baseType(); }
1194             };
1195         }
1196 
1197         @Override
1198         public TypeTag getTag() {
1199             return CLASS;
1200         }
1201 
1202         @Override
1203         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1204             return v.visitClassType(this, s);
1205         }
1206 
1207         public Type constType(Object constValue) {
1208             final Object value = constValue;
1209             return new ClassType(getEnclosingType(), typarams_field, tsym, metadata, flavor) {
1210                     @Override
1211                     public Object constValue() {
1212                         return value;
1213                     }
1214                     @Override
1215                     public Type baseType() {
1216                         return tsym.type;
1217                     }
1218                 };
1219         }
1220 
1221         /** The Java source which this type represents.
1222          */
1223         @DefinedBy(Api.LANGUAGE_MODEL)
1224         public String toString() {
1225             StringBuilder buf = new StringBuilder();
1226             if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
1227                 buf.append(getEnclosingType().toString());
1228                 buf.append(".");
1229                 appendAnnotationsString(buf);
1230                 buf.append(className(tsym, false));
1231             } else {
1232                 appendAnnotationsString(buf);
1233                 buf.append(className(tsym, true));
1234             }
1235             try {
1236                 if (isReferenceProjection()) {
1237                     buf.append('.');
1238                     buf.append(tsym.name.table.names.ref);
1239                 } else if (isValueProjection()) {
1240                     buf.append('.');
1241                     buf.append(tsym.name.table.names.val);
1242                 }
1243             } catch (CompletionFailure cf) {
1244                 // don't let missing types capsize the boat.
1245             }
1246             if (getTypeArguments().nonEmpty()) {
1247                 buf.append('<');
1248                 buf.append(getTypeArguments().toString());
1249                 buf.append(">");
1250             }
1251             return buf.toString();
1252         }
1253 //where
1254             private String className(Symbol sym, boolean longform) {
1255                 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
1256                     StringBuilder s = new StringBuilder(supertype_field.toString());
1257                     for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
1258                         s.append("&");
1259                         s.append(is.head.toString());
1260                     }
1261                     return s.toString();
1262                 } else if (sym.name.isEmpty()) {
1263                     String s;
1264                     ClassType norm = (ClassType) tsym.type;
1265                     if (norm == null) {
1266                         s = Log.getLocalizedString("anonymous.class", (Object)null);
1267                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
1268                         s = Log.getLocalizedString("anonymous.class",
1269                                                    norm.interfaces_field.head);
1270                     } else {
1271                         s = Log.getLocalizedString("anonymous.class",
1272                                                    norm.supertype_field);
1273                     }
1274                     if (moreInfo)
1275                         s += String.valueOf(sym.hashCode());
1276                     return s;
1277                 }
1278                 String s;
1279                 if (longform) {
1280                     s =  sym.getQualifiedName().toString();
1281                 } else {
1282                     s = sym.name.toString();
1283                 }
1284                 return s;
1285             }
1286 
1287         public Flavor getFlavor() {
1288             return flavor;
1289         }
1290 
1291         @DefinedBy(Api.LANGUAGE_MODEL)
1292         public List<Type> getTypeArguments() {
1293             if (typarams_field == null) {
1294                 complete();
1295                 if (typarams_field == null)
1296                     typarams_field = List.nil();
1297             }
1298             return typarams_field;
1299         }
1300 
1301         public boolean hasErasedSupertypes() {
1302             return isRaw();
1303         }
1304 
1305         @DefinedBy(Api.LANGUAGE_MODEL)
1306         public Type getEnclosingType() {
1307             if (outer_field != null && outer_field.isReferenceProjection()) {
1308                 outer_field = outer_field.asValueType();
1309             }
1310             return outer_field;
1311         }
1312 
1313         public void setEnclosingType(Type outer) {
1314             outer_field = outer;
1315         }
1316 
1317         public List<Type> allparams() {
1318             if (allparams_field == null) {
1319                 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
1320             }
1321             return allparams_field;
1322         }
1323 
1324         public boolean isErroneous() {
1325             return
1326                 getEnclosingType().isErroneous() ||
1327                 isErroneous(getTypeArguments()) ||
1328                 this != tsym.type && tsym.type.isErroneous();
1329         }
1330 
1331         public boolean isParameterized() {
1332             return allparams().tail != null;
1333             // optimization, was: allparams().nonEmpty();
1334         }
1335 
1336         @Override
1337         public boolean isReference() {
1338             return true;
1339         }
1340 
1341         @Override
1342         public boolean isPrimitiveClass() {
1343             // guard against over-eager and/or inopportune completion
1344             if (tsym != null) {
1345                 if (flavor == Flavor.Q_TypeOf_X || tsym.isCompleted()) {
1346                     flavor = flavor.metamorphose(tsym.flags());
1347                 }
1348             }
1349             return flavor == Flavor.Q_TypeOf_Q || flavor == Flavor.Q_TypeOf_L;
1350         }
1351 
1352         @Override
1353         public boolean isReferenceProjection() {
1354             // guard against over-eager and/or inopportune completion
1355             if (tsym != null) {
1356                 if (flavor == Flavor.L_TypeOf_X || tsym.isCompleted()) {
1357                     flavor = flavor.metamorphose(tsym.flags());
1358                 }
1359             }
1360             return flavor == Flavor.L_TypeOf_Q && tsym.type.getFlavor() == Flavor.Q_TypeOf_Q; // discount reference favoring primitives.
1361         }
1362 
1363         @Override
1364         public boolean isPrimitiveReferenceType() {
1365             // guard against over-eager and/or inopportune completion
1366             if (tsym != null) {
1367                 if (flavor == Flavor.L_TypeOf_X || tsym.isCompleted()) {
1368                     flavor = flavor.metamorphose(tsym.flags());
1369                 }
1370             }
1371             return flavor == Flavor.L_TypeOf_Q;
1372         }
1373 
1374         @Override
1375         public boolean isValueProjection() {
1376             // guard against over-eager and/or inopportune completion
1377             if (tsym != null) {
1378                 if (flavor == Flavor.Q_TypeOf_X || tsym.isCompleted()) {
1379                     flavor = flavor.metamorphose(tsym.flags());
1380 
1381                 }
1382             }
1383             return flavor == Flavor.Q_TypeOf_L;
1384         }
1385 
1386         // return the primitive value type *preserving parameterizations*
1387         @Override
1388         public ClassType asValueType() {
1389             if (tsym == null || !tsym.isPrimitiveClass())
1390                 return null;
1391 
1392             switch (flavor) {
1393                 case Q_TypeOf_L:
1394                 case Q_TypeOf_Q:
1395                     return this;
1396                 case L_TypeOf_Q:
1397                     if (projection != null)
1398                         return projection;
1399 
1400                     projection = new ClassType(outer_field, typarams_field, tsym, getMetadata(),
1401                             tsym.isReferenceFavoringPrimitiveClass() ? Flavor.Q_TypeOf_L : Flavor.Q_TypeOf_Q);
1402                     projection.allparams_field = allparams_field;
1403                     projection.supertype_field = supertype_field;
1404 
1405                     projection.interfaces_field = interfaces_field;
1406                     projection.all_interfaces_field = all_interfaces_field;
1407                     projection.projection = this;
1408                     return projection;
1409                 default:
1410                     Assert.check(false, "Should not get here");
1411                     return null;
1412             }
1413         }
1414 
1415         // return the reference projection type preserving parameterizations
1416         @Override
1417         public ClassType referenceProjection() {
1418 
1419             if (!isPrimitiveClass())
1420                 return null;
1421 
1422             if (projection != null)
1423                 return projection;
1424 
1425             projection = new ClassType(outer_field, typarams_field, tsym, getMetadata(), Flavor.L_TypeOf_Q);
1426             projection.allparams_field = allparams_field;
1427             projection.supertype_field = supertype_field;
1428 
1429             projection.interfaces_field = interfaces_field;
1430             projection.all_interfaces_field = all_interfaces_field;
1431             projection.projection = this;
1432             return projection;
1433         }
1434 
1435         @Override
1436         public boolean isNullOrReference() {
1437             return true;
1438         }
1439 
1440         /** A cache for the rank. */
1441         int rank_field = -1;
1442 
1443         /** A class type is raw if it misses some
1444          *  of its type parameter sections.
1445          *  After validation, this is equivalent to:
1446          *  {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
1447          */
1448         public boolean isRaw() {
1449             return
1450                 this != tsym.type && // necessary, but not sufficient condition
1451                 tsym.type.allparams().nonEmpty() &&
1452                 allparams().isEmpty();
1453         }
1454 
1455         public boolean contains(Type elem) {
1456             return
1457                 elem.equalsIgnoreMetadata(this)
1458                 || (isParameterized()
1459                     && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem)))
1460                 || (isCompound()
1461                     && (supertype_field.contains(elem) || contains(interfaces_field, elem)));
1462         }
1463 
1464         public void complete() {
1465             tsym.complete();
1466         }
1467 
1468         @DefinedBy(Api.LANGUAGE_MODEL)
1469         public TypeKind getKind() {
1470             tsym.apiComplete();
1471             return tsym.kind == TYP ? TypeKind.DECLARED : TypeKind.ERROR;
1472         }
1473 
1474         @DefinedBy(Api.LANGUAGE_MODEL)
1475         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1476             return v.visitDeclared(this, p);
1477         }
1478     }
1479 
1480     public static class ErasedClassType extends ClassType {
1481         public ErasedClassType(Type outer, TypeSymbol tsym,
1482                                TypeMetadata metadata) {
1483             super(outer, List.nil(), tsym, metadata, tsym.type.getFlavor());
1484         }
1485 
1486         @Override
1487         public boolean hasErasedSupertypes() {
1488             return true;
1489         }
1490     }
1491 
1492     // a clone of a ClassType that knows about the alternatives of a union type.
1493     public static class UnionClassType extends ClassType implements UnionType {
1494         final List<? extends Type> alternatives_field;
1495 
1496         public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
1497             // Presently no way to refer to this type directly, so we
1498             // cannot put annotations directly on it.
1499             super(ct.outer_field, ct.typarams_field, ct.tsym);
1500             allparams_field = ct.allparams_field;
1501             supertype_field = ct.supertype_field;
1502             interfaces_field = ct.interfaces_field;
1503             all_interfaces_field = ct.interfaces_field;
1504             alternatives_field = alternatives;
1505         }
1506 
1507         @Override
1508         public UnionClassType cloneWithMetadata(TypeMetadata md) {
1509             throw new AssertionError("Cannot add metadata to a union type");
1510         }
1511 
1512         public Type getLub() {
1513             return tsym.type;
1514         }
1515 
1516         @DefinedBy(Api.LANGUAGE_MODEL)
1517         public java.util.List<? extends TypeMirror> getAlternatives() {
1518             return Collections.unmodifiableList(alternatives_field);
1519         }
1520 
1521         @Override
1522         public boolean isUnion() {
1523             return true;
1524         }
1525 
1526         @Override
1527         public boolean isCompound() {
1528             return getLub().isCompound();
1529         }
1530 
1531         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1532         public TypeKind getKind() {
1533             return TypeKind.UNION;
1534         }
1535 
1536         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1537         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1538             return v.visitUnion(this, p);
1539         }
1540 
1541         public Iterable<? extends Type> getAlternativeTypes() {
1542             return alternatives_field;
1543         }
1544     }
1545 
1546     // a clone of a ClassType that knows about the bounds of an intersection type.
1547     public static class IntersectionClassType extends ClassType implements IntersectionType {
1548 
1549         public boolean allInterfaces;
1550 
1551         public IntersectionClassType(List<Type> bounds, ClassSymbol csym, boolean allInterfaces) {
1552             // Presently no way to refer to this type directly, so we
1553             // cannot put annotations directly on it.
1554             super(Type.noType, List.nil(), csym);
1555             this.allInterfaces = allInterfaces;
1556             Assert.check((csym.flags() & COMPOUND) != 0);
1557             supertype_field = bounds.head;
1558             interfaces_field = bounds.tail;
1559             Assert.check(!supertype_field.tsym.isCompleted() ||
1560                     !supertype_field.isInterface(), supertype_field);
1561         }
1562 
1563         @Override
1564         public IntersectionClassType cloneWithMetadata(TypeMetadata md) {
1565             throw new AssertionError("Cannot add metadata to an intersection type");
1566         }
1567 
1568         @DefinedBy(Api.LANGUAGE_MODEL)
1569         public java.util.List<? extends TypeMirror> getBounds() {
1570             return Collections.unmodifiableList(getExplicitComponents());
1571         }
1572 
1573         @Override
1574         public boolean isCompound() {
1575             return true;
1576         }
1577 
1578         public List<Type> getComponents() {
1579             return interfaces_field.prepend(supertype_field);
1580         }
1581 
1582         @Override
1583         public boolean isIntersection() {
1584             return true;
1585         }
1586 
1587         public List<Type> getExplicitComponents() {
1588             return allInterfaces ?
1589                     interfaces_field :
1590                     getComponents();
1591         }
1592 
1593         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1594         public TypeKind getKind() {
1595             return TypeKind.INTERSECTION;
1596         }
1597 
1598         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1599         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1600             return v.visitIntersection(this, p);
1601         }
1602     }
1603 
1604     public static class ArrayType extends Type
1605             implements LoadableConstant, javax.lang.model.type.ArrayType {
1606 
1607         public Type elemtype;
1608 
1609         public ArrayType(Type elemtype, TypeSymbol arrayClass) {
1610             this(elemtype, arrayClass, TypeMetadata.EMPTY);
1611         }
1612 
1613         public ArrayType(Type elemtype, TypeSymbol arrayClass,
1614                          TypeMetadata metadata) {
1615             super(arrayClass, metadata);
1616             this.elemtype = elemtype;
1617         }
1618 
1619         public ArrayType(ArrayType that) {
1620             //note: type metadata is deliberately shared here, as we want side-effects from annotation
1621             //processing to flow from original array to the cloned array.
1622             this(that.elemtype, that.tsym, that.getMetadata());
1623         }
1624 
1625         public int poolTag() {
1626             return ClassFile.CONSTANT_Class;
1627         }
1628 
1629         @Override
1630         public ArrayType cloneWithMetadata(TypeMetadata md) {
1631             return new ArrayType(elemtype, tsym, md) {
1632                 @Override
1633                 public Type baseType() { return ArrayType.this.baseType(); }
1634             };
1635         }
1636 
1637         @Override
1638         public TypeTag getTag() {
1639             return ARRAY;
1640         }
1641 
1642         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1643             return v.visitArrayType(this, s);
1644         }
1645 
1646         @DefinedBy(Api.LANGUAGE_MODEL)
1647         public String toString() {
1648             StringBuilder sb = new StringBuilder();
1649 
1650             // First append root component type
1651             Type t = elemtype;
1652             while (t.getKind() == TypeKind.ARRAY)
1653                 t = ((ArrayType) t).getComponentType();
1654             sb.append(t);
1655 
1656             // then append @Anno[] @Anno[] ... @Anno[]
1657             t = this;
1658             do {
1659                 t.appendAnnotationsString(sb, true);
1660                 sb.append("[]");
1661                 t = ((ArrayType) t).getComponentType();
1662             } while (t.getKind() == TypeKind.ARRAY);
1663 
1664             return sb.toString();
1665         }
1666 
1667         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1668         public boolean equals(Object obj) {
1669             return (obj instanceof ArrayType arrayType)
1670                     && (this == arrayType || elemtype.equals(arrayType.elemtype));
1671         }
1672 
1673         @DefinedBy(Api.LANGUAGE_MODEL)
1674         public int hashCode() {
1675             return (ARRAY.ordinal() << 5) + elemtype.hashCode();
1676         }
1677 
1678         public boolean isVarargs() {
1679             return false;
1680         }
1681 
1682         public List<Type> allparams() { return elemtype.allparams(); }
1683 
1684         public boolean isErroneous() {
1685             return elemtype.isErroneous();
1686         }
1687 
1688         public boolean isParameterized() {
1689             return elemtype.isParameterized();
1690         }
1691 
1692         @Override
1693         public boolean isReference() {
1694             return true;
1695         }
1696 
1697         @Override
1698         public boolean isNullOrReference() {
1699             return true;
1700         }
1701 
1702         public boolean isRaw() {
1703             return elemtype.isRaw();
1704         }
1705 
1706         public ArrayType makeVarargs() {
1707             return new ArrayType(elemtype, tsym, metadata) {
1708                 @Override
1709                 public boolean isVarargs() {
1710                     return true;
1711                 }
1712             };
1713         }
1714 
1715         public boolean contains(Type elem) {
1716             return elem.equalsIgnoreMetadata(this) || elemtype.contains(elem);
1717         }
1718 
1719         public void complete() {
1720             elemtype.complete();
1721         }
1722 
1723         @DefinedBy(Api.LANGUAGE_MODEL)
1724         public Type getComponentType() {
1725             return elemtype;
1726         }
1727 
1728         @DefinedBy(Api.LANGUAGE_MODEL)
1729         public TypeKind getKind() {
1730             return TypeKind.ARRAY;
1731         }
1732 
1733         @DefinedBy(Api.LANGUAGE_MODEL)
1734         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1735             return v.visitArray(this, p);
1736         }
1737     }
1738 
1739     public static class MethodType extends Type implements ExecutableType, LoadableConstant {
1740 
1741         public List<Type> argtypes;
1742         public Type restype;
1743         public List<Type> thrown;
1744 
1745         /** The type annotations on the method receiver.
1746          */
1747         public Type recvtype;
1748 
1749         public MethodType(List<Type> argtypes,
1750                           Type restype,
1751                           List<Type> thrown,
1752                           TypeSymbol methodClass) {
1753             // Presently no way to refer to a method type directly, so
1754             // we cannot put type annotations on it.
1755             super(methodClass, TypeMetadata.EMPTY);
1756             this.argtypes = argtypes;
1757             this.restype = restype;
1758             this.thrown = thrown;
1759         }
1760 
1761         @Override
1762         public MethodType cloneWithMetadata(TypeMetadata md) {
1763             throw new AssertionError("Cannot add metadata to a method type");
1764         }
1765 
1766         @Override
1767         public TypeTag getTag() {
1768             return METHOD;
1769         }
1770 
1771         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1772             return v.visitMethodType(this, s);
1773         }
1774 
1775         /** The Java source which this type represents.
1776          *
1777          *  XXX 06/09/99 iris This isn't correct Java syntax, but it probably
1778          *  should be.
1779          */
1780         @DefinedBy(Api.LANGUAGE_MODEL)
1781         public String toString() {
1782             StringBuilder sb = new StringBuilder();
1783             appendAnnotationsString(sb);
1784             sb.append('(');
1785             sb.append(argtypes);
1786             sb.append(')');
1787             sb.append(restype);
1788             return sb.toString();
1789         }
1790 
1791         @DefinedBy(Api.LANGUAGE_MODEL)
1792         public List<Type>        getParameterTypes() { return argtypes; }
1793         @DefinedBy(Api.LANGUAGE_MODEL)
1794         public Type              getReturnType()     { return restype; }
1795         @DefinedBy(Api.LANGUAGE_MODEL)
1796         public Type              getReceiverType()   {
1797             return (recvtype == null) ? Type.noType : recvtype;
1798         }
1799         @DefinedBy(Api.LANGUAGE_MODEL)
1800         public List<Type>        getThrownTypes()    { return thrown; }
1801 
1802         public boolean isErroneous() {
1803             return
1804                 isErroneous(argtypes) ||
1805                 restype != null && restype.isErroneous();
1806         }
1807 
1808         @Override
1809         public int poolTag() {
1810             return ClassFile.CONSTANT_MethodType;
1811         }
1812 
1813         public boolean contains(Type elem) {
1814             return elem.equalsIgnoreMetadata(this) || contains(argtypes, elem) || restype.contains(elem) || contains(thrown, elem);
1815         }
1816 
1817         public MethodType asMethodType() { return this; }
1818 
1819         public void complete() {
1820             for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
1821                 l.head.complete();
1822             restype.complete();
1823             recvtype.complete();
1824             for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1825                 l.head.complete();
1826         }
1827 
1828         @DefinedBy(Api.LANGUAGE_MODEL)
1829         public List<TypeVar> getTypeVariables() {
1830             return List.nil();
1831         }
1832 
1833         public TypeSymbol asElement() {
1834             return null;
1835         }
1836 
1837         @DefinedBy(Api.LANGUAGE_MODEL)
1838         public TypeKind getKind() {
1839             return TypeKind.EXECUTABLE;
1840         }
1841 
1842         @DefinedBy(Api.LANGUAGE_MODEL)
1843         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1844             return v.visitExecutable(this, p);
1845         }
1846     }
1847 
1848     public static class PackageType extends Type implements NoType {
1849 
1850         PackageType(PackageSymbol tsym) {
1851             // Package types cannot be annotated
1852             super(tsym, TypeMetadata.EMPTY);
1853         }
1854 
1855         @Override
1856         public PackageType cloneWithMetadata(TypeMetadata md) {
1857             throw new AssertionError("Cannot add metadata to a package type");
1858         }
1859 
1860         @Override
1861         public TypeTag getTag() {
1862             return PACKAGE;
1863         }
1864 
1865         @Override
1866         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1867             return v.visitPackageType(this, s);
1868         }
1869 
1870         @DefinedBy(Api.LANGUAGE_MODEL)
1871         public String toString() {
1872             return tsym.getQualifiedName().toString();
1873         }
1874 
1875         @DefinedBy(Api.LANGUAGE_MODEL)
1876         public TypeKind getKind() {
1877             return TypeKind.PACKAGE;
1878         }
1879 
1880         @DefinedBy(Api.LANGUAGE_MODEL)
1881         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1882             return v.visitNoType(this, p);
1883         }
1884     }
1885 
1886     public static class ModuleType extends Type implements NoType {
1887 
1888         ModuleType(ModuleSymbol tsym) {
1889             // Module types cannot be annotated
1890             super(tsym, TypeMetadata.EMPTY);
1891         }
1892 
1893         @Override
1894         public ModuleType cloneWithMetadata(TypeMetadata md) {
1895             throw new AssertionError("Cannot add metadata to a module type");
1896         }
1897 
1898         @Override
1899         public ModuleType annotatedType(List<Attribute.TypeCompound> annos) {
1900             throw new AssertionError("Cannot annotate a module type");
1901         }
1902 
1903         @Override
1904         public TypeTag getTag() {
1905             return TypeTag.MODULE;
1906         }
1907 
1908         @Override
1909         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1910             return v.visitModuleType(this, s);
1911         }
1912 
1913         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1914         public String toString() {
1915             return tsym.getQualifiedName().toString();
1916         }
1917 
1918         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1919         public TypeKind getKind() {
1920             return TypeKind.MODULE;
1921         }
1922 
1923         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1924         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1925             return v.visitNoType(this, p);
1926         }
1927     }
1928 
1929     public static class TypeVar extends Type implements TypeVariable {
1930 
1931         /** The upper bound of this type variable; set from outside.
1932          *  Must be nonempty once it is set.
1933          *  For a bound, `bound' is the bound type itself.
1934          *  Multiple bounds are expressed as a single class type which has the
1935          *  individual bounds as superclass, respectively interfaces.
1936          *  The class type then has as `tsym' a compiler generated class `c',
1937          *  which has a flag COMPOUND and whose owner is the type variable
1938          *  itself. Furthermore, the erasure_field of the class
1939          *  points to the first class or interface bound.
1940          */
1941         private Type _bound = null;
1942 
1943         /** The lower bound of this type variable.
1944          *  TypeVars don't normally have a lower bound, so it is normally set
1945          *  to syms.botType.
1946          *  Subtypes, such as CapturedType, may provide a different value.
1947          */
1948         public Type lower;
1949 
1950         public TypeVar(Name name, Symbol owner, Type lower) {
1951             super(null, TypeMetadata.EMPTY);
1952             Assert.checkNonNull(lower);
1953             tsym = new TypeVariableSymbol(0, name, this, owner);
1954             this.setUpperBound(null);
1955             this.lower = lower;
1956         }
1957 
1958         public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
1959             this(tsym, bound, lower, TypeMetadata.EMPTY);
1960         }
1961 
1962         public TypeVar(TypeSymbol tsym, Type bound, Type lower,
1963                        TypeMetadata metadata) {
1964             super(tsym, metadata);
1965             Assert.checkNonNull(lower);
1966             this.setUpperBound(bound);
1967             this.lower = lower;
1968         }
1969 
1970         @Override
1971         public TypeVar cloneWithMetadata(TypeMetadata md) {
1972             return new TypeVar(tsym, getUpperBound(), lower, md) {
1973                 @Override
1974                 public Type baseType() { return TypeVar.this.baseType(); }
1975 
1976                 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1977                 public Type getUpperBound() { return TypeVar.this.getUpperBound(); }
1978 
1979                 public void setUpperBound(Type bound) { TypeVar.this.setUpperBound(bound); }
1980             };
1981         }
1982 
1983         @Override
1984         public TypeTag getTag() {
1985             return TYPEVAR;
1986         }
1987 
1988         @Override
1989         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1990             return v.visitTypeVar(this, s);
1991         }
1992 
1993         @Override @DefinedBy(Api.LANGUAGE_MODEL)
1994         public Type getUpperBound() { return _bound; }
1995 
1996         public void setUpperBound(Type bound) { this._bound = bound; }
1997 
1998         int rank_field = -1;
1999 
2000         @Override @DefinedBy(Api.LANGUAGE_MODEL)
2001         public Type getLowerBound() {
2002             return lower;
2003         }
2004 
2005         @DefinedBy(Api.LANGUAGE_MODEL)
2006         public TypeKind getKind() {
2007             return TypeKind.TYPEVAR;
2008         }
2009 
2010         public boolean isCaptured() {
2011             return false;
2012         }
2013 
2014         @Override
2015         public boolean isReference() {
2016             return true;
2017         }
2018 
2019         @Override
2020         public boolean isNullOrReference() {
2021             return true;
2022         }
2023 
2024         @Override @DefinedBy(Api.LANGUAGE_MODEL)
2025         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2026             return v.visitTypeVariable(this, p);
2027         }
2028     }
2029 
2030     /** A captured type variable comes from wildcards which can have
2031      *  both upper and lower bound.  CapturedType extends TypeVar with
2032      *  a lower bound.
2033      */
2034     public static class CapturedType extends TypeVar {
2035 
2036         public WildcardType wildcard;
2037 
2038         public CapturedType(Name name,
2039                             Symbol owner,
2040                             Type upper,
2041                             Type lower,
2042                             WildcardType wildcard) {
2043             super(name, owner, lower);
2044             this.lower = Assert.checkNonNull(lower);
2045             this.setUpperBound(upper);
2046             this.wildcard = wildcard;
2047         }
2048 
2049         public CapturedType(TypeSymbol tsym,
2050                             Type bound,
2051                             Type upper,
2052                             Type lower,
2053                             WildcardType wildcard,
2054                             TypeMetadata metadata) {
2055             super(tsym, bound, lower, metadata);
2056             this.wildcard = wildcard;
2057         }
2058 
2059         @Override
2060         public CapturedType cloneWithMetadata(TypeMetadata md) {
2061             return new CapturedType(tsym, getUpperBound(), getUpperBound(), lower, wildcard, md) {
2062                 @Override
2063                 public Type baseType() { return CapturedType.this.baseType(); }
2064 
2065                 @Override @DefinedBy(Api.LANGUAGE_MODEL)
2066                 public Type getUpperBound() { return CapturedType.this.getUpperBound(); }
2067 
2068                 public void setUpperBound(Type bound) { CapturedType.this.setUpperBound(bound); }
2069             };
2070         }
2071 
2072         @Override
2073         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
2074             return v.visitCapturedType(this, s);
2075         }
2076 
2077         @Override
2078         public boolean isCaptured() {
2079             return true;
2080         }
2081 
2082         @Override @DefinedBy(Api.LANGUAGE_MODEL)
2083         public String toString() {
2084             StringBuilder sb = new StringBuilder();
2085             appendAnnotationsString(sb);
2086             sb.append("capture#");
2087             sb.append((hashCode() & 0xFFFFFFFFL) % Printer.PRIME);
2088             sb.append(" of ");
2089             sb.append(wildcard);
2090             return sb.toString();
2091         }
2092     }
2093 
2094     public static abstract class DelegatedType extends Type {
2095         public Type qtype;
2096         public TypeTag tag;
2097 
2098         public DelegatedType(TypeTag tag, Type qtype) {
2099             this(tag, qtype, TypeMetadata.EMPTY);
2100         }
2101 
2102         public DelegatedType(TypeTag tag, Type qtype,
2103                              TypeMetadata metadata) {
2104             super(qtype.tsym, metadata);
2105             this.tag = tag;
2106             this.qtype = qtype;
2107         }
2108 
2109         public TypeTag getTag() { return tag; }
2110         @DefinedBy(Api.LANGUAGE_MODEL)
2111         public String toString() { return qtype.toString(); }
2112         public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
2113         public Type getEnclosingType() { return qtype.getEnclosingType(); }
2114         public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
2115         public Type getReturnType() { return qtype.getReturnType(); }
2116         public Type getReceiverType() { return qtype.getReceiverType(); }
2117         public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
2118         public List<Type> allparams() { return qtype.allparams(); }
2119         public Type getUpperBound() { return qtype.getUpperBound(); }
2120         public boolean isErroneous() { return qtype.isErroneous(); }
2121     }
2122 
2123     /**
2124      * The type of a generic method type. It consists of a method type and
2125      * a list of method type-parameters that are used within the method
2126      * type.
2127      */
2128     public static class ForAll extends DelegatedType implements ExecutableType {
2129         public List<Type> tvars;
2130 
2131         public ForAll(List<Type> tvars, Type qtype) {
2132             super(FORALL, (MethodType)qtype);
2133             this.tvars = tvars;
2134         }
2135 
2136         @Override
2137         public ForAll cloneWithMetadata(TypeMetadata md) {
2138             throw new AssertionError("Cannot add metadata to a forall type");
2139         }
2140 
2141         @Override
2142         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
2143             return v.visitForAll(this, s);
2144         }
2145 
2146         @DefinedBy(Api.LANGUAGE_MODEL)
2147         public String toString() {
2148             StringBuilder sb = new StringBuilder();
2149             appendAnnotationsString(sb);
2150             sb.append('<');
2151             sb.append(tvars);
2152             sb.append('>');
2153             sb.append(qtype);
2154             return sb.toString();
2155         }
2156 
2157         public List<Type> getTypeArguments()   { return tvars; }
2158 
2159         public boolean isErroneous()  {
2160             return qtype.isErroneous();
2161         }
2162 
2163         public boolean contains(Type elem) {
2164             return qtype.contains(elem);
2165         }
2166 
2167         public MethodType asMethodType() {
2168             return (MethodType)qtype;
2169         }
2170 
2171         public void complete() {
2172             for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
2173                 ((TypeVar)l.head).getUpperBound().complete();
2174             }
2175             qtype.complete();
2176         }
2177 
2178         @DefinedBy(Api.LANGUAGE_MODEL)
2179         public List<TypeVar> getTypeVariables() {
2180             return List.convert(TypeVar.class, getTypeArguments());
2181         }
2182 
2183         @DefinedBy(Api.LANGUAGE_MODEL)
2184         public TypeKind getKind() {
2185             return TypeKind.EXECUTABLE;
2186         }
2187 
2188         @DefinedBy(Api.LANGUAGE_MODEL)
2189         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2190             return v.visitExecutable(this, p);
2191         }
2192     }
2193 
2194     /** A class for inference variables, for use during method/diamond type
2195      *  inference. An inference variable has upper/lower bounds and a set
2196      *  of equality constraints. Such bounds are set during subtyping, type-containment,
2197      *  type-equality checks, when the types being tested contain inference variables.
2198      *  A change listener can be attached to an inference variable, to receive notifications
2199      *  whenever the bounds of an inference variable change.
2200      */
2201     public static class UndetVar extends DelegatedType {
2202 
2203         enum Kind {
2204             NORMAL,
2205             CAPTURED,
2206             THROWS;
2207         }
2208 
2209         /** Inference variable change listener. The listener method is called
2210          *  whenever a change to the inference variable's bounds occurs
2211          */
2212         public interface UndetVarListener {
2213             /** called when some inference variable bounds (of given kinds ibs) change */
2214             void varBoundChanged(UndetVar uv, InferenceBound ib, Type bound, boolean update);
2215             /** called when the inferred type is set on some inference variable */
2216             default void varInstantiated(UndetVar uv) { Assert.error(); }
2217         }
2218 
2219         /**
2220          * Inference variable bound kinds
2221          */
2222         public enum InferenceBound {
2223             /** lower bounds */
2224             LOWER {
2225                 public InferenceBound complement() { return UPPER; }
2226             },
2227             /** equality constraints */
2228             EQ {
2229                 public InferenceBound complement() { return EQ; }
2230             },
2231             /** upper bounds */
2232             UPPER {
2233                 public InferenceBound complement() { return LOWER; }
2234             };
2235 
2236             public abstract InferenceBound complement();
2237 
2238             public boolean lessThan(InferenceBound that) {
2239                 if (that == this) {
2240                     return false;
2241                 } else {
2242                     switch (that) {
2243                         case UPPER: return true;
2244                         case LOWER: return false;
2245                         case EQ: return (this != UPPER);
2246                         default:
2247                             Assert.error("Cannot get here!");
2248                             return false;
2249                     }
2250                 }
2251             }
2252         }
2253 
2254         /** list of incorporation actions (used by the incorporation engine). */
2255         public ArrayDeque<IncorporationAction> incorporationActions = new ArrayDeque<>();
2256 
2257         /** inference variable bounds */
2258         protected Map<InferenceBound, List<Type>> bounds;
2259 
2260         /** inference variable's inferred type (set from Infer.java) */
2261         private Type inst = null;
2262 
2263         /** number of declared (upper) bounds */
2264         public int declaredCount;
2265 
2266         /** inference variable's change listener */
2267         public UndetVarListener listener = null;
2268 
2269         Kind kind;
2270 
2271         @Override
2272         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
2273             return v.visitUndetVar(this, s);
2274         }
2275 
2276         public UndetVar(TypeVar origin, UndetVarListener listener, Types types) {
2277             // This is a synthesized internal type, so we cannot annotate it.
2278             super(UNDETVAR, origin);
2279             this.kind = origin.isCaptured() ?
2280                     Kind.CAPTURED :
2281                     Kind.NORMAL;
2282             this.listener = listener;
2283             bounds = new EnumMap<>(InferenceBound.class);
2284             List<Type> declaredBounds = types.getBounds(origin);
2285             declaredCount = declaredBounds.length();
2286             bounds.put(InferenceBound.UPPER, List.nil());
2287             bounds.put(InferenceBound.LOWER, List.nil());
2288             bounds.put(InferenceBound.EQ, List.nil());
2289             for (Type t : declaredBounds.reverse()) {
2290                 //add bound works in reverse order
2291                 addBound(InferenceBound.UPPER, t, types, true);
2292             }
2293             if (origin.isCaptured() && !origin.lower.hasTag(BOT)) {
2294                 //add lower bound if needed
2295                 addBound(InferenceBound.LOWER, origin.lower, types, true);
2296             }
2297         }
2298 
2299         @DefinedBy(Api.LANGUAGE_MODEL)
2300         public String toString() {
2301             StringBuilder sb = new StringBuilder();
2302             appendAnnotationsString(sb);
2303             if (inst == null) {
2304                 sb.append(qtype);
2305                 sb.append('?');
2306             } else {
2307                 sb.append(inst);
2308             }
2309             return sb.toString();
2310         }
2311 
2312         public String debugString() {
2313             String result = "inference var = " + qtype + "\n";
2314             if (inst != null) {
2315                 result += "inst = " + inst + '\n';
2316             }
2317             for (InferenceBound bound: InferenceBound.values()) {
2318                 List<Type> aboundList = bounds.get(bound);
2319                 if (aboundList != null && aboundList.size() > 0) {
2320                     result += bound + " = " + aboundList + '\n';
2321                 }
2322             }
2323             return result;
2324         }
2325 
2326         public void setThrow() {
2327             if (this.kind == Kind.CAPTURED) {
2328                 //invalid state transition
2329                 throw new IllegalStateException();
2330             }
2331             this.kind = Kind.THROWS;
2332         }
2333 
2334         /**
2335          * Returns a new copy of this undet var.
2336          */
2337         public UndetVar dup(Types types) {
2338             UndetVar uv2 = new UndetVar((TypeVar)qtype, listener, types);
2339             dupTo(uv2, types);
2340             return uv2;
2341         }
2342 
2343         /**
2344          * Dumps the contents of this undet var on another undet var.
2345          */
2346         public void dupTo(UndetVar uv2, Types types) {
2347             uv2.listener = null;
2348             uv2.bounds.clear();
2349             for (InferenceBound ib : InferenceBound.values()) {
2350                 uv2.bounds.put(ib, List.nil());
2351                 for (Type t : getBounds(ib)) {
2352                     uv2.addBound(ib, t, types, true);
2353                 }
2354             }
2355             uv2.inst = inst;
2356             uv2.listener = listener;
2357             uv2.incorporationActions = new ArrayDeque<>();
2358             for (IncorporationAction action : incorporationActions) {
2359                 uv2.incorporationActions.add(action.dup(uv2));
2360             }
2361             uv2.kind = kind;
2362         }
2363 
2364         @Override
2365         public UndetVar cloneWithMetadata(TypeMetadata md) {
2366             throw new AssertionError("Cannot add metadata to an UndetVar type");
2367         }
2368 
2369         @Override
2370         public boolean isPartial() {
2371             return true;
2372         }
2373 
2374         @Override
2375         public Type baseType() {
2376             return (inst == null) ? this : inst.baseType();
2377         }
2378 
2379         public Type getInst() {
2380             return inst;
2381         }
2382 
2383         public void setInst(Type inst) {
2384             this.inst = inst;
2385             if (listener != null) {
2386                 listener.varInstantiated(this);
2387             }
2388         }
2389 
2390         /** get all bounds of a given kind */
2391         public List<Type> getBounds(InferenceBound... ibs) {
2392             ListBuffer<Type> buf = new ListBuffer<>();
2393             for (InferenceBound ib : ibs) {
2394                 buf.appendList(bounds.get(ib));
2395             }
2396             return buf.toList();
2397         }
2398 
2399         /** get the list of declared (upper) bounds */
2400         public List<Type> getDeclaredBounds() {
2401             ListBuffer<Type> buf = new ListBuffer<>();
2402             int count = 0;
2403             for (Type b : getBounds(InferenceBound.UPPER)) {
2404                 if (count++ == declaredCount) break;
2405                 buf.append(b);
2406             }
2407             return buf.toList();
2408         }
2409 
2410         /** internal method used to override an undetvar bounds */
2411         public void setBounds(InferenceBound ib, List<Type> newBounds) {
2412             bounds.put(ib, newBounds);
2413         }
2414 
2415         /** add a bound of a given kind - this might trigger listener notification */
2416         public final void addBound(InferenceBound ib, Type bound, Types types) {
2417             // Per JDK-8075793: in pre-8 sources, follow legacy javac behavior
2418             // when capture variables are inferred as bounds: for lower bounds,
2419             // map to the capture variable's upper bound; for upper bounds,
2420             // if the capture variable has a lower bound, map to that type
2421             if (types.mapCapturesToBounds) {
2422                 switch (ib) {
2423                     case LOWER:
2424                         bound = types.cvarUpperBound(bound);
2425                         break;
2426                     case UPPER:
2427                         Type altBound = types.cvarLowerBound(bound);
2428                         if (!altBound.hasTag(TypeTag.BOT)) bound = altBound;
2429                         break;
2430                 }
2431             }
2432             addBound(ib, bound, types, false);
2433         }
2434 
2435         @SuppressWarnings("fallthrough")
2436         private void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
2437             if (kind == Kind.CAPTURED && !update) {
2438                 //Captured inference variables bounds must not be updated during incorporation,
2439                 //except when some inference variable (beta) has been instantiated in the
2440                 //right-hand-side of a 'C<alpha> = capture(C<? extends/super beta>) constraint.
2441                 if (bound.hasTag(UNDETVAR) && !((UndetVar)bound).isCaptured()) {
2442                     //If the new incoming bound is itself a (regular) inference variable,
2443                     //then we are allowed to propagate this inference variable bounds to it.
2444                     ((UndetVar)bound).addBound(ib.complement(), this, types, false);
2445                 }
2446             } else {
2447                 Type bound2 = bound.map(toTypeVarMap).baseType();
2448                 List<Type> prevBounds = bounds.get(ib);
2449                 if (bound == qtype) return;
2450                 for (Type b : prevBounds) {
2451                     //check for redundancy - do not add same bound twice
2452                     if (types.isSameType(b, bound2)) return;
2453                 }
2454                 bounds.put(ib, prevBounds.prepend(bound2));
2455                 notifyBoundChange(ib, bound2, false);
2456             }
2457         }
2458         //where
2459             TypeMapping<Void> toTypeVarMap = new StructuralTypeMapping<Void>() {
2460                 @Override
2461                 public Type visitUndetVar(UndetVar uv, Void _unused) {
2462                     return uv.inst != null ? uv.inst : uv.qtype;
2463                 }
2464             };
2465 
2466         /** replace types in all bounds - this might trigger listener notification */
2467         public void substBounds(List<Type> from, List<Type> to, Types types) {
2468             final ListBuffer<Pair<InferenceBound, Type>>  boundsChanged = new ListBuffer<>();
2469             UndetVarListener prevListener = listener;
2470             try {
2471                 //setup new listener for keeping track of changed bounds
2472                 listener = (uv, ib, t, _ignored) -> {
2473                     Assert.check(uv == UndetVar.this);
2474                     boundsChanged.add(new Pair<>(ib, t));
2475                 };
2476                 for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
2477                     InferenceBound ib = _entry.getKey();
2478                     List<Type> prevBounds = _entry.getValue();
2479                     ListBuffer<Type> newBounds = new ListBuffer<>();
2480                     ListBuffer<Type> deps = new ListBuffer<>();
2481                     //step 1 - re-add bounds that are not dependent on ivars
2482                     for (Type t : prevBounds) {
2483                         if (!t.containsAny(from)) {
2484                             newBounds.append(t);
2485                         } else {
2486                             deps.append(t);
2487                         }
2488                     }
2489                     //step 2 - replace bounds
2490                     bounds.put(ib, newBounds.toList());
2491                     //step 3 - for each dependency, add new replaced bound
2492                     for (Type dep : deps) {
2493                         addBound(ib, types.subst(dep, from, to), types, true);
2494                     }
2495                 }
2496             } finally {
2497                 listener = prevListener;
2498                 for (Pair<InferenceBound, Type> boundUpdate : boundsChanged) {
2499                     notifyBoundChange(boundUpdate.fst, boundUpdate.snd, true);
2500                 }
2501             }
2502         }
2503 
2504         private void notifyBoundChange(InferenceBound ib, Type bound, boolean update) {
2505             if (listener != null) {
2506                 listener.varBoundChanged(this, ib, bound, update);
2507             }
2508         }
2509 
2510         public final boolean isCaptured() {
2511             return kind == Kind.CAPTURED;
2512         }
2513 
2514         public final boolean isThrows() {
2515             return kind == Kind.THROWS;
2516         }
2517     }
2518 
2519     /** Represents NONE.
2520      */
2521     public static class JCNoType extends Type implements NoType {
2522         public JCNoType() {
2523             // Need to use List.nil(), because JCNoType constructor
2524             // gets called in static initializers in Type, where
2525             // noAnnotations is also defined.
2526             super(null, TypeMetadata.EMPTY);
2527         }
2528 
2529         @Override
2530         public JCNoType cloneWithMetadata(TypeMetadata md) {
2531             throw new AssertionError("Cannot add metadata to a JCNoType");
2532         }
2533 
2534         @Override
2535         public TypeTag getTag() {
2536             return NONE;
2537         }
2538 
2539         @Override @DefinedBy(Api.LANGUAGE_MODEL)
2540         public TypeKind getKind() {
2541             return TypeKind.NONE;
2542         }
2543 
2544         @Override @DefinedBy(Api.LANGUAGE_MODEL)
2545         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2546             return v.visitNoType(this, p);
2547         }
2548 
2549         @Override
2550         public boolean isCompound() { return false; }
2551     }
2552 
2553     /** Represents VOID.
2554      */
2555     public static class JCVoidType extends Type implements NoType {
2556 
2557         public JCVoidType() {
2558             // Void cannot be annotated
2559             super(null, TypeMetadata.EMPTY);
2560         }
2561 
2562         @Override
2563         public JCVoidType cloneWithMetadata(TypeMetadata md) {
2564             throw new AssertionError("Cannot add metadata to a void type");
2565         }
2566 
2567         @Override
2568         public TypeTag getTag() {
2569             return VOID;
2570         }
2571 
2572         @Override @DefinedBy(Api.LANGUAGE_MODEL)
2573         public TypeKind getKind() {
2574             return TypeKind.VOID;
2575         }
2576 
2577         @Override
2578         public boolean isCompound() { return false; }
2579 
2580         @Override @DefinedBy(Api.LANGUAGE_MODEL)
2581         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2582             return v.visitNoType(this, p);
2583         }
2584 
2585         @Override
2586         public boolean isPrimitiveOrVoid() {
2587             return true;
2588         }
2589     }
2590 
2591     static class BottomType extends Type implements NullType {
2592         public BottomType() {
2593             // Bottom is a synthesized internal type, so it cannot be annotated
2594             super(null, TypeMetadata.EMPTY);
2595         }
2596 
2597         @Override
2598         public BottomType cloneWithMetadata(TypeMetadata md) {
2599             throw new AssertionError("Cannot add metadata to a bottom type");
2600         }
2601 
2602         @Override
2603         public TypeTag getTag() {
2604             return BOT;
2605         }
2606 
2607         @Override @DefinedBy(Api.LANGUAGE_MODEL)
2608         public TypeKind getKind() {
2609             return TypeKind.NULL;
2610         }
2611 
2612         @Override
2613         public boolean isCompound() { return false; }
2614 
2615         @Override @DefinedBy(Api.LANGUAGE_MODEL)
2616         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2617             return v.visitNull(this, p);
2618         }
2619 
2620         @Override
2621         public Type constType(Object value) {
2622             return this;
2623         }
2624 
2625         @Override
2626         public String stringValue() {
2627             return "null";
2628         }
2629 
2630         @Override
2631         public boolean isNullOrReference() {
2632             return true;
2633         }
2634 
2635     }
2636 
2637     public static class ErrorType extends ClassType
2638             implements javax.lang.model.type.ErrorType {
2639 
2640         private Type originalType = null;
2641 
2642         public ErrorType(ClassSymbol c, Type originalType) {
2643             this(originalType, c);
2644             c.type = this;
2645             c.kind = ERR;
2646             c.members_field = new Scope.ErrorScope(c);
2647         }
2648 
2649         public ErrorType(Type originalType, TypeSymbol tsym) {
2650             super(noType, List.nil(), tsym, TypeMetadata.EMPTY, Flavor.E_Typeof_X);
2651             this.originalType = (originalType == null ? noType : originalType);
2652         }
2653 
2654         private ErrorType(Type originalType, TypeSymbol tsym,
2655                           TypeMetadata metadata, Flavor flavor) {
2656             super(noType, List.nil(), null, metadata, flavor);
2657             this.tsym = tsym;
2658             this.originalType = (originalType == null ? noType : originalType);
2659         }
2660 
2661         @Override
2662         public ErrorType cloneWithMetadata(TypeMetadata md) {
2663             return new ErrorType(originalType, tsym, md, getFlavor()) {
2664                 @Override
2665                 public Type baseType() { return ErrorType.this.baseType(); }
2666             };
2667         }
2668 
2669         @Override
2670         public TypeTag getTag() {
2671             return ERROR;
2672         }
2673 
2674         @Override
2675         public boolean isPartial() {
2676             return true;
2677         }
2678 
2679         @Override
2680         public boolean isReference() {
2681             return true;
2682         }
2683 
2684         @Override
2685         public boolean isNullOrReference() {
2686             return true;
2687         }
2688 
2689         public ErrorType(Name name, TypeSymbol container, Type originalType) {
2690             this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
2691         }
2692 
2693         @Override
2694         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
2695             return v.visitErrorType(this, s);
2696         }
2697 
2698         public Type constType(Object constValue) { return this; }
2699         @DefinedBy(Api.LANGUAGE_MODEL)
2700         public Type getEnclosingType()           { return Type.noType; }
2701         public Type getReturnType()              { return this; }
2702         public Type asSub(Symbol sym)            { return this; }
2703 
2704         public boolean isGenType(Type t)         { return true; }
2705         public boolean isErroneous()             { return true; }
2706         public boolean isCompound()              { return false; }
2707         public boolean isInterface()             { return false; }
2708 
2709         public List<Type> allparams()            { return List.nil(); }
2710         @DefinedBy(Api.LANGUAGE_MODEL)
2711         public List<Type> getTypeArguments()     { return List.nil(); }
2712 
2713         @DefinedBy(Api.LANGUAGE_MODEL)
2714         public TypeKind getKind() {
2715             return TypeKind.ERROR;
2716         }
2717 
2718         public Type getOriginalType() {
2719             return originalType;
2720         }
2721 
2722         @DefinedBy(Api.LANGUAGE_MODEL)
2723         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2724             return v.visitError(this, p);
2725         }
2726     }
2727 
2728     public static class UnknownType extends Type {
2729 
2730         public UnknownType() {
2731             // Unknown is a synthesized internal type, so it cannot be
2732             // annotated.
2733             super(null, TypeMetadata.EMPTY);
2734         }
2735 
2736         @Override
2737         public UnknownType cloneWithMetadata(TypeMetadata md) {
2738             throw new AssertionError("Cannot add metadata to an unknown type");
2739         }
2740 
2741         @Override
2742         public TypeTag getTag() {
2743             return UNKNOWN;
2744         }
2745 
2746         @Override @DefinedBy(Api.LANGUAGE_MODEL)
2747         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2748             return v.visitUnknown(this, p);
2749         }
2750 
2751         @Override
2752         public boolean isPartial() {
2753             return true;
2754         }
2755     }
2756 
2757     /**
2758      * A visitor for types.  A visitor is used to implement operations
2759      * (or relations) on types.  Most common operations on types are
2760      * binary relations and this interface is designed for binary
2761      * relations, that is, operations of the form
2762      * Type&nbsp;&times;&nbsp;S&nbsp;&rarr;&nbsp;R.
2763      * <!-- In plain text: Type x S -> R -->
2764      *
2765      * @param <R> the return type of the operation implemented by this
2766      * visitor; use Void if no return type is needed.
2767      * @param <S> the type of the second argument (the first being the
2768      * type itself) of the operation implemented by this visitor; use
2769      * Void if a second argument is not needed.
2770      */
2771     public interface Visitor<R,S> {
2772         R visitClassType(ClassType t, S s);
2773         R visitWildcardType(WildcardType t, S s);
2774         R visitArrayType(ArrayType t, S s);
2775         R visitMethodType(MethodType t, S s);
2776         R visitPackageType(PackageType t, S s);
2777         R visitModuleType(ModuleType t, S s);
2778         R visitTypeVar(TypeVar t, S s);
2779         R visitCapturedType(CapturedType t, S s);
2780         R visitForAll(ForAll t, S s);
2781         R visitUndetVar(UndetVar t, S s);
2782         R visitErrorType(ErrorType t, S s);
2783         R visitType(Type t, S s);
2784     }
2785 }