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