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