1 /*
   2  * Copyright 1999-2009 Sun Microsystems, Inc.  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.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package com.sun.tools.javac.code;
  27 
  28 import com.sun.tools.javac.util.*;
  29 import com.sun.tools.javac.code.Symbol.*;
  30 
  31 import javax.lang.model.type.*;
  32 
  33 import static com.sun.tools.javac.code.Flags.*;
  34 import static com.sun.tools.javac.code.Kinds.*;
  35 import static com.sun.tools.javac.code.BoundKind.*;
  36 import static com.sun.tools.javac.code.TypeTags.*;
  37 
  38 /** This class represents Java types. The class itself defines the behavior of
  39  *  the following types:
  40  *  <pre>
  41  *  base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
  42  *  type `void' (tag: VOID),
  43  *  the bottom type (tag: BOT),
  44  *  the missing type (tag: NONE).
  45  *  </pre>
  46  *  <p>The behavior of the following types is defined in subclasses, which are
  47  *  all static inner classes of this class:
  48  *  <pre>
  49  *  class types (tag: CLASS, class: ClassType),
  50  *  array types (tag: ARRAY, class: ArrayType),
  51  *  method types (tag: METHOD, class: MethodType),
  52  *  package types (tag: PACKAGE, class: PackageType),
  53  *  type variables (tag: TYPEVAR, class: TypeVar),
  54  *  type arguments (tag: WILDCARD, class: WildcardType),
  55  *  polymorphic types (tag: FORALL, class: ForAll),
  56  *  the error type (tag: ERROR, class: ErrorType).
  57  *  </pre>
  58  *
  59  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
  60  *  you write code that depends on this, you do so at your own risk.
  61  *  This code and its internal interfaces are subject to change or
  62  *  deletion without notice.</b>
  63  *
  64  *  @see TypeTags
  65  */
  66 public class Type implements PrimitiveType {
  67 
  68     /** Constant type: no type at all. */
  69     public static final JCNoType noType = new JCNoType(NONE);
  70 
  71     /** If this switch is turned on, the names of type variables
  72      *  and anonymous classes are printed with hashcodes appended.
  73      */
  74     public static boolean moreInfo = false;
  75 
  76     /** The tag of this type.
  77      *
  78      *  @see TypeTags
  79      */
  80     public int tag;
  81 
  82     /** The defining class / interface / package / type variable
  83      */
  84     public TypeSymbol tsym;
  85 
  86     /**
  87      * The constant value of this type, null if this type does not
  88      * have a constant value attribute. Only primitive types and
  89      * strings (ClassType) can have a constant value attribute.
  90      * @return the constant value attribute of this type
  91      */
  92     public Object constValue() {
  93         return null;
  94     }
  95 
  96     public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
  97 
  98     /** Define a type given its tag and type symbol
  99      */
 100     public Type(int tag, TypeSymbol tsym) {
 101         this.tag = tag;
 102         this.tsym = tsym;
 103     }
 104 
 105     /** An abstract class for mappings from types to types
 106      */
 107     public static abstract class Mapping {
 108         private String name;
 109         public Mapping(String name) {
 110             this.name = name;
 111         }
 112         public abstract Type apply(Type t);
 113         public String toString() {
 114             return name;
 115         }
 116     }
 117 
 118     /** map a type function over all immediate descendants of this type
 119      */
 120     public Type map(Mapping f) {
 121         return this;
 122     }
 123 
 124     /** map a type function over a list of types
 125      */
 126     public static List<Type> map(List<Type> ts, Mapping f) {
 127         if (ts.nonEmpty()) {
 128             List<Type> tail1 = map(ts.tail, f);
 129             Type t = f.apply(ts.head);
 130             if (tail1 != ts.tail || t != ts.head)
 131                 return tail1.prepend(t);
 132         }
 133         return ts;
 134     }
 135 
 136     /** Define a constant type, of the same kind as this type
 137      *  and with given constant value
 138      */
 139     public Type constType(Object constValue) {
 140         final Object value = constValue;
 141         assert tag <= BOOLEAN;
 142         return new Type(tag, tsym) {
 143                 @Override
 144                 public Object constValue() {
 145                     return value;
 146                 }
 147                 @Override
 148                 public Type baseType() {
 149                     return tsym.type;
 150                 }
 151             };
 152     }
 153 
 154     /**
 155      * If this is a constant type, return its underlying type.
 156      * Otherwise, return the type itself.
 157      */
 158     public Type baseType() {
 159         return this;
 160     }
 161 
 162     /** Return the base types of a list of types.
 163      */
 164     public static List<Type> baseTypes(List<Type> ts) {
 165         if (ts.nonEmpty()) {
 166             Type t = ts.head.baseType();
 167             List<Type> baseTypes = baseTypes(ts.tail);
 168             if (t != ts.head || baseTypes != ts.tail)
 169                 return baseTypes.prepend(t);
 170         }
 171         return ts;
 172     }
 173 
 174     /** The Java source which this type represents.
 175      */
 176     public String toString() {
 177         String s = (tsym == null || tsym.name == null)
 178             ? "<none>"
 179             : tsym.name.toString();
 180         if (moreInfo && tag == TYPEVAR) s = s + hashCode();
 181         return s;
 182     }
 183 
 184     /**
 185      * The Java source which this type list represents.  A List is
 186      * represented as a comma-spearated listing of the elements in
 187      * that list.
 188      */
 189     public static String toString(List<Type> ts) {
 190         if (ts.isEmpty()) {
 191             return "";
 192         } else {
 193             StringBuffer buf = new StringBuffer();
 194             buf.append(ts.head.toString());
 195             for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail)
 196                 buf.append(",").append(l.head.toString());
 197             return buf.toString();
 198         }
 199     }
 200 
 201     /**
 202      * The constant value of this type, converted to String
 203      */
 204     public String stringValue() {
 205         assert constValue() != null;
 206         if (tag == BOOLEAN)
 207             return ((Integer) constValue()).intValue() == 0 ? "false" : "true";
 208         else if (tag == CHAR)
 209             return String.valueOf((char) ((Integer) constValue()).intValue());
 210         else
 211             return constValue().toString();
 212     }
 213 
 214     /**
 215      * This method is analogous to isSameType, but weaker, since we
 216      * never complete classes. Where isSameType would complete a
 217      * class, equals assumes that the two types are different.
 218      */
 219     public boolean equals(Object t) {
 220         return super.equals(t);
 221     }
 222 
 223     public int hashCode() {
 224         return super.hashCode();
 225     }
 226 
 227     /** Is this a constant type whose value is false?
 228      */
 229     public boolean isFalse() {
 230         return
 231             tag == BOOLEAN &&
 232             constValue() != null &&
 233             ((Integer)constValue()).intValue() == 0;
 234     }
 235 
 236     /** Is this a constant type whose value is true?
 237      */
 238     public boolean isTrue() {
 239         return
 240             tag == BOOLEAN &&
 241             constValue() != null &&
 242             ((Integer)constValue()).intValue() != 0;
 243     }
 244 
 245     public String argtypes(boolean varargs) {
 246         List<Type> args = getParameterTypes();
 247         if (!varargs) return args.toString();
 248         StringBuffer buf = new StringBuffer();
 249         while (args.tail.nonEmpty()) {
 250             buf.append(args.head);
 251             args = args.tail;
 252             buf.append(',');
 253         }
 254         if (args.head.tag == ARRAY) {
 255             buf.append(((ArrayType)args.head).elemtype);
 256             buf.append("...");
 257         } else {
 258             buf.append(args.head);
 259         }
 260         return buf.toString();
 261     }
 262 
 263     /** Access methods.
 264      */
 265     public List<Type>        getTypeArguments()  { return List.nil(); }
 266     public Type              getEnclosingType() { return null; }
 267     public List<Type>        getParameterTypes() { return List.nil(); }
 268     public Type              getReturnType()     { return null; }
 269     public List<Type>        getThrownTypes()    { return List.nil(); }
 270     public Type              getUpperBound()     { return null; }
 271     public Type              getLowerBound()     { return null; }
 272 
 273     public void setThrown(List<Type> ts) {
 274         throw new AssertionError();
 275     }
 276 
 277     /** Navigation methods, these will work for classes, type variables,
 278      *  foralls, but will return null for arrays and methods.
 279      */
 280 
 281    /** Return all parameters of this type and all its outer types in order
 282     *  outer (first) to inner (last).
 283     */
 284     public List<Type> allparams() { return List.nil(); }
 285 
 286     /** Does this type contain "error" elements?
 287      */
 288     public boolean isErroneous() {
 289         return false;
 290     }
 291 
 292     public static boolean isErroneous(List<Type> ts) {
 293         for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
 294             if (l.head.isErroneous()) return true;
 295         return false;
 296     }
 297 
 298     /** Is this type parameterized?
 299      *  A class type is parameterized if it has some parameters.
 300      *  An array type is parameterized if its element type is parameterized.
 301      *  All other types are not parameterized.
 302      */
 303     public boolean isParameterized() {
 304         return false;
 305     }
 306 
 307     /** Is this type a raw type?
 308      *  A class type is a raw type if it misses some of its parameters.
 309      *  An array type is a raw type if its element type is raw.
 310      *  All other types are not raw.
 311      *  Type validation will ensure that the only raw types
 312      *  in a program are types that miss all their type variables.
 313      */
 314     public boolean isRaw() {
 315         return false;
 316     }
 317 
 318     public boolean isCompound() {
 319         return tsym.completer == null
 320             // Compound types can't have a completer.  Calling
 321             // flags() will complete the symbol causing the
 322             // compiler to load classes unnecessarily.  This led
 323             // to regression 6180021.
 324             && (tsym.flags() & COMPOUND) != 0;
 325     }
 326 
 327     public boolean isInterface() {
 328         return (tsym.flags() & INTERFACE) != 0;
 329     }
 330 
 331     public boolean isPrimitive() {
 332         return tag < VOID;
 333     }
 334 
 335     /**
 336      * Does this type contain occurrences of type t?
 337      */
 338     public boolean contains(Type t) {
 339         return t == this;
 340     }
 341 
 342     public static boolean contains(List<Type> ts, Type t) {
 343         for (List<Type> l = ts;
 344              l.tail != null /*inlined: l.nonEmpty()*/;
 345              l = l.tail)
 346             if (l.head.contains(t)) return true;
 347         return false;
 348     }
 349 
 350     /** Does this type contain an occurrence of some type in `elems'?
 351      */
 352     public boolean containsSome(List<Type> ts) {
 353         for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
 354             if (this.contains(ts.head)) return true;
 355         return false;
 356     }
 357 
 358     public boolean isSuperBound() { return false; }
 359     public boolean isExtendsBound() { return false; }
 360     public boolean isUnbound() { return false; }
 361     public Type withTypeVar(Type t) { return this; }
 362 
 363     /** The underlying method type of this type.
 364      */
 365     public MethodType asMethodType() { throw new AssertionError(); }
 366 
 367     /** Complete loading all classes in this type.
 368      */
 369     public void complete() {}
 370 
 371     public Object clone() {
 372         try {
 373             return super.clone();
 374         } catch (CloneNotSupportedException e) {
 375             throw new AssertionError(e);
 376         }
 377     }
 378 
 379     public TypeSymbol asElement() {
 380         return tsym;
 381     }
 382 
 383     public TypeKind getKind() {
 384         switch (tag) {
 385         case BYTE:      return TypeKind.BYTE;
 386         case CHAR:      return TypeKind.CHAR;
 387         case SHORT:     return TypeKind.SHORT;
 388         case INT:       return TypeKind.INT;
 389         case LONG:      return TypeKind.LONG;
 390         case FLOAT:     return TypeKind.FLOAT;
 391         case DOUBLE:    return TypeKind.DOUBLE;
 392         case BOOLEAN:   return TypeKind.BOOLEAN;
 393         case VOID:      return TypeKind.VOID;
 394         case BOT:       return TypeKind.NULL;
 395         case NONE:      return TypeKind.NONE;
 396         default:        return TypeKind.OTHER;
 397         }
 398     }
 399 
 400     public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 401         if (isPrimitive())
 402             return v.visitPrimitive(this, p);
 403         else
 404             throw new AssertionError();
 405     }
 406 
 407     public static class WildcardType extends Type
 408             implements javax.lang.model.type.WildcardType {
 409 
 410         public Type type;
 411         public BoundKind kind;
 412         public TypeVar bound;
 413 
 414         @Override
 415         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
 416             return v.visitWildcardType(this, s);
 417         }
 418 
 419         public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
 420             super(WILDCARD, tsym);
 421             assert(type != null);
 422             this.kind = kind;
 423             this.type = type;
 424         }
 425         public WildcardType(WildcardType t, TypeVar bound) {
 426             this(t.type, t.kind, t.tsym, bound);
 427         }
 428 
 429         public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, TypeVar bound) {
 430             this(type, kind, tsym);
 431             this.bound = bound;
 432         }
 433 
 434         public boolean isSuperBound() {
 435             return kind == SUPER ||
 436                 kind == UNBOUND;
 437         }
 438         public boolean isExtendsBound() {
 439             return kind == EXTENDS ||
 440                 kind == UNBOUND;
 441         }
 442         public boolean isUnbound() {
 443             return kind == UNBOUND;
 444         }
 445 
 446         public Type withTypeVar(Type t) {
 447             //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
 448             if (bound == t)
 449                 return this;
 450             bound = (TypeVar)t;
 451             return this;
 452         }
 453 
 454         boolean isPrintingBound = false;
 455         public String toString() {
 456             StringBuffer s = new StringBuffer();
 457             s.append(kind.toString());
 458             if (kind != UNBOUND)
 459                 s.append(type);
 460             if (moreInfo && bound != null && !isPrintingBound)
 461                 try {
 462                     isPrintingBound = true;
 463                     s.append("{:").append(bound.bound).append(":}");
 464                 } finally {
 465                     isPrintingBound = false;
 466                 }
 467             return s.toString();
 468         }
 469 
 470         public Type map(Mapping f) {
 471             //- System.err.println("   (" + this + ").map(" + f + ")");//DEBUG
 472             Type t = type;
 473             if (t != null)
 474                 t = f.apply(t);
 475             if (t == type)
 476                 return this;
 477             else
 478                 return new WildcardType(t, kind, tsym, bound);
 479         }
 480 
 481         public Type getExtendsBound() {
 482             if (kind == EXTENDS)
 483                 return type;
 484             else
 485                 return null;
 486         }
 487 
 488         public Type getSuperBound() {
 489             if (kind == SUPER)
 490                 return type;
 491             else
 492                 return null;
 493         }
 494 
 495         public TypeKind getKind() {
 496             return TypeKind.WILDCARD;
 497         }
 498 
 499         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 500             return v.visitWildcard(this, p);
 501         }
 502     }
 503 
 504     public static class ClassType extends Type implements DeclaredType {
 505 
 506         /** The enclosing type of this type. If this is the type of an inner
 507          *  class, outer_field refers to the type of its enclosing
 508          *  instance class, in all other cases it referes to noType.
 509          */
 510         private Type outer_field;
 511 
 512         /** The type parameters of this type (to be set once class is loaded).
 513          */
 514         public List<Type> typarams_field;
 515 
 516         /** A cache variable for the type parameters of this type,
 517          *  appended to all parameters of its enclosing class.
 518          *  @see #allparams
 519          */
 520         public List<Type> allparams_field;
 521 
 522         /** The supertype of this class (to be set once class is loaded).
 523          */
 524         public Type supertype_field;
 525 
 526         /** The interfaces of this class (to be set once class is loaded).
 527          */
 528         public List<Type> interfaces_field;
 529 
 530         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
 531             super(CLASS, tsym);
 532             this.outer_field = outer;
 533             this.typarams_field = typarams;
 534             this.allparams_field = null;
 535             this.supertype_field = null;
 536             this.interfaces_field = null;
 537             /*
 538             // this can happen during error recovery
 539             assert
 540                 outer.isParameterized() ?
 541                 typarams.length() == tsym.type.typarams().length() :
 542                 outer.isRaw() ?
 543                 typarams.length() == 0 :
 544                 true;
 545             */
 546         }
 547 
 548         @Override
 549         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
 550             return v.visitClassType(this, s);
 551         }
 552 
 553         public Type constType(Object constValue) {
 554             final Object value = constValue;
 555             return new ClassType(getEnclosingType(), typarams_field, tsym) {
 556                     @Override
 557                     public Object constValue() {
 558                         return value;
 559                     }
 560                     @Override
 561                     public Type baseType() {
 562                         return tsym.type;
 563                     }
 564                 };
 565         }
 566 
 567         /** The Java source which this type represents.
 568          */
 569         public String toString() {
 570             StringBuffer buf = new StringBuffer();
 571             if (getEnclosingType().tag == CLASS && tsym.owner.kind == TYP) {
 572                 buf.append(getEnclosingType().toString());
 573                 buf.append(".");
 574                 buf.append(className(tsym, false));
 575             } else {
 576                 buf.append(className(tsym, true));
 577             }
 578             if (getTypeArguments().nonEmpty()) {
 579                 buf.append('<');
 580                 buf.append(getTypeArguments().toString());
 581                 buf.append(">");
 582             }
 583             return buf.toString();
 584         }
 585 //where
 586             private String className(Symbol sym, boolean longform) {
 587                 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
 588                     StringBuffer s = new StringBuffer(supertype_field.toString());
 589                     for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
 590                         s.append("&");
 591                         s.append(is.head.toString());
 592                     }
 593                     return s.toString();
 594                 } else if (sym.name.isEmpty()) {
 595                     String s;
 596                     ClassType norm = (ClassType) tsym.type;
 597                     if (norm == null) {
 598                         s = Log.getLocalizedString("anonymous.class", (Object)null);
 599                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
 600                         s = Log.getLocalizedString("anonymous.class",
 601                                                    norm.interfaces_field.head);
 602                     } else {
 603                         s = Log.getLocalizedString("anonymous.class",
 604                                                    norm.supertype_field);
 605                     }
 606                     if (moreInfo)
 607                         s += String.valueOf(sym.hashCode());
 608                     return s;
 609                 } else if (longform) {
 610                     return sym.getQualifiedName().toString();
 611                 } else {
 612                     return sym.name.toString();
 613                 }
 614             }
 615 
 616         public List<Type> getTypeArguments() {
 617             if (typarams_field == null) {
 618                 complete();
 619                 if (typarams_field == null)
 620                     typarams_field = List.nil();
 621             }
 622             return typarams_field;
 623         }
 624 
 625         public boolean hasErasedSupertypes() {
 626             return isRaw();
 627         }
 628 
 629         public Type getEnclosingType() {
 630             return outer_field;
 631         }
 632 
 633         public void setEnclosingType(Type outer) {
 634             outer_field = outer;
 635         }
 636 
 637         public List<Type> allparams() {
 638             if (allparams_field == null) {
 639                 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
 640             }
 641             return allparams_field;
 642         }
 643 
 644         public boolean isErroneous() {
 645             return
 646                 getEnclosingType().isErroneous() ||
 647                 isErroneous(getTypeArguments()) ||
 648                 this != tsym.type && tsym.type.isErroneous();
 649         }
 650 
 651         public boolean isParameterized() {
 652             return allparams().tail != null;
 653             // optimization, was: allparams().nonEmpty();
 654         }
 655 
 656         /** A cache for the rank. */
 657         int rank_field = -1;
 658 
 659         /** A class type is raw if it misses some
 660          *  of its type parameter sections.
 661          *  After validation, this is equivalent to:
 662          *  allparams.isEmpty() && tsym.type.allparams.nonEmpty();
 663          */
 664         public boolean isRaw() {
 665             return
 666                 this != tsym.type && // necessary, but not sufficient condition
 667                 tsym.type.allparams().nonEmpty() &&
 668                 allparams().isEmpty();
 669         }
 670 
 671         public Type map(Mapping f) {
 672             Type outer = getEnclosingType();
 673             Type outer1 = f.apply(outer);
 674             List<Type> typarams = getTypeArguments();
 675             List<Type> typarams1 = map(typarams, f);
 676             if (outer1 == outer && typarams1 == typarams) return this;
 677             else return new ClassType(outer1, typarams1, tsym);
 678         }
 679 
 680         public boolean contains(Type elem) {
 681             return
 682                 elem == this
 683                 || (isParameterized()
 684                     && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem)));
 685         }
 686 
 687         public void complete() {
 688             if (tsym.completer != null) tsym.complete();
 689         }
 690 
 691         public TypeKind getKind() {
 692             return TypeKind.DECLARED;
 693         }
 694 
 695         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 696             return v.visitDeclared(this, p);
 697         }
 698     }
 699 
 700     public static class ErasedClassType extends ClassType {
 701         public ErasedClassType(Type outer, TypeSymbol tsym) {
 702             super(outer, List.<Type>nil(), tsym);
 703         }
 704 
 705         @Override
 706         public boolean hasErasedSupertypes() {
 707             return true;
 708         }
 709     }
 710 
 711     public static class ArrayType extends Type
 712             implements javax.lang.model.type.ArrayType {
 713 
 714         public Type elemtype;
 715 
 716         public ArrayType(Type elemtype, TypeSymbol arrayClass) {
 717             super(ARRAY, arrayClass);
 718             this.elemtype = elemtype;
 719         }
 720 
 721         @Override
 722         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
 723             return v.visitArrayType(this, s);
 724         }
 725 
 726         public String toString() {
 727             return elemtype + "[]";
 728         }
 729 
 730         public boolean equals(Object obj) {
 731             return
 732                 this == obj ||
 733                 (obj instanceof ArrayType &&
 734                  this.elemtype.equals(((ArrayType)obj).elemtype));
 735         }
 736 
 737         public int hashCode() {
 738             return (ARRAY << 5) + elemtype.hashCode();
 739         }
 740 
 741         public List<Type> allparams() { return elemtype.allparams(); }
 742 
 743         public boolean isErroneous() {
 744             return elemtype.isErroneous();
 745         }
 746 
 747         public boolean isParameterized() {
 748             return elemtype.isParameterized();
 749         }
 750 
 751         public boolean isRaw() {
 752             return elemtype.isRaw();
 753         }
 754 
 755         public Type map(Mapping f) {
 756             Type elemtype1 = f.apply(elemtype);
 757             if (elemtype1 == elemtype) return this;
 758             else return new ArrayType(elemtype1, tsym);
 759         }
 760 
 761         public boolean contains(Type elem) {
 762             return elem == this || elemtype.contains(elem);
 763         }
 764 
 765         public void complete() {
 766             elemtype.complete();
 767         }
 768 
 769         public Type getComponentType() {
 770             return elemtype;
 771         }
 772 
 773         public TypeKind getKind() {
 774             return TypeKind.ARRAY;
 775         }
 776 
 777         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 778             return v.visitArray(this, p);
 779         }
 780     }
 781 
 782     public static class MethodType extends Type
 783                     implements Cloneable, ExecutableType {
 784 
 785         public List<Type> argtypes;
 786         public Type restype;
 787         public List<Type> thrown;
 788 
 789         public MethodType(List<Type> argtypes,
 790                           Type restype,
 791                           List<Type> thrown,
 792                           TypeSymbol methodClass) {
 793             super(METHOD, methodClass);
 794             this.argtypes = argtypes;
 795             this.restype = restype;
 796             this.thrown = thrown;
 797         }
 798 
 799         @Override
 800         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
 801             return v.visitMethodType(this, s);
 802         }
 803 
 804         /** The Java source which this type represents.
 805          *
 806          *  XXX 06/09/99 iris This isn't correct Java syntax, but it probably
 807          *  should be.
 808          */
 809         public String toString() {
 810             return "(" + argtypes + ")" + restype;
 811         }
 812 
 813         public boolean equals(Object obj) {
 814             if (this == obj)
 815                 return true;
 816             if (!(obj instanceof MethodType))
 817                 return false;
 818             MethodType m = (MethodType)obj;
 819             List<Type> args1 = argtypes;
 820             List<Type> args2 = m.argtypes;
 821             while (!args1.isEmpty() && !args2.isEmpty()) {
 822                 if (!args1.head.equals(args2.head))
 823                     return false;
 824                 args1 = args1.tail;
 825                 args2 = args2.tail;
 826             }
 827             if (!args1.isEmpty() || !args2.isEmpty())
 828                 return false;
 829             return restype.equals(m.restype);
 830         }
 831 
 832         public int hashCode() {
 833             int h = METHOD;
 834             for (List<Type> thisargs = this.argtypes;
 835                  thisargs.tail != null; /*inlined: thisargs.nonEmpty()*/
 836                  thisargs = thisargs.tail)
 837                 h = (h << 5) + thisargs.head.hashCode();
 838             return (h << 5) + this.restype.hashCode();
 839         }
 840 
 841         public List<Type>        getParameterTypes() { return argtypes; }
 842         public Type              getReturnType()     { return restype; }
 843         public List<Type>        getThrownTypes()    { return thrown; }
 844 
 845         public void setThrown(List<Type> t) {
 846             thrown = t;
 847         }
 848 
 849         public boolean isErroneous() {
 850             return
 851                 isErroneous(argtypes) ||
 852                 restype != null && restype.isErroneous();
 853         }
 854 
 855         public Type map(Mapping f) {
 856             List<Type> argtypes1 = map(argtypes, f);
 857             Type restype1 = f.apply(restype);
 858             List<Type> thrown1 = map(thrown, f);
 859             if (argtypes1 == argtypes &&
 860                 restype1 == restype &&
 861                 thrown1 == thrown) return this;
 862             else return new MethodType(argtypes1, restype1, thrown1, tsym);
 863         }
 864 
 865         public boolean contains(Type elem) {
 866             return elem == this || contains(argtypes, elem) || restype.contains(elem);
 867         }
 868 
 869         public MethodType asMethodType() { return this; }
 870 
 871         public void complete() {
 872             for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
 873                 l.head.complete();
 874             restype.complete();
 875             for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
 876                 l.head.complete();
 877         }
 878 
 879         public List<TypeVar> getTypeVariables() {
 880             return List.nil();
 881         }
 882 
 883         public TypeSymbol asElement() {
 884             return null;
 885         }
 886 
 887         public TypeKind getKind() {
 888             return TypeKind.EXECUTABLE;
 889         }
 890 
 891         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 892             return v.visitExecutable(this, p);
 893         }
 894     }
 895 
 896     public static class PackageType extends Type implements NoType {
 897 
 898         PackageType(TypeSymbol tsym) {
 899             super(PACKAGE, tsym);
 900         }
 901 
 902         @Override
 903         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
 904             return v.visitPackageType(this, s);
 905         }
 906 
 907         public String toString() {
 908             return tsym.getQualifiedName().toString();
 909         }
 910 
 911         public TypeKind getKind() {
 912             return TypeKind.PACKAGE;
 913         }
 914 
 915         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 916             return v.visitNoType(this, p);
 917         }
 918     }
 919 
 920     public static class TypeVar extends Type implements TypeVariable {
 921 
 922         /** The bound of this type variable; set from outside.
 923          *  Must be nonempty once it is set.
 924          *  For a bound, `bound' is the bound type itself.
 925          *  Multiple bounds are expressed as a single class type which has the
 926          *  individual bounds as superclass, respectively interfaces.
 927          *  The class type then has as `tsym' a compiler generated class `c',
 928          *  which has a flag COMPOUND and whose owner is the type variable
 929          *  itself. Furthermore, the erasure_field of the class
 930          *  points to the first class or interface bound.
 931          */
 932         public Type bound = null;
 933         public Type lower;
 934 
 935         public TypeVar(Name name, Symbol owner, Type lower) {
 936             super(TYPEVAR, null);
 937             tsym = new TypeSymbol(0, name, this, owner);
 938             this.lower = lower;
 939         }
 940 
 941         public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
 942             super(TYPEVAR, tsym);
 943             this.bound = bound;
 944             this.lower = lower;
 945         }
 946 
 947         @Override
 948         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
 949             return v.visitTypeVar(this, s);
 950         }
 951 
 952         public Type getUpperBound() { return bound; }
 953 
 954         int rank_field = -1;
 955 
 956         public Type getLowerBound() {
 957             return lower;
 958         }
 959 
 960         public TypeKind getKind() {
 961             return TypeKind.TYPEVAR;
 962         }
 963 
 964         public boolean isCaptured() {
 965             return false;
 966         }
 967 
 968         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 969             return v.visitTypeVariable(this, p);
 970         }
 971     }
 972 
 973     /** A captured type variable comes from wildcards which can have
 974      *  both upper and lower bound.  CapturedType extends TypeVar with
 975      *  a lower bound.
 976      */
 977     public static class CapturedType extends TypeVar {
 978 
 979         public Type lower;
 980         public WildcardType wildcard;
 981 
 982         public CapturedType(Name name,
 983                             Symbol owner,
 984                             Type upper,
 985                             Type lower,
 986                             WildcardType wildcard) {
 987             super(name, owner, lower);
 988             assert lower != null;
 989             this.bound = upper;
 990             this.lower = lower;
 991             this.wildcard = wildcard;
 992         }
 993 
 994         @Override
 995         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
 996             return v.visitCapturedType(this, s);
 997         }
 998 
 999         public Type getLowerBound() {
1000             return lower;
1001         }
1002 
1003         @Override
1004         public boolean isCaptured() {
1005             return true;
1006         }
1007 
1008         @Override
1009         public String toString() {
1010             return "capture#"
1011                 + (hashCode() & 0xFFFFFFFFL) % Printer.PRIME
1012                 + " of "
1013                 + wildcard;
1014         }
1015     }
1016 
1017     public static abstract class DelegatedType extends Type {
1018         public Type qtype;
1019         public DelegatedType(int tag, Type qtype) {
1020             super(tag, qtype.tsym);
1021             this.qtype = qtype;
1022         }
1023         public String toString() { return qtype.toString(); }
1024         public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
1025         public Type getEnclosingType() { return qtype.getEnclosingType(); }
1026         public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
1027         public Type getReturnType() { return qtype.getReturnType(); }
1028         public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
1029         public List<Type> allparams() { return qtype.allparams(); }
1030         public Type getUpperBound() { return qtype.getUpperBound(); }
1031         public Object clone() { DelegatedType t = (DelegatedType)super.clone(); t.qtype = (Type)qtype.clone(); return t; }
1032         public boolean isErroneous() { return qtype.isErroneous(); }
1033     }
1034 
1035     public static class ForAll extends DelegatedType
1036             implements Cloneable, ExecutableType {
1037         public List<Type> tvars;
1038 
1039         public ForAll(List<Type> tvars, Type qtype) {
1040             super(FORALL, qtype);
1041             this.tvars = tvars;
1042         }
1043 
1044         @Override
1045         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1046             return v.visitForAll(this, s);
1047         }
1048 
1049         public String toString() {
1050             return "<" + tvars + ">" + qtype;
1051         }
1052 
1053         public List<Type> getTypeArguments()   { return tvars; }
1054 
1055         public void setThrown(List<Type> t) {
1056             qtype.setThrown(t);
1057         }
1058 
1059         public Object clone() {
1060             ForAll result = (ForAll)super.clone();
1061             result.qtype = (Type)result.qtype.clone();
1062             return result;
1063         }
1064 
1065         public boolean isErroneous()  {
1066             return qtype.isErroneous();
1067         }
1068 
1069         /**
1070          * Replaces this ForAll's typevars with a set of concrete Java types
1071          * and returns the instantiated generic type. Subclasses should override
1072          * in order to check that the list of types is a valid instantiation
1073          * of the ForAll's typevars.
1074          *
1075          * @param actuals list of actual types
1076          * @param types types instance
1077          * @return qtype where all occurrences of tvars are replaced
1078          * by types in actuals
1079          */
1080         public Type inst(List<Type> actuals, Types types) {
1081             return types.subst(qtype, tvars, actuals);
1082         }
1083 
1084         /**
1085          * Kind of type-constraint derived during type inference
1086          */
1087         public enum ConstraintKind {
1088             /**
1089              * upper bound constraint (a type variable must be instantiated
1090              * with a type T, where T is a subtype of all the types specified by
1091              * its EXTENDS constraints).
1092              */
1093             EXTENDS,
1094             /**
1095              * lower bound constraint (a type variable must be instantiated
1096              * with a type T, where T is a supertype of all the types specified by
1097              * its SUPER constraints).
1098              */
1099             SUPER,
1100             /**
1101              * equality constraint (a type variable must be instantiated to the type
1102              * specified by its EQUAL constraint.
1103              */
1104             EQUAL;
1105         }
1106 
1107         /**
1108          * Get the type-constraints of a given kind for a given type-variable of
1109          * this ForAll type. Subclasses should override in order to return more
1110          * accurate sets of constraints.
1111          *
1112          * @param tv the type-variable for which the constraint is to be retrieved
1113          * @param ck the constraint kind to be retrieved
1114          * @return the list of types specified by the selected constraint
1115          */
1116         public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
1117             return List.nil();
1118         }
1119 
1120         public Type map(Mapping f) {
1121             return f.apply(qtype);
1122         }
1123 
1124         public boolean contains(Type elem) {
1125             return qtype.contains(elem);
1126         }
1127 
1128         public MethodType asMethodType() {
1129             return qtype.asMethodType();
1130         }
1131 
1132         public void complete() {
1133             for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
1134                 ((TypeVar)l.head).bound.complete();
1135             }
1136             qtype.complete();
1137         }
1138 
1139         public List<TypeVar> getTypeVariables() {
1140             return List.convert(TypeVar.class, getTypeArguments());
1141         }
1142 
1143         public TypeKind getKind() {
1144             return TypeKind.EXECUTABLE;
1145         }
1146 
1147         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1148             return v.visitExecutable(this, p);
1149         }
1150     }
1151 
1152     /** A class for instantiatable variables, for use during type
1153      *  inference.
1154      */
1155     public static class UndetVar extends DelegatedType {
1156         public List<Type> lobounds = List.nil();
1157         public List<Type> hibounds = List.nil();
1158         public Type inst = null;
1159 
1160         @Override
1161         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1162             return v.visitUndetVar(this, s);
1163         }
1164 
1165         public UndetVar(Type origin) {
1166             super(UNDETVAR, origin);
1167         }
1168 
1169         public String toString() {
1170             if (inst != null) return inst.toString();
1171             else return qtype + "?";
1172         }
1173 
1174         public Type baseType() {
1175             if (inst != null) return inst.baseType();
1176             else return this;
1177         }
1178     }
1179 
1180     /** Represents VOID or NONE.
1181      */
1182     static class JCNoType extends Type implements NoType {
1183         public JCNoType(int tag) {
1184             super(tag, null);
1185         }
1186 
1187         @Override
1188         public TypeKind getKind() {
1189             switch (tag) {
1190             case VOID:  return TypeKind.VOID;
1191             case NONE:  return TypeKind.NONE;
1192             default:
1193                 throw new AssertionError("Unexpected tag: " + tag);
1194             }
1195         }
1196 
1197         @Override
1198         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1199             return v.visitNoType(this, p);
1200         }
1201     }
1202 
1203     static class BottomType extends Type implements NullType {
1204         public BottomType() {
1205             super(TypeTags.BOT, null);
1206         }
1207 
1208         @Override
1209         public TypeKind getKind() {
1210             return TypeKind.NULL;
1211         }
1212 
1213         @Override
1214         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1215             return v.visitNull(this, p);
1216         }
1217 
1218         @Override
1219         public Type constType(Object value) {
1220             return this;
1221         }
1222 
1223         @Override
1224         public String stringValue() {
1225             return "null";
1226         }
1227     }
1228 
1229     public static class ErrorType extends ClassType
1230             implements javax.lang.model.type.ErrorType {
1231 
1232         private Type originalType = null;
1233 
1234         public ErrorType(Type originalType, TypeSymbol tsym) {
1235             super(noType, List.<Type>nil(), null);
1236             tag = ERROR;
1237             this.tsym = tsym;
1238             this.originalType = (originalType == null ? noType : originalType);
1239         }
1240 
1241         public ErrorType(ClassSymbol c, Type originalType) {
1242             this(originalType, c);
1243             c.type = this;
1244             c.kind = ERR;
1245             c.members_field = new Scope.ErrorScope(c);
1246         }
1247 
1248         public ErrorType(Name name, TypeSymbol container, Type originalType) {
1249             this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
1250         }
1251 
1252         @Override
1253         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1254             return v.visitErrorType(this, s);
1255         }
1256 
1257         public Type constType(Object constValue) { return this; }
1258         public Type getEnclosingType()          { return this; }
1259         public Type getReturnType()              { return this; }
1260         public Type asSub(Symbol sym)            { return this; }
1261         public Type map(Mapping f)               { return this; }
1262 
1263         public boolean isGenType(Type t)         { return true; }
1264         public boolean isErroneous()             { return true; }
1265         public boolean isCompound()              { return false; }
1266         public boolean isInterface()             { return false; }
1267 
1268         public List<Type> allparams()            { return List.nil(); }
1269         public List<Type> getTypeArguments()     { return List.nil(); }
1270 
1271         public TypeKind getKind() {
1272             return TypeKind.ERROR;
1273         }
1274 
1275         public Type getOriginalType() {
1276             return originalType;
1277         }
1278 
1279         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1280             return v.visitError(this, p);
1281         }
1282     }
1283 
1284     /**
1285      * A visitor for types.  A visitor is used to implement operations
1286      * (or relations) on types.  Most common operations on types are
1287      * binary relations and this interface is designed for binary
1288      * relations, that is, operations on the form
1289      * Type&nbsp;&times;&nbsp;S&nbsp;&rarr;&nbsp;R.
1290      * <!-- In plain text: Type x S -> R -->
1291      *
1292      * @param <R> the return type of the operation implemented by this
1293      * visitor; use Void if no return type is needed.
1294      * @param <S> the type of the second argument (the first being the
1295      * type itself) of the operation implemented by this visitor; use
1296      * Void if a second argument is not needed.
1297      */
1298     public interface Visitor<R,S> {
1299         R visitClassType(ClassType t, S s);
1300         R visitWildcardType(WildcardType t, S s);
1301         R visitArrayType(ArrayType t, S s);
1302         R visitMethodType(MethodType t, S s);
1303         R visitPackageType(PackageType t, S s);
1304         R visitTypeVar(TypeVar t, S s);
1305         R visitCapturedType(CapturedType t, S s);
1306         R visitForAll(ForAll t, S s);
1307         R visitUndetVar(UndetVar t, S s);
1308         R visitErrorType(ErrorType t, S s);
1309         R visitType(Type t, S s);
1310     }
1311 }