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