1 /* 2 * Copyright 1999-2009 Sun Microsystems, Inc. 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. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 package com.sun.tools.javac.code; 27 28 import com.sun.tools.javac.util.*; 29 import com.sun.tools.javac.code.Symbol.*; 30 31 import javax.lang.model.type.*; 32 33 import static com.sun.tools.javac.code.Flags.*; 34 import static com.sun.tools.javac.code.Kinds.*; 35 import static com.sun.tools.javac.code.BoundKind.*; 36 import static com.sun.tools.javac.code.TypeTags.*; 37 38 /** This class represents Java types. The class itself defines the behavior of 39 * the following types: 40 * <pre> 41 * base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN), 42 * type `void' (tag: VOID), 43 * the bottom type (tag: BOT), 44 * the missing type (tag: NONE). 45 * </pre> 46 * <p>The behavior of the following types is defined in subclasses, which are 47 * all static inner classes of this class: 48 * <pre> 49 * class types (tag: CLASS, class: ClassType), 50 * array types (tag: ARRAY, class: ArrayType), 51 * method types (tag: METHOD, class: MethodType), 52 * package types (tag: PACKAGE, class: PackageType), 53 * type variables (tag: TYPEVAR, class: TypeVar), 54 * type arguments (tag: WILDCARD, class: WildcardType), 55 * polymorphic types (tag: FORALL, class: ForAll), 56 * the error type (tag: ERROR, class: ErrorType). 57 * </pre> 58 * 59 * <p><b>This is NOT part of any API supported by Sun Microsystems. If 60 * you write code that depends on this, you do so at your own risk. 61 * This code and its internal interfaces are subject to change or 62 * deletion without notice.</b> 63 * 64 * @see TypeTags 65 */ 66 public class Type implements PrimitiveType { 67 68 /** Constant type: no type at all. */ 69 public static final JCNoType noType = new JCNoType(NONE); 70 71 /** If this switch is turned on, the names of type variables 72 * and anonymous classes are printed with hashcodes appended. 73 */ 74 public static boolean moreInfo = false; 75 76 /** The tag of this type. 77 * 78 * @see TypeTags 79 */ 80 public int tag; 81 82 /** The defining class / interface / package / type variable 83 */ 84 public TypeSymbol tsym; 85 86 /** 87 * The constant value of this type, null if this type does not 88 * have a constant value attribute. Only primitive types and 89 * strings (ClassType) can have a constant value attribute. 90 * @return the constant value attribute of this type 91 */ 92 public Object constValue() { 93 return null; 94 } 95 96 public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); } 97 98 /** Define a type given its tag and type symbol 99 */ 100 public Type(int tag, TypeSymbol tsym) { 101 this.tag = tag; 102 this.tsym = tsym; 103 } 104 105 /** An abstract class for mappings from types to types 106 */ 107 public static abstract class Mapping { 108 private String name; 109 public Mapping(String name) { 110 this.name = name; 111 } 112 public abstract Type apply(Type t); 113 public String toString() { 114 return name; 115 } 116 } 117 118 /** map a type function over all immediate descendants of this type 119 */ 120 public Type map(Mapping f) { 121 return this; 122 } 123 124 /** map a type function over a list of types 125 */ 126 public static List<Type> map(List<Type> ts, Mapping f) { 127 if (ts.nonEmpty()) { 128 List<Type> tail1 = map(ts.tail, f); 129 Type t = f.apply(ts.head); 130 if (tail1 != ts.tail || t != ts.head) 131 return tail1.prepend(t); 132 } 133 return ts; 134 } 135 136 /** Define a constant type, of the same kind as this type 137 * and with given constant value 138 */ 139 public Type constType(Object constValue) { 140 final Object value = constValue; 141 assert tag <= BOOLEAN; 142 return new Type(tag, tsym) { 143 @Override 144 public Object constValue() { 145 return value; 146 } 147 @Override 148 public Type baseType() { 149 return tsym.type; 150 } 151 }; 152 } 153 154 /** 155 * If this is a constant type, return its underlying type. 156 * Otherwise, return the type itself. 157 */ 158 public Type baseType() { 159 return this; 160 } 161 162 /** Return the base types of a list of types. 163 */ 164 public static List<Type> baseTypes(List<Type> ts) { 165 if (ts.nonEmpty()) { 166 Type t = ts.head.baseType(); 167 List<Type> baseTypes = baseTypes(ts.tail); 168 if (t != ts.head || baseTypes != ts.tail) 169 return baseTypes.prepend(t); 170 } 171 return ts; 172 } 173 174 /** The Java source which this type represents. 175 */ 176 public String toString() { 177 String s = (tsym == null || tsym.name == null) 178 ? "<none>" 179 : tsym.name.toString(); 180 if (moreInfo && tag == TYPEVAR) s = s + hashCode(); 181 return s; 182 } 183 184 /** 185 * The Java source which this type list represents. A List is 186 * represented as a comma-spearated listing of the elements in 187 * that list. 188 */ 189 public static String toString(List<Type> ts) { 190 if (ts.isEmpty()) { 191 return ""; 192 } else { 193 StringBuffer buf = new StringBuffer(); 194 buf.append(ts.head.toString()); 195 for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail) 196 buf.append(",").append(l.head.toString()); 197 return buf.toString(); 198 } 199 } 200 201 /** 202 * The constant value of this type, converted to String 203 */ 204 public String stringValue() { 205 assert constValue() != null; 206 if (tag == BOOLEAN) 207 return ((Integer) constValue()).intValue() == 0 ? "false" : "true"; 208 else if (tag == CHAR) 209 return String.valueOf((char) ((Integer) constValue()).intValue()); 210 else 211 return constValue().toString(); 212 } 213 214 /** 215 * This method is analogous to isSameType, but weaker, since we 216 * never complete classes. Where isSameType would complete a 217 * class, equals assumes that the two types are different. 218 */ 219 public boolean equals(Object t) { 220 return super.equals(t); 221 } 222 223 public int hashCode() { 224 return super.hashCode(); 225 } 226 227 /** Is this a constant type whose value is false? 228 */ 229 public boolean isFalse() { 230 return 231 tag == BOOLEAN && 232 constValue() != null && 233 ((Integer)constValue()).intValue() == 0; 234 } 235 236 /** Is this a constant type whose value is true? 237 */ 238 public boolean isTrue() { 239 return 240 tag == BOOLEAN && 241 constValue() != null && 242 ((Integer)constValue()).intValue() != 0; 243 } 244 245 public String argtypes(boolean varargs) { 246 List<Type> args = getParameterTypes(); 247 if (!varargs) return args.toString(); 248 StringBuffer buf = new StringBuffer(); 249 while (args.tail.nonEmpty()) { 250 buf.append(args.head); 251 args = args.tail; 252 buf.append(','); 253 } 254 if (args.head.tag == ARRAY) { 255 buf.append(((ArrayType)args.head).elemtype); 256 buf.append("..."); 257 } else { 258 buf.append(args.head); 259 } 260 return buf.toString(); 261 } 262 263 /** Access methods. 264 */ 265 public List<Type> getTypeArguments() { return List.nil(); } 266 public Type getEnclosingType() { return null; } 267 public List<Type> getParameterTypes() { return List.nil(); } 268 public Type getReturnType() { return null; } 269 public List<Type> getThrownTypes() { return List.nil(); } 270 public Type getUpperBound() { return null; } 271 public Type getLowerBound() { return null; } 272 273 public void setThrown(List<Type> ts) { 274 throw new AssertionError(); 275 } 276 277 /** Navigation methods, these will work for classes, type variables, 278 * foralls, but will return null for arrays and methods. 279 */ 280 281 /** Return all parameters of this type and all its outer types in order 282 * outer (first) to inner (last). 283 */ 284 public List<Type> allparams() { return List.nil(); } 285 286 /** Does this type contain "error" elements? 287 */ 288 public boolean isErroneous() { 289 return false; 290 } 291 292 public static boolean isErroneous(List<Type> ts) { 293 for (List<Type> l = ts; l.nonEmpty(); l = l.tail) 294 if (l.head.isErroneous()) return true; 295 return false; 296 } 297 298 /** Is this type parameterized? 299 * A class type is parameterized if it has some parameters. 300 * An array type is parameterized if its element type is parameterized. 301 * All other types are not parameterized. 302 */ 303 public boolean isParameterized() { 304 return false; 305 } 306 307 /** Is this type a raw type? 308 * A class type is a raw type if it misses some of its parameters. 309 * An array type is a raw type if its element type is raw. 310 * All other types are not raw. 311 * Type validation will ensure that the only raw types 312 * in a program are types that miss all their type variables. 313 */ 314 public boolean isRaw() { 315 return false; 316 } 317 318 public boolean isCompound() { 319 return tsym.completer == null 320 // Compound types can't have a completer. Calling 321 // flags() will complete the symbol causing the 322 // compiler to load classes unnecessarily. This led 323 // to regression 6180021. 324 && (tsym.flags() & COMPOUND) != 0; 325 } 326 327 public boolean isInterface() { 328 return (tsym.flags() & INTERFACE) != 0; 329 } 330 331 public boolean isPrimitive() { 332 return tag < VOID; 333 } 334 335 /** 336 * Does this type contain occurrences of type t? 337 */ 338 public boolean contains(Type t) { 339 return t == this; 340 } 341 342 public static boolean contains(List<Type> ts, Type t) { 343 for (List<Type> l = ts; 344 l.tail != null /*inlined: l.nonEmpty()*/; 345 l = l.tail) 346 if (l.head.contains(t)) return true; 347 return false; 348 } 349 350 /** Does this type contain an occurrence of some type in `elems'? 351 */ 352 public boolean containsSome(List<Type> ts) { 353 for (List<Type> l = ts; l.nonEmpty(); l = l.tail) 354 if (this.contains(ts.head)) return true; 355 return false; 356 } 357 358 public boolean isSuperBound() { return false; } 359 public boolean isExtendsBound() { return false; } 360 public boolean isUnbound() { return false; } 361 public Type withTypeVar(Type t) { return this; } 362 363 /** The underlying method type of this type. 364 */ 365 public MethodType asMethodType() { throw new AssertionError(); } 366 367 /** Complete loading all classes in this type. 368 */ 369 public void complete() {} 370 371 public Object clone() { 372 try { 373 return super.clone(); 374 } catch (CloneNotSupportedException e) { 375 throw new AssertionError(e); 376 } 377 } 378 379 public TypeSymbol asElement() { 380 return tsym; 381 } 382 383 public TypeKind getKind() { 384 switch (tag) { 385 case BYTE: return TypeKind.BYTE; 386 case CHAR: return TypeKind.CHAR; 387 case SHORT: return TypeKind.SHORT; 388 case INT: return TypeKind.INT; 389 case LONG: return TypeKind.LONG; 390 case FLOAT: return TypeKind.FLOAT; 391 case DOUBLE: return TypeKind.DOUBLE; 392 case BOOLEAN: return TypeKind.BOOLEAN; 393 case VOID: return TypeKind.VOID; 394 case BOT: return TypeKind.NULL; 395 case NONE: return TypeKind.NONE; 396 default: return TypeKind.OTHER; 397 } 398 } 399 400 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 401 if (isPrimitive()) 402 return v.visitPrimitive(this, p); 403 else 404 throw new AssertionError(); 405 } 406 407 public static class WildcardType extends Type 408 implements javax.lang.model.type.WildcardType { 409 410 public Type type; 411 public BoundKind kind; 412 public TypeVar bound; 413 414 @Override 415 public <R,S> R accept(Type.Visitor<R,S> v, S s) { 416 return v.visitWildcardType(this, s); 417 } 418 419 public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) { 420 super(WILDCARD, tsym); 421 assert(type != null); 422 this.kind = kind; 423 this.type = type; 424 } 425 public WildcardType(WildcardType t, TypeVar bound) { 426 this(t.type, t.kind, t.tsym, bound); 427 } 428 429 public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, TypeVar bound) { 430 this(type, kind, tsym); 431 this.bound = bound; 432 } 433 434 public boolean isSuperBound() { 435 return kind == SUPER || 436 kind == UNBOUND; 437 } 438 public boolean isExtendsBound() { 439 return kind == EXTENDS || 440 kind == UNBOUND; 441 } 442 public boolean isUnbound() { 443 return kind == UNBOUND; 444 } 445 446 public Type withTypeVar(Type t) { 447 //-System.err.println(this+".withTypeVar("+t+");");//DEBUG 448 if (bound == t) 449 return this; 450 bound = (TypeVar)t; 451 return this; 452 } 453 454 boolean isPrintingBound = false; 455 public String toString() { 456 StringBuffer s = new StringBuffer(); 457 s.append(kind.toString()); 458 if (kind != UNBOUND) 459 s.append(type); 460 if (moreInfo && bound != null && !isPrintingBound) 461 try { 462 isPrintingBound = true; 463 s.append("{:").append(bound.bound).append(":}"); 464 } finally { 465 isPrintingBound = false; 466 } 467 return s.toString(); 468 } 469 470 public Type map(Mapping f) { 471 //- System.err.println(" (" + this + ").map(" + f + ")");//DEBUG 472 Type t = type; 473 if (t != null) 474 t = f.apply(t); 475 if (t == type) 476 return this; 477 else 478 return new WildcardType(t, kind, tsym, bound); 479 } 480 481 public Type getExtendsBound() { 482 if (kind == EXTENDS) 483 return type; 484 else 485 return null; 486 } 487 488 public Type getSuperBound() { 489 if (kind == SUPER) 490 return type; 491 else 492 return null; 493 } 494 495 public TypeKind getKind() { 496 return TypeKind.WILDCARD; 497 } 498 499 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 500 return v.visitWildcard(this, p); 501 } 502 } 503 504 public static class ClassType extends Type implements DeclaredType { 505 506 /** The enclosing type of this type. If this is the type of an inner 507 * class, outer_field refers to the type of its enclosing 508 * instance class, in all other cases it referes to noType. 509 */ 510 private Type outer_field; 511 512 /** The type parameters of this type (to be set once class is loaded). 513 */ 514 public List<Type> typarams_field; 515 516 /** A cache variable for the type parameters of this type, 517 * appended to all parameters of its enclosing class. 518 * @see #allparams 519 */ 520 public List<Type> allparams_field; 521 522 /** The supertype of this class (to be set once class is loaded). 523 */ 524 public Type supertype_field; 525 526 /** The interfaces of this class (to be set once class is loaded). 527 */ 528 public List<Type> interfaces_field; 529 530 public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) { 531 super(CLASS, tsym); 532 this.outer_field = outer; 533 this.typarams_field = typarams; 534 this.allparams_field = null; 535 this.supertype_field = null; 536 this.interfaces_field = null; 537 /* 538 // this can happen during error recovery 539 assert 540 outer.isParameterized() ? 541 typarams.length() == tsym.type.typarams().length() : 542 outer.isRaw() ? 543 typarams.length() == 0 : 544 true; 545 */ 546 } 547 548 @Override 549 public <R,S> R accept(Type.Visitor<R,S> v, S s) { 550 return v.visitClassType(this, s); 551 } 552 553 public Type constType(Object constValue) { 554 final Object value = constValue; 555 return new ClassType(getEnclosingType(), typarams_field, tsym) { 556 @Override 557 public Object constValue() { 558 return value; 559 } 560 @Override 561 public Type baseType() { 562 return tsym.type; 563 } 564 }; 565 } 566 567 /** The Java source which this type represents. 568 */ 569 public String toString() { 570 StringBuffer buf = new StringBuffer(); 571 if (getEnclosingType().tag == CLASS && tsym.owner.kind == TYP) { 572 buf.append(getEnclosingType().toString()); 573 buf.append("."); 574 buf.append(className(tsym, false)); 575 } else { 576 buf.append(className(tsym, true)); 577 } 578 if (getTypeArguments().nonEmpty()) { 579 buf.append('<'); 580 buf.append(getTypeArguments().toString()); 581 buf.append(">"); 582 } 583 return buf.toString(); 584 } 585 //where 586 private String className(Symbol sym, boolean longform) { 587 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) { 588 StringBuffer s = new StringBuffer(supertype_field.toString()); 589 for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) { 590 s.append("&"); 591 s.append(is.head.toString()); 592 } 593 return s.toString(); 594 } else if (sym.name.isEmpty()) { 595 String s; 596 ClassType norm = (ClassType) tsym.type; 597 if (norm == null) { 598 s = Log.getLocalizedString("anonymous.class", (Object)null); 599 } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) { 600 s = Log.getLocalizedString("anonymous.class", 601 norm.interfaces_field.head); 602 } else { 603 s = Log.getLocalizedString("anonymous.class", 604 norm.supertype_field); 605 } 606 if (moreInfo) 607 s += String.valueOf(sym.hashCode()); 608 return s; 609 } else if (longform) { 610 return sym.getQualifiedName().toString(); 611 } else { 612 return sym.name.toString(); 613 } 614 } 615 616 public List<Type> getTypeArguments() { 617 if (typarams_field == null) { 618 complete(); 619 if (typarams_field == null) 620 typarams_field = List.nil(); 621 } 622 return typarams_field; 623 } 624 625 public boolean hasErasedSupertypes() { 626 return isRaw(); 627 } 628 629 public Type getEnclosingType() { 630 return outer_field; 631 } 632 633 public void setEnclosingType(Type outer) { 634 outer_field = outer; 635 } 636 637 public List<Type> allparams() { 638 if (allparams_field == null) { 639 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams()); 640 } 641 return allparams_field; 642 } 643 644 public boolean isErroneous() { 645 return 646 getEnclosingType().isErroneous() || 647 isErroneous(getTypeArguments()) || 648 this != tsym.type && tsym.type.isErroneous(); 649 } 650 651 public boolean isParameterized() { 652 return allparams().tail != null; 653 // optimization, was: allparams().nonEmpty(); 654 } 655 656 /** A cache for the rank. */ 657 int rank_field = -1; 658 659 /** A class type is raw if it misses some 660 * of its type parameter sections. 661 * After validation, this is equivalent to: 662 * allparams.isEmpty() && tsym.type.allparams.nonEmpty(); 663 */ 664 public boolean isRaw() { 665 return 666 this != tsym.type && // necessary, but not sufficient condition 667 tsym.type.allparams().nonEmpty() && 668 allparams().isEmpty(); 669 } 670 671 public Type map(Mapping f) { 672 Type outer = getEnclosingType(); 673 Type outer1 = f.apply(outer); 674 List<Type> typarams = getTypeArguments(); 675 List<Type> typarams1 = map(typarams, f); 676 if (outer1 == outer && typarams1 == typarams) return this; 677 else return new ClassType(outer1, typarams1, tsym); 678 } 679 680 public boolean contains(Type elem) { 681 return 682 elem == this 683 || (isParameterized() 684 && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem))); 685 } 686 687 public void complete() { 688 if (tsym.completer != null) tsym.complete(); 689 } 690 691 public TypeKind getKind() { 692 return TypeKind.DECLARED; 693 } 694 695 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 696 return v.visitDeclared(this, p); 697 } 698 } 699 700 public static class ErasedClassType extends ClassType { 701 public ErasedClassType(Type outer, TypeSymbol tsym) { 702 super(outer, List.<Type>nil(), tsym); 703 } 704 705 @Override 706 public boolean hasErasedSupertypes() { 707 return true; 708 } 709 } 710 711 public static class ArrayType extends Type 712 implements javax.lang.model.type.ArrayType { 713 714 public Type elemtype; 715 716 public ArrayType(Type elemtype, TypeSymbol arrayClass) { 717 super(ARRAY, arrayClass); 718 this.elemtype = elemtype; 719 } 720 721 @Override 722 public <R,S> R accept(Type.Visitor<R,S> v, S s) { 723 return v.visitArrayType(this, s); 724 } 725 726 public String toString() { 727 return elemtype + "[]"; 728 } 729 730 public boolean equals(Object obj) { 731 return 732 this == obj || 733 (obj instanceof ArrayType && 734 this.elemtype.equals(((ArrayType)obj).elemtype)); 735 } 736 737 public int hashCode() { 738 return (ARRAY << 5) + elemtype.hashCode(); 739 } 740 741 public List<Type> allparams() { return elemtype.allparams(); } 742 743 public boolean isErroneous() { 744 return elemtype.isErroneous(); 745 } 746 747 public boolean isParameterized() { 748 return elemtype.isParameterized(); 749 } 750 751 public boolean isRaw() { 752 return elemtype.isRaw(); 753 } 754 755 public Type map(Mapping f) { 756 Type elemtype1 = f.apply(elemtype); 757 if (elemtype1 == elemtype) return this; 758 else return new ArrayType(elemtype1, tsym); 759 } 760 761 public boolean contains(Type elem) { 762 return elem == this || elemtype.contains(elem); 763 } 764 765 public void complete() { 766 elemtype.complete(); 767 } 768 769 public Type getComponentType() { 770 return elemtype; 771 } 772 773 public TypeKind getKind() { 774 return TypeKind.ARRAY; 775 } 776 777 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 778 return v.visitArray(this, p); 779 } 780 } 781 782 public static class MethodType extends Type 783 implements Cloneable, ExecutableType { 784 785 public List<Type> argtypes; 786 public Type restype; 787 public List<Type> thrown; 788 789 public MethodType(List<Type> argtypes, 790 Type restype, 791 List<Type> thrown, 792 TypeSymbol methodClass) { 793 super(METHOD, methodClass); 794 this.argtypes = argtypes; 795 this.restype = restype; 796 this.thrown = thrown; 797 } 798 799 @Override 800 public <R,S> R accept(Type.Visitor<R,S> v, S s) { 801 return v.visitMethodType(this, s); 802 } 803 804 /** The Java source which this type represents. 805 * 806 * XXX 06/09/99 iris This isn't correct Java syntax, but it probably 807 * should be. 808 */ 809 public String toString() { 810 return "(" + argtypes + ")" + restype; 811 } 812 813 public boolean equals(Object obj) { 814 if (this == obj) 815 return true; 816 if (!(obj instanceof MethodType)) 817 return false; 818 MethodType m = (MethodType)obj; 819 List<Type> args1 = argtypes; 820 List<Type> args2 = m.argtypes; 821 while (!args1.isEmpty() && !args2.isEmpty()) { 822 if (!args1.head.equals(args2.head)) 823 return false; 824 args1 = args1.tail; 825 args2 = args2.tail; 826 } 827 if (!args1.isEmpty() || !args2.isEmpty()) 828 return false; 829 return restype.equals(m.restype); 830 } 831 832 public int hashCode() { 833 int h = METHOD; 834 for (List<Type> thisargs = this.argtypes; 835 thisargs.tail != null; /*inlined: thisargs.nonEmpty()*/ 836 thisargs = thisargs.tail) 837 h = (h << 5) + thisargs.head.hashCode(); 838 return (h << 5) + this.restype.hashCode(); 839 } 840 841 public List<Type> getParameterTypes() { return argtypes; } 842 public Type getReturnType() { return restype; } 843 public List<Type> getThrownTypes() { return thrown; } 844 845 public void setThrown(List<Type> t) { 846 thrown = t; 847 } 848 849 public boolean isErroneous() { 850 return 851 isErroneous(argtypes) || 852 restype != null && restype.isErroneous(); 853 } 854 855 public Type map(Mapping f) { 856 List<Type> argtypes1 = map(argtypes, f); 857 Type restype1 = f.apply(restype); 858 List<Type> thrown1 = map(thrown, f); 859 if (argtypes1 == argtypes && 860 restype1 == restype && 861 thrown1 == thrown) return this; 862 else return new MethodType(argtypes1, restype1, thrown1, tsym); 863 } 864 865 public boolean contains(Type elem) { 866 return elem == this || contains(argtypes, elem) || restype.contains(elem); 867 } 868 869 public MethodType asMethodType() { return this; } 870 871 public void complete() { 872 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail) 873 l.head.complete(); 874 restype.complete(); 875 for (List<Type> l = thrown; l.nonEmpty(); l = l.tail) 876 l.head.complete(); 877 } 878 879 public List<TypeVar> getTypeVariables() { 880 return List.nil(); 881 } 882 883 public TypeSymbol asElement() { 884 return null; 885 } 886 887 public TypeKind getKind() { 888 return TypeKind.EXECUTABLE; 889 } 890 891 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 892 return v.visitExecutable(this, p); 893 } 894 } 895 896 public static class PackageType extends Type implements NoType { 897 898 PackageType(TypeSymbol tsym) { 899 super(PACKAGE, tsym); 900 } 901 902 @Override 903 public <R,S> R accept(Type.Visitor<R,S> v, S s) { 904 return v.visitPackageType(this, s); 905 } 906 907 public String toString() { 908 return tsym.getQualifiedName().toString(); 909 } 910 911 public TypeKind getKind() { 912 return TypeKind.PACKAGE; 913 } 914 915 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 916 return v.visitNoType(this, p); 917 } 918 } 919 920 public static class TypeVar extends Type implements TypeVariable { 921 922 /** The bound of this type variable; set from outside. 923 * Must be nonempty once it is set. 924 * For a bound, `bound' is the bound type itself. 925 * Multiple bounds are expressed as a single class type which has the 926 * individual bounds as superclass, respectively interfaces. 927 * The class type then has as `tsym' a compiler generated class `c', 928 * which has a flag COMPOUND and whose owner is the type variable 929 * itself. Furthermore, the erasure_field of the class 930 * points to the first class or interface bound. 931 */ 932 public Type bound = null; 933 public Type lower; 934 935 public TypeVar(Name name, Symbol owner, Type lower) { 936 super(TYPEVAR, null); 937 tsym = new TypeSymbol(0, name, this, owner); 938 this.lower = lower; 939 } 940 941 public TypeVar(TypeSymbol tsym, Type bound, Type lower) { 942 super(TYPEVAR, tsym); 943 this.bound = bound; 944 this.lower = lower; 945 } 946 947 @Override 948 public <R,S> R accept(Type.Visitor<R,S> v, S s) { 949 return v.visitTypeVar(this, s); 950 } 951 952 public Type getUpperBound() { return bound; } 953 954 int rank_field = -1; 955 956 public Type getLowerBound() { 957 return lower; 958 } 959 960 public TypeKind getKind() { 961 return TypeKind.TYPEVAR; 962 } 963 964 public boolean isCaptured() { 965 return false; 966 } 967 968 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 969 return v.visitTypeVariable(this, p); 970 } 971 } 972 973 /** A captured type variable comes from wildcards which can have 974 * both upper and lower bound. CapturedType extends TypeVar with 975 * a lower bound. 976 */ 977 public static class CapturedType extends TypeVar { 978 979 public Type lower; 980 public WildcardType wildcard; 981 982 public CapturedType(Name name, 983 Symbol owner, 984 Type upper, 985 Type lower, 986 WildcardType wildcard) { 987 super(name, owner, lower); 988 assert lower != null; 989 this.bound = upper; 990 this.lower = lower; 991 this.wildcard = wildcard; 992 } 993 994 @Override 995 public <R,S> R accept(Type.Visitor<R,S> v, S s) { 996 return v.visitCapturedType(this, s); 997 } 998 999 public Type getLowerBound() { 1000 return lower; 1001 } 1002 1003 @Override 1004 public boolean isCaptured() { 1005 return true; 1006 } 1007 1008 @Override 1009 public String toString() { 1010 return "capture#" 1011 + (hashCode() & 0xFFFFFFFFL) % Printer.PRIME 1012 + " of " 1013 + wildcard; 1014 } 1015 } 1016 1017 public static abstract class DelegatedType extends Type { 1018 public Type qtype; 1019 public DelegatedType(int tag, Type qtype) { 1020 super(tag, qtype.tsym); 1021 this.qtype = qtype; 1022 } 1023 public String toString() { return qtype.toString(); } 1024 public List<Type> getTypeArguments() { return qtype.getTypeArguments(); } 1025 public Type getEnclosingType() { return qtype.getEnclosingType(); } 1026 public List<Type> getParameterTypes() { return qtype.getParameterTypes(); } 1027 public Type getReturnType() { return qtype.getReturnType(); } 1028 public List<Type> getThrownTypes() { return qtype.getThrownTypes(); } 1029 public List<Type> allparams() { return qtype.allparams(); } 1030 public Type getUpperBound() { return qtype.getUpperBound(); } 1031 public Object clone() { DelegatedType t = (DelegatedType)super.clone(); t.qtype = (Type)qtype.clone(); return t; } 1032 public boolean isErroneous() { return qtype.isErroneous(); } 1033 } 1034 1035 public static class ForAll extends DelegatedType 1036 implements Cloneable, ExecutableType { 1037 public List<Type> tvars; 1038 1039 public ForAll(List<Type> tvars, Type qtype) { 1040 super(FORALL, qtype); 1041 this.tvars = tvars; 1042 } 1043 1044 @Override 1045 public <R,S> R accept(Type.Visitor<R,S> v, S s) { 1046 return v.visitForAll(this, s); 1047 } 1048 1049 public String toString() { 1050 return "<" + tvars + ">" + qtype; 1051 } 1052 1053 public List<Type> getTypeArguments() { return tvars; } 1054 1055 public void setThrown(List<Type> t) { 1056 qtype.setThrown(t); 1057 } 1058 1059 public Object clone() { 1060 ForAll result = (ForAll)super.clone(); 1061 result.qtype = (Type)result.qtype.clone(); 1062 return result; 1063 } 1064 1065 public boolean isErroneous() { 1066 return qtype.isErroneous(); 1067 } 1068 1069 /** 1070 * Replaces this ForAll's typevars with a set of concrete Java types 1071 * and returns the instantiated generic type. Subclasses should override 1072 * in order to check that the list of types is a valid instantiation 1073 * of the ForAll's typevars. 1074 * 1075 * @param actuals list of actual types 1076 * @param types types instance 1077 * @return qtype where all occurrences of tvars are replaced 1078 * by types in actuals 1079 */ 1080 public Type inst(List<Type> actuals, Types types) { 1081 return types.subst(qtype, tvars, actuals); 1082 } 1083 1084 /** 1085 * Kind of type-constraint derived during type inference 1086 */ 1087 public enum ConstraintKind { 1088 /** 1089 * upper bound constraint (a type variable must be instantiated 1090 * with a type T, where T is a subtype of all the types specified by 1091 * its EXTENDS constraints). 1092 */ 1093 EXTENDS, 1094 /** 1095 * lower bound constraint (a type variable must be instantiated 1096 * with a type T, where T is a supertype of all the types specified by 1097 * its SUPER constraints). 1098 */ 1099 SUPER, 1100 /** 1101 * equality constraint (a type variable must be instantiated to the type 1102 * specified by its EQUAL constraint. 1103 */ 1104 EQUAL; 1105 } 1106 1107 /** 1108 * Get the type-constraints of a given kind for a given type-variable of 1109 * this ForAll type. Subclasses should override in order to return more 1110 * accurate sets of constraints. 1111 * 1112 * @param tv the type-variable for which the constraint is to be retrieved 1113 * @param ck the constraint kind to be retrieved 1114 * @return the list of types specified by the selected constraint 1115 */ 1116 public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) { 1117 return List.nil(); 1118 } 1119 1120 public Type map(Mapping f) { 1121 return f.apply(qtype); 1122 } 1123 1124 public boolean contains(Type elem) { 1125 return qtype.contains(elem); 1126 } 1127 1128 public MethodType asMethodType() { 1129 return qtype.asMethodType(); 1130 } 1131 1132 public void complete() { 1133 for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) { 1134 ((TypeVar)l.head).bound.complete(); 1135 } 1136 qtype.complete(); 1137 } 1138 1139 public List<TypeVar> getTypeVariables() { 1140 return List.convert(TypeVar.class, getTypeArguments()); 1141 } 1142 1143 public TypeKind getKind() { 1144 return TypeKind.EXECUTABLE; 1145 } 1146 1147 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 1148 return v.visitExecutable(this, p); 1149 } 1150 } 1151 1152 /** A class for instantiatable variables, for use during type 1153 * inference. 1154 */ 1155 public static class UndetVar extends DelegatedType { 1156 public List<Type> lobounds = List.nil(); 1157 public List<Type> hibounds = List.nil(); 1158 public Type inst = null; 1159 1160 @Override 1161 public <R,S> R accept(Type.Visitor<R,S> v, S s) { 1162 return v.visitUndetVar(this, s); 1163 } 1164 1165 public UndetVar(Type origin) { 1166 super(UNDETVAR, origin); 1167 } 1168 1169 public String toString() { 1170 if (inst != null) return inst.toString(); 1171 else return qtype + "?"; 1172 } 1173 1174 public Type baseType() { 1175 if (inst != null) return inst.baseType(); 1176 else return this; 1177 } 1178 } 1179 1180 /** Represents VOID or NONE. 1181 */ 1182 static class JCNoType extends Type implements NoType { 1183 public JCNoType(int tag) { 1184 super(tag, null); 1185 } 1186 1187 @Override 1188 public TypeKind getKind() { 1189 switch (tag) { 1190 case VOID: return TypeKind.VOID; 1191 case NONE: return TypeKind.NONE; 1192 default: 1193 throw new AssertionError("Unexpected tag: " + tag); 1194 } 1195 } 1196 1197 @Override 1198 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 1199 return v.visitNoType(this, p); 1200 } 1201 } 1202 1203 static class BottomType extends Type implements NullType { 1204 public BottomType() { 1205 super(TypeTags.BOT, null); 1206 } 1207 1208 @Override 1209 public TypeKind getKind() { 1210 return TypeKind.NULL; 1211 } 1212 1213 @Override 1214 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 1215 return v.visitNull(this, p); 1216 } 1217 1218 @Override 1219 public Type constType(Object value) { 1220 return this; 1221 } 1222 1223 @Override 1224 public String stringValue() { 1225 return "null"; 1226 } 1227 } 1228 1229 public static class ErrorType extends ClassType 1230 implements javax.lang.model.type.ErrorType { 1231 1232 private Type originalType = null; 1233 1234 public ErrorType(Type originalType, TypeSymbol tsym) { 1235 super(noType, List.<Type>nil(), null); 1236 tag = ERROR; 1237 this.tsym = tsym; 1238 this.originalType = (originalType == null ? noType : originalType); 1239 } 1240 1241 public ErrorType(ClassSymbol c, Type originalType) { 1242 this(originalType, c); 1243 c.type = this; 1244 c.kind = ERR; 1245 c.members_field = new Scope.ErrorScope(c); 1246 } 1247 1248 public ErrorType(Name name, TypeSymbol container, Type originalType) { 1249 this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType); 1250 } 1251 1252 @Override 1253 public <R,S> R accept(Type.Visitor<R,S> v, S s) { 1254 return v.visitErrorType(this, s); 1255 } 1256 1257 public Type constType(Object constValue) { return this; } 1258 public Type getEnclosingType() { return this; } 1259 public Type getReturnType() { return this; } 1260 public Type asSub(Symbol sym) { return this; } 1261 public Type map(Mapping f) { return this; } 1262 1263 public boolean isGenType(Type t) { return true; } 1264 public boolean isErroneous() { return true; } 1265 public boolean isCompound() { return false; } 1266 public boolean isInterface() { return false; } 1267 1268 public List<Type> allparams() { return List.nil(); } 1269 public List<Type> getTypeArguments() { return List.nil(); } 1270 1271 public TypeKind getKind() { 1272 return TypeKind.ERROR; 1273 } 1274 1275 public Type getOriginalType() { 1276 return originalType; 1277 } 1278 1279 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 1280 return v.visitError(this, p); 1281 } 1282 } 1283 1284 /** 1285 * A visitor for types. A visitor is used to implement operations 1286 * (or relations) on types. Most common operations on types are 1287 * binary relations and this interface is designed for binary 1288 * relations, that is, operations on the form 1289 * Type × S → R. 1290 * <!-- In plain text: Type x S -> R --> 1291 * 1292 * @param <R> the return type of the operation implemented by this 1293 * visitor; use Void if no return type is needed. 1294 * @param <S> the type of the second argument (the first being the 1295 * type itself) of the operation implemented by this visitor; use 1296 * Void if a second argument is not needed. 1297 */ 1298 public interface Visitor<R,S> { 1299 R visitClassType(ClassType t, S s); 1300 R visitWildcardType(WildcardType t, S s); 1301 R visitArrayType(ArrayType t, S s); 1302 R visitMethodType(MethodType t, S s); 1303 R visitPackageType(PackageType t, S s); 1304 R visitTypeVar(TypeVar t, S s); 1305 R visitCapturedType(CapturedType t, S s); 1306 R visitForAll(ForAll t, S s); 1307 R visitUndetVar(UndetVar t, S s); 1308 R visitErrorType(ErrorType t, S s); 1309 R visitType(Type t, S s); 1310 } 1311 }