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

Fri, 11 Oct 2013 15:49:15 +0200

author
jlahoda
date
Fri, 11 Oct 2013 15:49:15 +0200
changeset 2108
872c4a898b38
parent 2100
1e7ad879f15e
child 2134
b0c086cd4520
permissions
-rw-r--r--

6278240: Exception from AnnotationValue.getValue() should list the found type not the required type
Reviewed-by: darcy, jfranck, jjg

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

mercurial