src/share/classes/com/sun/tools/javac/code/Type.java

Fri, 12 Apr 2013 12:05:04 +0200

author
jfranck
date
Fri, 12 Apr 2013 12:05:04 +0200
changeset 1689
137994c189e5
parent 1678
c635a966ce84
child 1755
ddb4a2bfcd82
permissions
-rw-r--r--

7015104: use new subtype of TypeSymbol for type parameters
Reviewed-by: jjg, mcimadamore

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

mercurial