1 /*
   2  * Copyright (c) 1999, 2014, 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.Collections;
  30 import java.util.EnumMap;
  31 import java.util.EnumSet;
  32 import java.util.Map;
  33 import java.util.Set;
  34 
  35 import javax.lang.model.type.*;
  36 
  37 import com.sun.tools.javac.code.Symbol.*;
  38 import com.sun.tools.javac.util.*;
  39 import static com.sun.tools.javac.code.BoundKind.*;
  40 import static com.sun.tools.javac.code.Flags.*;
  41 import static com.sun.tools.javac.code.Kinds.*;
  42 import static com.sun.tools.javac.code.TypeTag.*;
  43 
  44 /** This class represents Java types. The class itself defines the behavior of
  45  *  the following types:
  46  *  <pre>
  47  *  base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
  48  *  type `void' (tag: VOID),
  49  *  the bottom type (tag: BOT),
  50  *  the missing type (tag: NONE).
  51  *  </pre>
  52  *  <p>The behavior of the following types is defined in subclasses, which are
  53  *  all static inner classes of this class:
  54  *  <pre>
  55  *  class types (tag: CLASS, class: ClassType),
  56  *  array types (tag: ARRAY, class: ArrayType),
  57  *  method types (tag: METHOD, class: MethodType),
  58  *  package types (tag: PACKAGE, class: PackageType),
  59  *  type variables (tag: TYPEVAR, class: TypeVar),
  60  *  type arguments (tag: WILDCARD, class: WildcardType),
  61  *  generic method types (tag: FORALL, class: ForAll),
  62  *  the error type (tag: ERROR, class: ErrorType).
  63  *  </pre>
  64  *
  65  *  <p><b>This is NOT part of any supported API.
  66  *  If you write code that depends on this, you do so at your own risk.
  67  *  This code and its internal interfaces are subject to change or
  68  *  deletion without notice.</b>
  69  *
  70  *  @see TypeTag
  71  */
  72 public abstract class Type extends AnnoConstruct implements TypeMirror {
  73 
  74     /** Constant type: no type at all. */
  75     public static final JCNoType noType = new JCNoType() {
  76         @Override
  77         public String toString() {
  78             return "none";
  79         }
  80     };
  81 
  82     /** Constant type: special type to be used during recovery of deferred expressions. */
  83     public static final JCNoType recoveryType = new JCNoType(){
  84         @Override
  85         public String toString() {
  86             return "recovery";
  87         }
  88     };
  89 
  90     /** Constant type: special type to be used for marking stuck trees. */
  91     public static final JCNoType stuckType = new JCNoType() {
  92         @Override
  93         public String toString() {
  94             return "stuck";
  95         }
  96     };
  97 
  98     /** If this switch is turned on, the names of type variables
  99      *  and anonymous classes are printed with hashcodes appended.
 100      */
 101     public static boolean moreInfo = false;
 102 
 103     /** The defining class / interface / package / type variable.
 104      */
 105     public TypeSymbol tsym;
 106 
 107     /**
 108      * Checks if the current type tag is equal to the given tag.
 109      * @return true if tag is equal to the current type tag.
 110      */
 111     public boolean hasTag(TypeTag tag) {
 112         return tag == getTag();
 113     }
 114 
 115     /**
 116      * Returns the current type tag.
 117      * @return the value of the current type tag.
 118      */
 119     public abstract TypeTag getTag();
 120 
 121     public boolean isNumeric() {
 122         return false;
 123     }
 124 
 125     public boolean isPrimitive() {
 126         return false;
 127     }
 128 
 129     public boolean isPrimitiveOrVoid() {
 130         return false;
 131     }
 132 
 133     public boolean isReference() {
 134         return false;
 135     }
 136 
 137     public boolean isNullOrReference() {
 138         return false;
 139     }
 140 
 141     public boolean isPartial() {
 142         return false;
 143     }
 144 
 145     /**
 146      * The constant value of this type, null if this type does not
 147      * have a constant value attribute. Only primitive types and
 148      * strings (ClassType) can have a constant value attribute.
 149      * @return the constant value attribute of this type
 150      */
 151     public Object constValue() {
 152         return null;
 153     }
 154 
 155     /** Is this a constant type whose value is false?
 156      */
 157     public boolean isFalse() {
 158         return false;
 159     }
 160 
 161     /** Is this a constant type whose value is true?
 162      */
 163     public boolean isTrue() {
 164         return false;
 165     }
 166 
 167     /**
 168      * Get the representation of this type used for modelling purposes.
 169      * By default, this is itself. For ErrorType, a different value
 170      * may be provided.
 171      */
 172     public Type getModelType() {
 173         return this;
 174     }
 175 
 176     public static List<Type> getModelTypes(List<Type> ts) {
 177         ListBuffer<Type> lb = new ListBuffer<>();
 178         for (Type t: ts)
 179             lb.append(t.getModelType());
 180         return lb.toList();
 181     }
 182 
 183     /**For ErrorType, returns the original type, otherwise returns the type itself.
 184      */
 185     public Type getOriginalType() {
 186         return this;
 187     }
 188 
 189     public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
 190 
 191     /** Define a type given its tag and type symbol
 192      */
 193     public Type(TypeSymbol tsym) {
 194         this.tsym = tsym;
 195     }
 196 
 197     /** An abstract class for mappings from types to types
 198      */
 199     public static abstract class Mapping {
 200         private String name;
 201         public Mapping(String name) {
 202             this.name = name;
 203         }
 204         public abstract Type apply(Type t);
 205         public String toString() {
 206             return name;
 207         }
 208     }
 209 
 210     /** map a type function over all immediate descendants of this type
 211      */
 212     public Type map(Mapping f) {
 213         return this;
 214     }
 215 
 216     /** map a type function over a list of types
 217      */
 218     public static List<Type> map(List<Type> ts, Mapping f) {
 219         if (ts.nonEmpty()) {
 220             List<Type> tail1 = map(ts.tail, f);
 221             Type t = f.apply(ts.head);
 222             if (tail1 != ts.tail || t != ts.head)
 223                 return tail1.prepend(t);
 224         }
 225         return ts;
 226     }
 227 
 228     /** Define a constant type, of the same kind as this type
 229      *  and with given constant value
 230      */
 231     public Type constType(Object constValue) {
 232         throw new AssertionError();
 233     }
 234 
 235     /**
 236      * If this is a constant type, return its underlying type.
 237      * Otherwise, return the type itself.
 238      */
 239     public Type baseType() {
 240         return this;
 241     }
 242 
 243     public Type annotatedType(List<Attribute.TypeCompound> annos) {
 244         return new AnnotatedType(annos, this);
 245     }
 246 
 247     public boolean isAnnotated() {
 248         return false;
 249     }
 250 
 251     /**
 252      * If this is an annotated type, return the underlying type.
 253      * Otherwise, return the type itself.
 254      */
 255     public Type unannotatedType() {
 256         return this;
 257     }
 258 
 259     @Override
 260     public List<Attribute.TypeCompound> getAnnotationMirrors() {
 261         return List.nil();
 262     }
 263 
 264 
 265     @Override
 266     public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
 267         return null;
 268     }
 269 
 270 
 271     @Override
 272     public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
 273         @SuppressWarnings("unchecked")
 274         A[] tmp = (A[]) java.lang.reflect.Array.newInstance(annotationType, 0);
 275         return tmp;
 276     }
 277 
 278     /** Return the base types of a list of types.
 279      */
 280     public static List<Type> baseTypes(List<Type> ts) {
 281         if (ts.nonEmpty()) {
 282             Type t = ts.head.baseType();
 283             List<Type> baseTypes = baseTypes(ts.tail);
 284             if (t != ts.head || baseTypes != ts.tail)
 285                 return baseTypes.prepend(t);
 286         }
 287         return ts;
 288     }
 289 
 290     /** The Java source which this type represents.
 291      */
 292     public String toString() {
 293         String s = (tsym == null || tsym.name == null)
 294             ? "<none>"
 295             : tsym.name.toString();
 296         if (moreInfo && hasTag(TYPEVAR)) {
 297             s = s + hashCode();
 298         }
 299         return s;
 300     }
 301 
 302     /**
 303      * The Java source which this type list represents.  A List is
 304      * represented as a comma-spearated listing of the elements in
 305      * that list.
 306      */
 307     public static String toString(List<Type> ts) {
 308         if (ts.isEmpty()) {
 309             return "";
 310         } else {
 311             StringBuilder buf = new StringBuilder();
 312             buf.append(ts.head.toString());
 313             for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail)
 314                 buf.append(",").append(l.head.toString());
 315             return buf.toString();
 316         }
 317     }
 318 
 319     /**
 320      * The constant value of this type, converted to String
 321      */
 322     public String stringValue() {
 323         Object cv = Assert.checkNonNull(constValue());
 324         return cv.toString();
 325     }
 326 
 327     /**
 328      * This method is analogous to isSameType, but weaker, since we
 329      * never complete classes. Where isSameType would complete a
 330      * class, equals assumes that the two types are different.
 331      */
 332     @Override
 333     public boolean equals(Object t) {
 334         return super.equals(t);
 335     }
 336 
 337     @Override
 338     public int hashCode() {
 339         return super.hashCode();
 340     }
 341 
 342     public String argtypes(boolean varargs) {
 343         List<Type> args = getParameterTypes();
 344         if (!varargs) return args.toString();
 345         StringBuilder buf = new StringBuilder();
 346         while (args.tail.nonEmpty()) {
 347             buf.append(args.head);
 348             args = args.tail;
 349             buf.append(',');
 350         }
 351         if (args.head.unannotatedType().hasTag(ARRAY)) {
 352             buf.append(((ArrayType)args.head.unannotatedType()).elemtype);
 353             if (args.head.getAnnotationMirrors().nonEmpty()) {
 354                 buf.append(args.head.getAnnotationMirrors());
 355             }
 356             buf.append("...");
 357         } else {
 358             buf.append(args.head);
 359         }
 360         return buf.toString();
 361     }
 362 
 363     /** Access methods.
 364      */
 365     public List<Type>        getTypeArguments()  { return List.nil(); }
 366     public Type              getEnclosingType()  { return null; }
 367     public List<Type>        getParameterTypes() { return List.nil(); }
 368     public Type              getReturnType()     { return null; }
 369     public Type              getReceiverType()   { return null; }
 370     public List<Type>        getThrownTypes()    { return List.nil(); }
 371     public Type              getUpperBound()     { return null; }
 372     public Type              getLowerBound()     { return null; }
 373 
 374     /** Navigation methods, these will work for classes, type variables,
 375      *  foralls, but will return null for arrays and methods.
 376      */
 377 
 378    /** Return all parameters of this type and all its outer types in order
 379     *  outer (first) to inner (last).
 380     */
 381     public List<Type> allparams() { return List.nil(); }
 382 
 383     /** Does this type contain "error" elements?
 384      */
 385     public boolean isErroneous() {
 386         return false;
 387     }
 388 
 389     public static boolean isErroneous(List<Type> ts) {
 390         for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
 391             if (l.head.isErroneous()) return true;
 392         return false;
 393     }
 394 
 395     /** Is this type parameterized?
 396      *  A class type is parameterized if it has some parameters.
 397      *  An array type is parameterized if its element type is parameterized.
 398      *  All other types are not parameterized.
 399      */
 400     public boolean isParameterized() {
 401         return false;
 402     }
 403 
 404     /** Is this type a raw type?
 405      *  A class type is a raw type if it misses some of its parameters.
 406      *  An array type is a raw type if its element type is raw.
 407      *  All other types are not raw.
 408      *  Type validation will ensure that the only raw types
 409      *  in a program are types that miss all their type variables.
 410      */
 411     public boolean isRaw() {
 412         return false;
 413     }
 414 
 415     public boolean isCompound() {
 416         return tsym.completer == null
 417             // Compound types can't have a completer.  Calling
 418             // flags() will complete the symbol causing the
 419             // compiler to load classes unnecessarily.  This led
 420             // to regression 6180021.
 421             && (tsym.flags() & COMPOUND) != 0;
 422     }
 423 
 424     public boolean isInterface() {
 425         return (tsym.flags() & INTERFACE) != 0;
 426     }
 427 
 428     public boolean isFinal() {
 429         return (tsym.flags() & FINAL) != 0;
 430     }
 431 
 432     /**
 433      * Does this type contain occurrences of type t?
 434      */
 435     public boolean contains(Type t) {
 436         return t == this;
 437     }
 438 
 439     public static boolean contains(List<Type> ts, Type t) {
 440         for (List<Type> l = ts;
 441              l.tail != null /*inlined: l.nonEmpty()*/;
 442              l = l.tail)
 443             if (l.head.contains(t)) return true;
 444         return false;
 445     }
 446 
 447     /** Does this type contain an occurrence of some type in 'ts'?
 448      */
 449     public boolean containsAny(List<Type> ts) {
 450         for (Type t : ts)
 451             if (this.contains(t)) return true;
 452         return false;
 453     }
 454 
 455     public static boolean containsAny(List<Type> ts1, List<Type> ts2) {
 456         for (Type t : ts1)
 457             if (t.containsAny(ts2)) return true;
 458         return false;
 459     }
 460 
 461     public static List<Type> filter(List<Type> ts, Filter<Type> tf) {
 462         ListBuffer<Type> buf = new ListBuffer<>();
 463         for (Type t : ts) {
 464             if (tf.accepts(t)) {
 465                 buf.append(t);
 466             }
 467         }
 468         return buf.toList();
 469     }
 470 
 471     public boolean isSuperBound() { return false; }
 472     public boolean isExtendsBound() { return false; }
 473     public boolean isUnbound() { return false; }
 474     public Type withTypeVar(Type t) { return this; }
 475 
 476     /** The underlying method type of this type.
 477      */
 478     public MethodType asMethodType() { throw new AssertionError(); }
 479 
 480     /** Complete loading all classes in this type.
 481      */
 482     public void complete() {}
 483 
 484     public TypeSymbol asElement() {
 485         return tsym;
 486     }
 487 
 488     @Override
 489     public TypeKind getKind() {
 490         return TypeKind.OTHER;
 491     }
 492 
 493     @Override
 494     public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 495         throw new AssertionError();
 496     }
 497 
 498     public static class JCPrimitiveType extends Type
 499             implements javax.lang.model.type.PrimitiveType {
 500 
 501         TypeTag tag;
 502 
 503         public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
 504             super(tsym);
 505             this.tag = tag;
 506             Assert.check(tag.isPrimitive);
 507         }
 508 
 509         @Override
 510         public boolean isNumeric() {
 511             return tag != BOOLEAN;
 512         }
 513 
 514         @Override
 515         public boolean isPrimitive() {
 516             return true;
 517         }
 518 
 519         @Override
 520         public TypeTag getTag() {
 521             return tag;
 522         }
 523 
 524         @Override
 525         public boolean isPrimitiveOrVoid() {
 526             return true;
 527         }
 528 
 529         /** Define a constant type, of the same kind as this type
 530          *  and with given constant value
 531          */
 532         @Override
 533         public Type constType(Object constValue) {
 534             final Object value = constValue;
 535             return new JCPrimitiveType(tag, tsym) {
 536                     @Override
 537                     public Object constValue() {
 538                         return value;
 539                     }
 540                     @Override
 541                     public Type baseType() {
 542                         return tsym.type;
 543                     }
 544                 };
 545         }
 546 
 547         /**
 548          * The constant value of this type, converted to String
 549          */
 550         @Override
 551         public String stringValue() {
 552             Object cv = Assert.checkNonNull(constValue());
 553             if (tag == BOOLEAN) {
 554                 return ((Integer) cv).intValue() == 0 ? "false" : "true";
 555             }
 556             else if (tag == CHAR) {
 557                 return String.valueOf((char) ((Integer) cv).intValue());
 558             }
 559             else {
 560                 return cv.toString();
 561             }
 562         }
 563 
 564         /** Is this a constant type whose value is false?
 565          */
 566         @Override
 567         public boolean isFalse() {
 568             return
 569                 tag == BOOLEAN &&
 570                 constValue() != null &&
 571                 ((Integer)constValue()).intValue() == 0;
 572         }
 573 
 574         /** Is this a constant type whose value is true?
 575          */
 576         @Override
 577         public boolean isTrue() {
 578             return
 579                 tag == BOOLEAN &&
 580                 constValue() != null &&
 581                 ((Integer)constValue()).intValue() != 0;
 582         }
 583 
 584         @Override
 585         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 586             return v.visitPrimitive(this, p);
 587         }
 588 
 589         @Override
 590         public TypeKind getKind() {
 591             switch (tag) {
 592                 case BYTE:      return TypeKind.BYTE;
 593                 case CHAR:      return TypeKind.CHAR;
 594                 case SHORT:     return TypeKind.SHORT;
 595                 case INT:       return TypeKind.INT;
 596                 case LONG:      return TypeKind.LONG;
 597                 case FLOAT:     return TypeKind.FLOAT;
 598                 case DOUBLE:    return TypeKind.DOUBLE;
 599                 case BOOLEAN:   return TypeKind.BOOLEAN;
 600             }
 601             throw new AssertionError();
 602         }
 603 
 604     }
 605 
 606     public static class WildcardType extends Type
 607             implements javax.lang.model.type.WildcardType {
 608 
 609         public Type type;
 610         public BoundKind kind;
 611         public TypeVar bound;
 612 
 613         @Override
 614         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
 615             return v.visitWildcardType(this, s);
 616         }
 617 
 618         public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
 619             super(tsym);
 620             this.type = Assert.checkNonNull(type);
 621             this.kind = kind;
 622         }
 623         public WildcardType(WildcardType t, TypeVar bound) {
 624             this(t.type, t.kind, t.tsym, bound);
 625         }
 626 
 627         public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, TypeVar bound) {
 628             this(type, kind, tsym);
 629             this.bound = bound;
 630         }
 631 
 632         @Override
 633         public TypeTag getTag() {
 634             return WILDCARD;
 635         }
 636 
 637         @Override
 638         public boolean contains(Type t) {
 639             return kind != UNBOUND && type.contains(t);
 640         }
 641 
 642         public boolean isSuperBound() {
 643             return kind == SUPER ||
 644                 kind == UNBOUND;
 645         }
 646         public boolean isExtendsBound() {
 647             return kind == EXTENDS ||
 648                 kind == UNBOUND;
 649         }
 650         public boolean isUnbound() {
 651             return kind == UNBOUND;
 652         }
 653 
 654         @Override
 655         public boolean isReference() {
 656             return true;
 657         }
 658 
 659         @Override
 660         public boolean isNullOrReference() {
 661             return true;
 662         }
 663 
 664         @Override
 665         public Type withTypeVar(Type t) {
 666             //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
 667             if (bound == t)
 668                 return this;
 669             bound = (TypeVar)t;
 670             return this;
 671         }
 672 
 673         boolean isPrintingBound = false;
 674         public String toString() {
 675             StringBuilder s = new StringBuilder();
 676             s.append(kind.toString());
 677             if (kind != UNBOUND)
 678                 s.append(type);
 679             if (moreInfo && bound != null && !isPrintingBound)
 680                 try {
 681                     isPrintingBound = true;
 682                     s.append("{:").append(bound.bound).append(":}");
 683                 } finally {
 684                     isPrintingBound = false;
 685                 }
 686             return s.toString();
 687         }
 688 
 689         public Type map(Mapping f) {
 690             //- System.err.println("   (" + this + ").map(" + f + ")");//DEBUG
 691             Type t = type;
 692             if (t != null)
 693                 t = f.apply(t);
 694             if (t == type)
 695                 return this;
 696             else
 697                 return new WildcardType(t, kind, tsym, bound);
 698         }
 699 
 700         public Type getExtendsBound() {
 701             if (kind == EXTENDS)
 702                 return type;
 703             else
 704                 return null;
 705         }
 706 
 707         public Type getSuperBound() {
 708             if (kind == SUPER)
 709                 return type;
 710             else
 711                 return null;
 712         }
 713 
 714         public TypeKind getKind() {
 715             return TypeKind.WILDCARD;
 716         }
 717 
 718         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 719             return v.visitWildcard(this, p);
 720         }
 721     }
 722 
 723     public static class ClassType extends Type implements DeclaredType {
 724 
 725         /** The enclosing type of this type. If this is the type of an inner
 726          *  class, outer_field refers to the type of its enclosing
 727          *  instance class, in all other cases it refers to noType.
 728          */
 729         private Type outer_field;
 730 
 731         /** The type parameters of this type (to be set once class is loaded).
 732          */
 733         public List<Type> typarams_field;
 734 
 735         /** A cache variable for the type parameters of this type,
 736          *  appended to all parameters of its enclosing class.
 737          *  @see #allparams
 738          */
 739         public List<Type> allparams_field;
 740 
 741         /** The supertype of this class (to be set once class is loaded).
 742          */
 743         public Type supertype_field;
 744 
 745         /** The interfaces of this class (to be set once class is loaded).
 746          */
 747         public List<Type> interfaces_field;
 748 
 749         /** All the interfaces of this class, including missing ones.
 750          */
 751         public List<Type> all_interfaces_field;
 752 
 753         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
 754             super(tsym);
 755             this.outer_field = outer;
 756             this.typarams_field = typarams;
 757             this.allparams_field = null;
 758             this.supertype_field = null;
 759             this.interfaces_field = null;
 760             /*
 761             // this can happen during error recovery
 762             assert
 763                 outer.isParameterized() ?
 764                 typarams.length() == tsym.type.typarams().length() :
 765                 outer.isRaw() ?
 766                 typarams.length() == 0 :
 767                 true;
 768             */
 769         }
 770 
 771         @Override
 772         public TypeTag getTag() {
 773             return CLASS;
 774         }
 775 
 776         @Override
 777         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
 778             return v.visitClassType(this, s);
 779         }
 780 
 781         public Type constType(Object constValue) {
 782             final Object value = constValue;
 783             return new ClassType(getEnclosingType(), typarams_field, tsym) {
 784                     @Override
 785                     public Object constValue() {
 786                         return value;
 787                     }
 788                     @Override
 789                     public Type baseType() {
 790                         return tsym.type;
 791                     }
 792                 };
 793         }
 794 
 795         /** The Java source which this type represents.
 796          */
 797         public String toString() {
 798             StringBuilder buf = new StringBuilder();
 799             if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
 800                 buf.append(getEnclosingType().toString());
 801                 buf.append(".");
 802                 buf.append(className(tsym, false));
 803             } else {
 804                 buf.append(className(tsym, true));
 805             }
 806             if (getTypeArguments().nonEmpty()) {
 807                 buf.append('<');
 808                 buf.append(getTypeArguments().toString());
 809                 buf.append(">");
 810             }
 811             return buf.toString();
 812         }
 813 //where
 814             private String className(Symbol sym, boolean longform) {
 815                 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
 816                     StringBuilder s = new StringBuilder(supertype_field.toString());
 817                     for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
 818                         s.append("&");
 819                         s.append(is.head.toString());
 820                     }
 821                     return s.toString();
 822                 } else if (sym.name.isEmpty()) {
 823                     String s;
 824                     ClassType norm = (ClassType) tsym.type.unannotatedType();
 825                     if (norm == null) {
 826                         s = Log.getLocalizedString("anonymous.class", (Object)null);
 827                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
 828                         s = Log.getLocalizedString("anonymous.class",
 829                                                    norm.interfaces_field.head);
 830                     } else {
 831                         s = Log.getLocalizedString("anonymous.class",
 832                                                    norm.supertype_field);
 833                     }
 834                     if (moreInfo)
 835                         s += String.valueOf(sym.hashCode());
 836                     return s;
 837                 } else if (longform) {
 838                     return sym.getQualifiedName().toString();
 839                 } else {
 840                     return sym.name.toString();
 841                 }
 842             }
 843 
 844         public List<Type> getTypeArguments() {
 845             if (typarams_field == null) {
 846                 complete();
 847                 if (typarams_field == null)
 848                     typarams_field = List.nil();
 849             }
 850             return typarams_field;
 851         }
 852 
 853         public boolean hasErasedSupertypes() {
 854             return isRaw();
 855         }
 856 
 857         public Type getEnclosingType() {
 858             return outer_field;
 859         }
 860 
 861         public void setEnclosingType(Type outer) {
 862             outer_field = outer;
 863         }
 864 
 865         public List<Type> allparams() {
 866             if (allparams_field == null) {
 867                 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
 868             }
 869             return allparams_field;
 870         }
 871 
 872         public boolean isErroneous() {
 873             return
 874                 getEnclosingType().isErroneous() ||
 875                 isErroneous(getTypeArguments()) ||
 876                 this != tsym.type.unannotatedType() && tsym.type.isErroneous();
 877         }
 878 
 879         public boolean isParameterized() {
 880             return allparams().tail != null;
 881             // optimization, was: allparams().nonEmpty();
 882         }
 883 
 884         @Override
 885         public boolean isReference() {
 886             return true;
 887         }
 888 
 889         @Override
 890         public boolean isNullOrReference() {
 891             return true;
 892         }
 893 
 894         /** A cache for the rank. */
 895         int rank_field = -1;
 896 
 897         /** A class type is raw if it misses some
 898          *  of its type parameter sections.
 899          *  After validation, this is equivalent to:
 900          *  {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
 901          */
 902         public boolean isRaw() {
 903             return
 904                 this != tsym.type && // necessary, but not sufficient condition
 905                 tsym.type.allparams().nonEmpty() &&
 906                 allparams().isEmpty();
 907         }
 908 
 909         public Type map(Mapping f) {
 910             Type outer = getEnclosingType();
 911             Type outer1 = f.apply(outer);
 912             List<Type> typarams = getTypeArguments();
 913             List<Type> typarams1 = map(typarams, f);
 914             if (outer1 == outer && typarams1 == typarams) return this;
 915             else return new ClassType(outer1, typarams1, tsym);
 916         }
 917 
 918         public boolean contains(Type elem) {
 919             return
 920                 elem == this
 921                 || (isParameterized()
 922                     && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem)))
 923                 || (isCompound()
 924                     && (supertype_field.contains(elem) || contains(interfaces_field, elem)));
 925         }
 926 
 927         public void complete() {
 928             if (tsym.completer != null) tsym.complete();
 929         }
 930 
 931         public TypeKind getKind() {
 932             return TypeKind.DECLARED;
 933         }
 934 
 935         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 936             return v.visitDeclared(this, p);
 937         }
 938     }
 939 
 940     public static class ErasedClassType extends ClassType {
 941         public ErasedClassType(Type outer, TypeSymbol tsym) {
 942             super(outer, List.<Type>nil(), tsym);
 943         }
 944 
 945         @Override
 946         public boolean hasErasedSupertypes() {
 947             return true;
 948         }
 949     }
 950 
 951     // a clone of a ClassType that knows about the alternatives of a union type.
 952     public static class UnionClassType extends ClassType implements UnionType {
 953         final List<? extends Type> alternatives_field;
 954 
 955         public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
 956             super(ct.outer_field, ct.typarams_field, ct.tsym);
 957             allparams_field = ct.allparams_field;
 958             supertype_field = ct.supertype_field;
 959             interfaces_field = ct.interfaces_field;
 960             all_interfaces_field = ct.interfaces_field;
 961             alternatives_field = alternatives;
 962         }
 963 
 964         public Type getLub() {
 965             return tsym.type;
 966         }
 967 
 968         public java.util.List<? extends TypeMirror> getAlternatives() {
 969             return Collections.unmodifiableList(alternatives_field);
 970         }
 971 
 972         @Override
 973         public TypeKind getKind() {
 974             return TypeKind.UNION;
 975         }
 976 
 977         @Override
 978         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 979             return v.visitUnion(this, p);
 980         }
 981     }
 982 
 983     // a clone of a ClassType that knows about the bounds of an intersection type.
 984     public static class IntersectionClassType extends ClassType implements IntersectionType {
 985 
 986         public boolean allInterfaces;
 987 
 988         public IntersectionClassType(List<Type> bounds, ClassSymbol csym, boolean allInterfaces) {
 989             super(Type.noType, List.<Type>nil(), csym);
 990             this.allInterfaces = allInterfaces;
 991             Assert.check((csym.flags() & COMPOUND) != 0);
 992             supertype_field = bounds.head;
 993             interfaces_field = bounds.tail;
 994             Assert.check(supertype_field.tsym.completer != null ||
 995                     !supertype_field.isInterface(), supertype_field);
 996         }
 997 
 998         public java.util.List<? extends TypeMirror> getBounds() {
 999             return Collections.unmodifiableList(getExplicitComponents());
1000         }
1001 
1002         public List<Type> getComponents() {
1003             return interfaces_field.prepend(supertype_field);
1004         }
1005 
1006         public List<Type> getExplicitComponents() {
1007             return allInterfaces ?
1008                     interfaces_field :
1009                     getComponents();
1010         }
1011 
1012         @Override
1013         public TypeKind getKind() {
1014             return TypeKind.INTERSECTION;
1015         }
1016 
1017         @Override
1018         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1019             return v.visitIntersection(this, p);
1020         }
1021     }
1022 
1023     public static class ArrayType extends Type
1024             implements javax.lang.model.type.ArrayType {
1025 
1026         public Type elemtype;
1027 
1028         public ArrayType(Type elemtype, TypeSymbol arrayClass) {
1029             super(arrayClass);
1030             this.elemtype = elemtype;
1031         }
1032 
1033         @Override
1034         public TypeTag getTag() {
1035             return ARRAY;
1036         }
1037 
1038         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1039             return v.visitArrayType(this, s);
1040         }
1041 
1042         public String toString() {
1043             return elemtype + "[]";
1044         }
1045 
1046         public boolean equals(Object obj) {
1047             return
1048                 this == obj ||
1049                 (obj instanceof ArrayType &&
1050                  this.elemtype.equals(((ArrayType)obj).elemtype));
1051         }
1052 
1053         public int hashCode() {
1054             return (ARRAY.ordinal() << 5) + elemtype.hashCode();
1055         }
1056 
1057         public boolean isVarargs() {
1058             return false;
1059         }
1060 
1061         public List<Type> allparams() { return elemtype.allparams(); }
1062 
1063         public boolean isErroneous() {
1064             return elemtype.isErroneous();
1065         }
1066 
1067         public boolean isParameterized() {
1068             return elemtype.isParameterized();
1069         }
1070 
1071         @Override
1072         public boolean isReference() {
1073             return true;
1074         }
1075 
1076         @Override
1077         public boolean isNullOrReference() {
1078             return true;
1079         }
1080 
1081         public boolean isRaw() {
1082             return elemtype.isRaw();
1083         }
1084 
1085         public ArrayType makeVarargs() {
1086             return new ArrayType(elemtype, tsym) {
1087                 @Override
1088                 public boolean isVarargs() {
1089                     return true;
1090                 }
1091             };
1092         }
1093 
1094         public Type map(Mapping f) {
1095             Type elemtype1 = f.apply(elemtype);
1096             if (elemtype1 == elemtype) return this;
1097             else return new ArrayType(elemtype1, tsym);
1098         }
1099 
1100         public boolean contains(Type elem) {
1101             return elem == this || elemtype.contains(elem);
1102         }
1103 
1104         public void complete() {
1105             elemtype.complete();
1106         }
1107 
1108         public Type getComponentType() {
1109             return elemtype;
1110         }
1111 
1112         public TypeKind getKind() {
1113             return TypeKind.ARRAY;
1114         }
1115 
1116         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1117             return v.visitArray(this, p);
1118         }
1119     }
1120 
1121     public static class MethodType extends Type implements ExecutableType {
1122 
1123         public List<Type> argtypes;
1124         public Type restype;
1125         public List<Type> thrown;
1126 
1127         /** The type annotations on the method receiver.
1128          */
1129         public Type recvtype;
1130 
1131         public MethodType(List<Type> argtypes,
1132                           Type restype,
1133                           List<Type> thrown,
1134                           TypeSymbol methodClass) {
1135             super(methodClass);
1136             this.argtypes = argtypes;
1137             this.restype = restype;
1138             this.thrown = thrown;
1139         }
1140 
1141         @Override
1142         public TypeTag getTag() {
1143             return METHOD;
1144         }
1145 
1146         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1147             return v.visitMethodType(this, s);
1148         }
1149 
1150         /** The Java source which this type represents.
1151          *
1152          *  XXX 06/09/99 iris This isn't correct Java syntax, but it probably
1153          *  should be.
1154          */
1155         public String toString() {
1156             return "(" + argtypes + ")" + restype;
1157         }
1158 
1159         public List<Type>        getParameterTypes() { return argtypes; }
1160         public Type              getReturnType()     { return restype; }
1161         public Type              getReceiverType()   { return recvtype; }
1162         public List<Type>        getThrownTypes()    { return thrown; }
1163 
1164         public boolean isErroneous() {
1165             return
1166                 isErroneous(argtypes) ||
1167                 restype != null && restype.isErroneous();
1168         }
1169 
1170         public Type map(Mapping f) {
1171             List<Type> argtypes1 = map(argtypes, f);
1172             Type restype1 = f.apply(restype);
1173             List<Type> thrown1 = map(thrown, f);
1174             if (argtypes1 == argtypes &&
1175                 restype1 == restype &&
1176                 thrown1 == thrown) return this;
1177             else return new MethodType(argtypes1, restype1, thrown1, tsym);
1178         }
1179 
1180         public boolean contains(Type elem) {
1181             return elem == this || contains(argtypes, elem) || restype.contains(elem) || contains(thrown, elem);
1182         }
1183 
1184         public MethodType asMethodType() { return this; }
1185 
1186         public void complete() {
1187             for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
1188                 l.head.complete();
1189             restype.complete();
1190             recvtype.complete();
1191             for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1192                 l.head.complete();
1193         }
1194 
1195         public List<TypeVar> getTypeVariables() {
1196             return List.nil();
1197         }
1198 
1199         public TypeSymbol asElement() {
1200             return null;
1201         }
1202 
1203         public TypeKind getKind() {
1204             return TypeKind.EXECUTABLE;
1205         }
1206 
1207         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1208             return v.visitExecutable(this, p);
1209         }
1210     }
1211 
1212     public static class PackageType extends Type implements NoType {
1213 
1214         PackageType(TypeSymbol tsym) {
1215             super(tsym);
1216         }
1217 
1218         @Override
1219         public TypeTag getTag() {
1220             return PACKAGE;
1221         }
1222 
1223         @Override
1224         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1225             return v.visitPackageType(this, s);
1226         }
1227 
1228         public String toString() {
1229             return tsym.getQualifiedName().toString();
1230         }
1231 
1232         public TypeKind getKind() {
1233             return TypeKind.PACKAGE;
1234         }
1235 
1236         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1237             return v.visitNoType(this, p);
1238         }
1239     }
1240 
1241     public static class TypeVar extends Type implements TypeVariable {
1242 
1243         /** The upper bound of this type variable; set from outside.
1244          *  Must be nonempty once it is set.
1245          *  For a bound, `bound' is the bound type itself.
1246          *  Multiple bounds are expressed as a single class type which has the
1247          *  individual bounds as superclass, respectively interfaces.
1248          *  The class type then has as `tsym' a compiler generated class `c',
1249          *  which has a flag COMPOUND and whose owner is the type variable
1250          *  itself. Furthermore, the erasure_field of the class
1251          *  points to the first class or interface bound.
1252          */
1253         public Type bound = null;
1254 
1255         /** The lower bound of this type variable.
1256          *  TypeVars don't normally have a lower bound, so it is normally set
1257          *  to syms.botType.
1258          *  Subtypes, such as CapturedType, may provide a different value.
1259          */
1260         public Type lower;
1261 
1262         public TypeVar(Name name, Symbol owner, Type lower) {
1263             super(null);
1264             tsym = new TypeVariableSymbol(0, name, this, owner);
1265             this.lower = lower;
1266         }
1267 
1268         public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
1269             super(tsym);
1270             this.bound = bound;
1271             this.lower = lower;
1272         }
1273 
1274         @Override
1275         public TypeTag getTag() {
1276             return TYPEVAR;
1277         }
1278 
1279         @Override
1280         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1281             return v.visitTypeVar(this, s);
1282         }
1283 
1284         @Override
1285         public Type getUpperBound() {
1286             if ((bound == null || bound.hasTag(NONE)) && this != tsym.type) {
1287                 bound = tsym.type.getUpperBound();
1288             }
1289             return bound;
1290         }
1291 
1292         int rank_field = -1;
1293 
1294         @Override
1295         public Type getLowerBound() {
1296             return lower;
1297         }
1298 
1299         public TypeKind getKind() {
1300             return TypeKind.TYPEVAR;
1301         }
1302 
1303         public boolean isCaptured() {
1304             return false;
1305         }
1306 
1307         @Override
1308         public boolean isReference() {
1309             return true;
1310         }
1311 
1312         @Override
1313         public boolean isNullOrReference() {
1314             return true;
1315         }
1316 
1317         @Override
1318         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1319             return v.visitTypeVariable(this, p);
1320         }
1321     }
1322 
1323     /** A captured type variable comes from wildcards which can have
1324      *  both upper and lower bound.  CapturedType extends TypeVar with
1325      *  a lower bound.
1326      */
1327     public static class CapturedType extends TypeVar {
1328 
1329         public WildcardType wildcard;
1330 
1331         public CapturedType(Name name,
1332                             Symbol owner,
1333                             Type upper,
1334                             Type lower,
1335                             WildcardType wildcard) {
1336             super(name, owner, lower);
1337             this.lower = Assert.checkNonNull(lower);
1338             this.bound = upper;
1339             this.wildcard = wildcard;
1340         }
1341 
1342         @Override
1343         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1344             return v.visitCapturedType(this, s);
1345         }
1346 
1347         @Override
1348         public boolean isCaptured() {
1349             return true;
1350         }
1351 
1352         @Override
1353         public String toString() {
1354             return "capture#"
1355                 + (hashCode() & 0xFFFFFFFFL) % Printer.PRIME
1356                 + " of "
1357                 + wildcard;
1358         }
1359     }
1360 
1361     public static abstract class DelegatedType extends Type {
1362         public Type qtype;
1363         public TypeTag tag;
1364         public DelegatedType(TypeTag tag, Type qtype) {
1365             super(qtype.tsym);
1366             this.tag = tag;
1367             this.qtype = qtype;
1368         }
1369         public TypeTag getTag() { return tag; }
1370         public String toString() { return qtype.toString(); }
1371         public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
1372         public Type getEnclosingType() { return qtype.getEnclosingType(); }
1373         public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
1374         public Type getReturnType() { return qtype.getReturnType(); }
1375         public Type getReceiverType() { return qtype.getReceiverType(); }
1376         public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
1377         public List<Type> allparams() { return qtype.allparams(); }
1378         public Type getUpperBound() { return qtype.getUpperBound(); }
1379         public boolean isErroneous() { return qtype.isErroneous(); }
1380     }
1381 
1382     /**
1383      * The type of a generic method type. It consists of a method type and
1384      * a list of method type-parameters that are used within the method
1385      * type.
1386      */
1387     public static class ForAll extends DelegatedType implements ExecutableType {
1388         public List<Type> tvars;
1389 
1390         public ForAll(List<Type> tvars, Type qtype) {
1391             super(FORALL, (MethodType)qtype);
1392             this.tvars = tvars;
1393         }
1394 
1395         @Override
1396         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1397             return v.visitForAll(this, s);
1398         }
1399 
1400         public String toString() {
1401             return "<" + tvars + ">" + qtype;
1402         }
1403 
1404         public List<Type> getTypeArguments()   { return tvars; }
1405 
1406         public boolean isErroneous()  {
1407             return qtype.isErroneous();
1408         }
1409 
1410         public Type map(Mapping f) {
1411             return f.apply(qtype);
1412         }
1413 
1414         public boolean contains(Type elem) {
1415             return qtype.contains(elem);
1416         }
1417 
1418         public MethodType asMethodType() {
1419             return (MethodType)qtype;
1420         }
1421 
1422         public void complete() {
1423             for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
1424                 ((TypeVar)l.head).bound.complete();
1425             }
1426             qtype.complete();
1427         }
1428 
1429         public List<TypeVar> getTypeVariables() {
1430             return List.convert(TypeVar.class, getTypeArguments());
1431         }
1432 
1433         public TypeKind getKind() {
1434             return TypeKind.EXECUTABLE;
1435         }
1436 
1437         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1438             return v.visitExecutable(this, p);
1439         }
1440     }
1441 
1442     /** A class for inference variables, for use during method/diamond type
1443      *  inference. An inference variable has upper/lower bounds and a set
1444      *  of equality constraints. Such bounds are set during subtyping, type-containment,
1445      *  type-equality checks, when the types being tested contain inference variables.
1446      *  A change listener can be attached to an inference variable, to receive notifications
1447      *  whenever the bounds of an inference variable change.
1448      */
1449     public static class UndetVar extends DelegatedType {
1450 
1451         /** Inference variable change listener. The listener method is called
1452          *  whenever a change to the inference variable's bounds occurs
1453          */
1454         public interface UndetVarListener {
1455             /** called when some inference variable bounds (of given kinds ibs) change */
1456             void varChanged(UndetVar uv, Set<InferenceBound> ibs);
1457         }
1458 
1459         /**
1460          * Inference variable bound kinds
1461          */
1462         public enum InferenceBound {
1463             UPPER {
1464                 public InferenceBound complement() { return LOWER; }
1465             },
1466              /** lower bounds */
1467             LOWER {
1468                 public InferenceBound complement() { return UPPER; }
1469             },
1470              /** equality constraints */
1471             EQ {
1472                 public InferenceBound complement() { return EQ; }
1473             };
1474 
1475             public abstract InferenceBound complement();
1476         }
1477 
1478         /** inference variable bounds */
1479         protected Map<InferenceBound, List<Type>> bounds;
1480 
1481         /** inference variable's inferred type (set from Infer.java) */
1482         public Type inst = null;
1483 
1484         /** number of declared (upper) bounds */
1485         public int declaredCount;
1486 
1487         /** inference variable's change listener */
1488         public UndetVarListener listener = null;
1489 
1490         @Override
1491         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1492             return v.visitUndetVar(this, s);
1493         }
1494 
1495         public UndetVar(TypeVar origin, Types types) {
1496             super(UNDETVAR, origin);
1497             bounds = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
1498             List<Type> declaredBounds = types.getBounds(origin);
1499             declaredCount = declaredBounds.length();
1500             bounds.put(InferenceBound.UPPER, declaredBounds);
1501             bounds.put(InferenceBound.LOWER, List.<Type>nil());
1502             bounds.put(InferenceBound.EQ, List.<Type>nil());
1503         }
1504 
1505         public String toString() {
1506             return (inst == null) ? qtype + "?" : inst.toString();
1507         }
1508 
1509         public String debugString() {
1510             String result = "inference var = " + qtype + "\n";
1511             if (inst != null) {
1512                 result += "inst = " + inst + '\n';
1513             }
1514             for (InferenceBound bound: InferenceBound.values()) {
1515                 List<Type> aboundList = bounds.get(bound);
1516                 if (aboundList.size() > 0) {
1517                     result += bound + " = " + aboundList + '\n';
1518                 }
1519             }
1520             return result;
1521         }
1522 
1523         @Override
1524         public boolean isPartial() {
1525             return true;
1526         }
1527 
1528         @Override
1529         public Type baseType() {
1530             return (inst == null) ? this : inst.baseType();
1531         }
1532 
1533         /** get all bounds of a given kind */
1534         public List<Type> getBounds(InferenceBound... ibs) {
1535             ListBuffer<Type> buf = new ListBuffer<>();
1536             for (InferenceBound ib : ibs) {
1537                 buf.appendList(bounds.get(ib));
1538             }
1539             return buf.toList();
1540         }
1541 
1542         /** get the list of declared (upper) bounds */
1543         public List<Type> getDeclaredBounds() {
1544             ListBuffer<Type> buf = new ListBuffer<>();
1545             int count = 0;
1546             for (Type b : getBounds(InferenceBound.UPPER)) {
1547                 if (count++ == declaredCount) break;
1548                 buf.append(b);
1549             }
1550             return buf.toList();
1551         }
1552 
1553         /** internal method used to override an undetvar bounds */
1554         public void setBounds(InferenceBound ib, List<Type> newBounds) {
1555             bounds.put(ib, newBounds);
1556         }
1557 
1558         /** add a bound of a given kind - this might trigger listener notification */
1559         public final void addBound(InferenceBound ib, Type bound, Types types) {
1560             addBound(ib, bound, types, false);
1561         }
1562 
1563         protected void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
1564             Type bound2 = toTypeVarMap.apply(bound).baseType();
1565             List<Type> prevBounds = bounds.get(ib);
1566             for (Type b : prevBounds) {
1567                 //check for redundancy - use strict version of isSameType on tvars
1568                 //(as the standard version will lead to false positives w.r.t. clones ivars)
1569                 if (types.isSameType(b, bound2, true) || bound == qtype) return;
1570             }
1571             bounds.put(ib, prevBounds.prepend(bound2));
1572             notifyChange(EnumSet.of(ib));
1573         }
1574         //where
1575             Type.Mapping toTypeVarMap = new Mapping("toTypeVarMap") {
1576                 @Override
1577                 public Type apply(Type t) {
1578                     if (t.hasTag(UNDETVAR)) {
1579                         UndetVar uv = (UndetVar)t;
1580                         return uv.inst != null ? uv.inst : uv.qtype;
1581                     } else {
1582                         return t.map(this);
1583                     }
1584                 }
1585             };
1586 
1587         /** replace types in all bounds - this might trigger listener notification */
1588         public void substBounds(List<Type> from, List<Type> to, Types types) {
1589             List<Type> instVars = from.diff(to);
1590             //if set of instantiated ivars is empty, there's nothing to do!
1591             if (instVars.isEmpty()) return;
1592             final EnumSet<InferenceBound> boundsChanged = EnumSet.noneOf(InferenceBound.class);
1593             UndetVarListener prevListener = listener;
1594             try {
1595                 //setup new listener for keeping track of changed bounds
1596                 listener = new UndetVarListener() {
1597                     public void varChanged(UndetVar uv, Set<InferenceBound> ibs) {
1598                         boundsChanged.addAll(ibs);
1599                     }
1600                 };
1601                 for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
1602                     InferenceBound ib = _entry.getKey();
1603                     List<Type> prevBounds = _entry.getValue();
1604                     ListBuffer<Type> newBounds = new ListBuffer<>();
1605                     ListBuffer<Type> deps = new ListBuffer<>();
1606                     //step 1 - re-add bounds that are not dependent on ivars
1607                     for (Type t : prevBounds) {
1608                         if (!t.containsAny(instVars)) {
1609                             newBounds.append(t);
1610                         } else {
1611                             deps.append(t);
1612                         }
1613                     }
1614                     //step 2 - replace bounds
1615                     bounds.put(ib, newBounds.toList());
1616                     //step 3 - for each dependency, add new replaced bound
1617                     for (Type dep : deps) {
1618                         addBound(ib, types.subst(dep, from, to), types, true);
1619                     }
1620                 }
1621             } finally {
1622                 listener = prevListener;
1623                 if (!boundsChanged.isEmpty()) {
1624                     notifyChange(boundsChanged);
1625                 }
1626             }
1627         }
1628 
1629         private void notifyChange(EnumSet<InferenceBound> ibs) {
1630             if (listener != null) {
1631                 listener.varChanged(this, ibs);
1632             }
1633         }
1634 
1635         public boolean isCaptured() {
1636             return false;
1637         }
1638     }
1639 
1640     /**
1641      * This class is used to represent synthetic captured inference variables
1642      * that can be generated during nested generic method calls. The only difference
1643      * between these inference variables and ordinary ones is that captured inference
1644      * variables cannot get new bounds through incorporation.
1645      */
1646     public static class CapturedUndetVar extends UndetVar {
1647 
1648         public CapturedUndetVar(CapturedType origin, Types types) {
1649             super(origin, types);
1650             if (!origin.lower.hasTag(BOT)) {
1651                 bounds.put(InferenceBound.LOWER, List.of(origin.lower));
1652             }
1653         }
1654 
1655         @Override
1656         public void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
1657             if (update) {
1658                 //only change bounds if request comes from substBounds
1659                 super.addBound(ib, bound, types, update);
1660             }
1661         }
1662 
1663         @Override
1664         public boolean isCaptured() {
1665             return true;
1666         }
1667     }
1668 
1669     /** Represents NONE.
1670      */
1671     public static class JCNoType extends Type implements NoType {
1672         public JCNoType() {
1673             super(null);
1674         }
1675 
1676         @Override
1677         public TypeTag getTag() {
1678             return NONE;
1679         }
1680 
1681         @Override
1682         public TypeKind getKind() {
1683             return TypeKind.NONE;
1684         }
1685 
1686         @Override
1687         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1688             return v.visitNoType(this, p);
1689         }
1690 
1691         @Override
1692         public boolean isCompound() { return false; }
1693     }
1694 
1695     /** Represents VOID.
1696      */
1697     public static class JCVoidType extends Type implements NoType {
1698 
1699         public JCVoidType() {
1700             super(null);
1701         }
1702 
1703         @Override
1704         public TypeTag getTag() {
1705             return VOID;
1706         }
1707 
1708         @Override
1709         public TypeKind getKind() {
1710             return TypeKind.VOID;
1711         }
1712 
1713         @Override
1714         public boolean isCompound() { return false; }
1715 
1716         @Override
1717         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1718             return v.visitNoType(this, p);
1719         }
1720 
1721         @Override
1722         public boolean isPrimitiveOrVoid() {
1723             return true;
1724         }
1725     }
1726 
1727     static class BottomType extends Type implements NullType {
1728         public BottomType() {
1729             super(null);
1730         }
1731 
1732         @Override
1733         public TypeTag getTag() {
1734             return BOT;
1735         }
1736 
1737         @Override
1738         public TypeKind getKind() {
1739             return TypeKind.NULL;
1740         }
1741 
1742         @Override
1743         public boolean isCompound() { return false; }
1744 
1745         @Override
1746         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1747             return v.visitNull(this, p);
1748         }
1749 
1750         @Override
1751         public Type constType(Object value) {
1752             return this;
1753         }
1754 
1755         @Override
1756         public String stringValue() {
1757             return "null";
1758         }
1759 
1760         @Override
1761         public boolean isNullOrReference() {
1762             return true;
1763         }
1764 
1765     }
1766 
1767     public static class ErrorType extends ClassType
1768             implements javax.lang.model.type.ErrorType {
1769 
1770         private Type originalType = null;
1771 
1772         public ErrorType(Type originalType, TypeSymbol tsym) {
1773             super(noType, List.<Type>nil(), null);
1774             this.tsym = tsym;
1775             this.originalType = (originalType == null ? noType : originalType);
1776         }
1777 
1778         public ErrorType(ClassSymbol c, Type originalType) {
1779             this(originalType, c);
1780             c.type = this;
1781             c.kind = ERR;
1782             c.members_field = new Scope.ErrorScope(c);
1783         }
1784 
1785         @Override
1786         public TypeTag getTag() {
1787             return ERROR;
1788         }
1789 
1790         @Override
1791         public boolean isPartial() {
1792             return true;
1793         }
1794 
1795         @Override
1796         public boolean isReference() {
1797             return true;
1798         }
1799 
1800         @Override
1801         public boolean isNullOrReference() {
1802             return true;
1803         }
1804 
1805         public ErrorType(Name name, TypeSymbol container, Type originalType) {
1806             this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
1807         }
1808 
1809         @Override
1810         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1811             return v.visitErrorType(this, s);
1812         }
1813 
1814         public Type constType(Object constValue) { return this; }
1815         public Type getEnclosingType()           { return this; }
1816         public Type getReturnType()              { return this; }
1817         public Type asSub(Symbol sym)            { return this; }
1818         public Type map(Mapping f)               { return this; }
1819 
1820         public boolean isGenType(Type t)         { return true; }
1821         public boolean isErroneous()             { return true; }
1822         public boolean isCompound()              { return false; }
1823         public boolean isInterface()             { return false; }
1824 
1825         public List<Type> allparams()            { return List.nil(); }
1826         public List<Type> getTypeArguments()     { return List.nil(); }
1827 
1828         public TypeKind getKind() {
1829             return TypeKind.ERROR;
1830         }
1831 
1832         public Type getOriginalType() {
1833             return originalType;
1834         }
1835 
1836         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1837             return v.visitError(this, p);
1838         }
1839     }
1840 
1841     public static class AnnotatedType extends Type
1842             implements
1843                 javax.lang.model.type.ArrayType,
1844                 javax.lang.model.type.DeclaredType,
1845                 javax.lang.model.type.PrimitiveType,
1846                 javax.lang.model.type.TypeVariable,
1847                 javax.lang.model.type.WildcardType {
1848         /** The type annotations on this type.
1849          */
1850         private List<Attribute.TypeCompound> typeAnnotations;
1851 
1852         /** The underlying type that is annotated.
1853          */
1854         private Type underlyingType;
1855 
1856         protected AnnotatedType(List<Attribute.TypeCompound> typeAnnotations,
1857                 Type underlyingType) {
1858             super(underlyingType.tsym);
1859             this.typeAnnotations = typeAnnotations;
1860             this.underlyingType = underlyingType;
1861             Assert.check(typeAnnotations != null && typeAnnotations.nonEmpty(),
1862                     "Can't create AnnotatedType without annotations: " + underlyingType);
1863             Assert.check(!underlyingType.isAnnotated(),
1864                     "Can't annotate already annotated type: " + underlyingType +
1865                     "; adding: " + typeAnnotations);
1866         }
1867 
1868         @Override
1869         public TypeTag getTag() {
1870             return underlyingType.getTag();
1871         }
1872 
1873         @Override
1874         public boolean isAnnotated() {
1875             return true;
1876         }
1877 
1878         @Override
1879         public List<Attribute.TypeCompound> getAnnotationMirrors() {
1880             return typeAnnotations;
1881         }
1882 
1883 
1884         @Override
1885         public TypeKind getKind() {
1886             return underlyingType.getKind();
1887         }
1888 
1889         @Override
1890         public Type unannotatedType() {
1891             return underlyingType;
1892         }
1893 
1894         @Override
1895         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1896             return v.visitAnnotatedType(this, s);
1897         }
1898 
1899         @Override
1900         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1901             return underlyingType.accept(v, p);
1902         }
1903 
1904         @Override
1905         public Type map(Mapping f) {
1906             underlyingType.map(f);
1907             return this;
1908         }
1909 
1910         @Override
1911         public Type constType(Object constValue) { return underlyingType.constType(constValue); }
1912         @Override
1913         public Type getEnclosingType()           { return underlyingType.getEnclosingType(); }
1914 
1915         @Override
1916         public Type getReturnType()              { return underlyingType.getReturnType(); }
1917         @Override
1918         public List<Type> getTypeArguments()     { return underlyingType.getTypeArguments(); }
1919         @Override
1920         public List<Type> getParameterTypes()    { return underlyingType.getParameterTypes(); }
1921         @Override
1922         public Type getReceiverType()            { return underlyingType.getReceiverType(); }
1923         @Override
1924         public List<Type> getThrownTypes()       { return underlyingType.getThrownTypes(); }
1925         @Override
1926         public Type getUpperBound()              { return underlyingType.getUpperBound(); }
1927         @Override
1928         public Type getLowerBound()              { return underlyingType.getLowerBound(); }
1929 
1930         @Override
1931         public boolean isErroneous()             { return underlyingType.isErroneous(); }
1932         @Override
1933         public boolean isCompound()              { return underlyingType.isCompound(); }
1934         @Override
1935         public boolean isInterface()             { return underlyingType.isInterface(); }
1936         @Override
1937         public List<Type> allparams()            { return underlyingType.allparams(); }
1938         @Override
1939         public boolean isPrimitive()             { return underlyingType.isPrimitive(); }
1940         @Override
1941         public boolean isPrimitiveOrVoid()       { return underlyingType.isPrimitiveOrVoid(); }
1942         @Override
1943         public boolean isNumeric()               { return underlyingType.isNumeric(); }
1944         @Override
1945         public boolean isReference()             { return underlyingType.isReference(); }
1946         @Override
1947         public boolean isNullOrReference()       { return underlyingType.isNullOrReference(); }
1948         @Override
1949         public boolean isPartial()               { return underlyingType.isPartial(); }
1950         @Override
1951         public boolean isParameterized()         { return underlyingType.isParameterized(); }
1952         @Override
1953         public boolean isRaw()                   { return underlyingType.isRaw(); }
1954         @Override
1955         public boolean isFinal()                 { return underlyingType.isFinal(); }
1956         @Override
1957         public boolean isSuperBound()            { return underlyingType.isSuperBound(); }
1958         @Override
1959         public boolean isExtendsBound()          { return underlyingType.isExtendsBound(); }
1960         @Override
1961         public boolean isUnbound()               { return underlyingType.isUnbound(); }
1962 
1963         @Override
1964         public String toString() {
1965             // This method is only used for internal debugging output.
1966             // See
1967             // com.sun.tools.javac.code.Printer.visitAnnotatedType(AnnotatedType, Locale)
1968             // for the user-visible logic.
1969             if (typeAnnotations != null &&
1970                     !typeAnnotations.isEmpty()) {
1971                 return "(" + typeAnnotations.toString() + " :: " + underlyingType.toString() + ")";
1972             } else {
1973                 return "({} :: " + underlyingType.toString() +")";
1974             }
1975         }
1976 
1977         @Override
1978         public boolean contains(Type t)          { return underlyingType.contains(t); }
1979 
1980         @Override
1981         public Type withTypeVar(Type t) {
1982             // Don't create a new AnnotatedType, as 'this' will
1983             // get its annotations set later.
1984             underlyingType = underlyingType.withTypeVar(t);
1985             return this;
1986         }
1987 
1988         // TODO: attach annotations?
1989         @Override
1990         public TypeSymbol asElement()            { return underlyingType.asElement(); }
1991 
1992         // TODO: attach annotations?
1993         @Override
1994         public MethodType asMethodType()         { return underlyingType.asMethodType(); }
1995 
1996         @Override
1997         public void complete()                   { underlyingType.complete(); }
1998 
1999         @Override
2000         public TypeMirror getComponentType()     { return ((ArrayType)underlyingType).getComponentType(); }
2001 
2002         // The result is an ArrayType, but only in the model sense, not the Type sense.
2003         public Type makeVarargs() {
2004             return ((ArrayType) underlyingType).makeVarargs().annotatedType(typeAnnotations);
2005         }
2006 
2007         @Override
2008         public TypeMirror getExtendsBound()      { return ((WildcardType)underlyingType).getExtendsBound(); }
2009         @Override
2010         public TypeMirror getSuperBound()        { return ((WildcardType)underlyingType).getSuperBound(); }
2011     }
2012 
2013     public static class UnknownType extends Type {
2014 
2015         public UnknownType() {
2016             super(null);
2017         }
2018 
2019         @Override
2020         public TypeTag getTag() {
2021             return UNKNOWN;
2022         }
2023 
2024         @Override
2025         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2026             return v.visitUnknown(this, p);
2027         }
2028 
2029         @Override
2030         public boolean isPartial() {
2031             return true;
2032         }
2033     }
2034 
2035     /**
2036      * A visitor for types.  A visitor is used to implement operations
2037      * (or relations) on types.  Most common operations on types are
2038      * binary relations and this interface is designed for binary
2039      * relations, that is, operations of the form
2040      * Type&nbsp;&times;&nbsp;S&nbsp;&rarr;&nbsp;R.
2041      * <!-- In plain text: Type x S -> R -->
2042      *
2043      * @param <R> the return type of the operation implemented by this
2044      * visitor; use Void if no return type is needed.
2045      * @param <S> the type of the second argument (the first being the
2046      * type itself) of the operation implemented by this visitor; use
2047      * Void if a second argument is not needed.
2048      */
2049     public interface Visitor<R,S> {
2050         R visitClassType(ClassType t, S s);
2051         R visitWildcardType(WildcardType t, S s);
2052         R visitArrayType(ArrayType t, S s);
2053         R visitMethodType(MethodType t, S s);
2054         R visitPackageType(PackageType t, S s);
2055         R visitTypeVar(TypeVar t, S s);
2056         R visitCapturedType(CapturedType t, S s);
2057         R visitForAll(ForAll t, S s);
2058         R visitUndetVar(UndetVar t, S s);
2059         R visitErrorType(ErrorType t, S s);
2060         R visitAnnotatedType(AnnotatedType t, S s);
2061         R visitType(Type t, S s);
2062     }
2063 }