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