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