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

Wed, 27 Apr 2016 01:34:52 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:34:52 +0800
changeset 0
959103a6100f
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17

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

mercurial