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

Tue, 15 Oct 2013 15:57:13 -0700

author
jjg
date
Tue, 15 Oct 2013 15:57:13 -0700
changeset 2134
b0c086cd4520
parent 2108
872c4a898b38
child 2200
7c89d200781b
permissions
-rw-r--r--

8026564: import changes from type-annotations forest
Reviewed-by: jjg
Contributed-by: wdietl@gmail.com, steve.sides@oracle.com

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

mercurial