1 /* 2 * Copyright 2003-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 java.lang.ref.SoftReference; 29 import java.util.*; 30 31 import com.sun.tools.javac.util.*; 32 import com.sun.tools.javac.util.List; 33 34 import com.sun.tools.javac.jvm.ClassReader; 35 import com.sun.tools.javac.comp.Check; 36 37 import static com.sun.tools.javac.code.Type.*; 38 import static com.sun.tools.javac.code.TypeTags.*; 39 import static com.sun.tools.javac.code.Symbol.*; 40 import static com.sun.tools.javac.code.Flags.*; 41 import static com.sun.tools.javac.code.BoundKind.*; 42 import static com.sun.tools.javac.util.ListBuffer.lb; 43 44 /** 45 * Utility class containing various operations on types. 46 * 47 * <p>Unless other names are more illustrative, the following naming 48 * conventions should be observed in this file: 49 * 50 * <dl> 51 * <dt>t</dt> 52 * <dd>If the first argument to an operation is a type, it should be named t.</dd> 53 * <dt>s</dt> 54 * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd> 55 * <dt>ts</dt> 56 * <dd>If an operations takes a list of types, the first should be named ts.</dd> 57 * <dt>ss</dt> 58 * <dd>A second list of types should be named ss.</dd> 59 * </dl> 60 * 61 * <p><b>This is NOT part of any API supported by Sun Microsystems. 62 * If you write code that depends on this, you do so at your own risk. 63 * This code and its internal interfaces are subject to change or 64 * deletion without notice.</b> 65 */ 66 public class Types { 67 protected static final Context.Key<Types> typesKey = 68 new Context.Key<Types>(); 69 70 final Symtab syms; 71 final JavacMessages messages; 72 final Names names; 73 final boolean allowBoxing; 74 final ClassReader reader; 75 final Source source; 76 final Check chk; 77 List<Warner> warnStack = List.nil(); 78 final Name capturedName; 79 80 // <editor-fold defaultstate="collapsed" desc="Instantiating"> 81 public static Types instance(Context context) { 82 Types instance = context.get(typesKey); 83 if (instance == null) 84 instance = new Types(context); 85 return instance; 86 } 87 88 protected Types(Context context) { 89 context.put(typesKey, this); 90 syms = Symtab.instance(context); 91 names = Names.instance(context); 92 allowBoxing = Source.instance(context).allowBoxing(); 93 reader = ClassReader.instance(context); 94 source = Source.instance(context); 95 chk = Check.instance(context); 96 capturedName = names.fromString("<captured wildcard>"); 97 messages = JavacMessages.instance(context); 98 } 99 // </editor-fold> 100 101 // <editor-fold defaultstate="collapsed" desc="upperBound"> 102 /** 103 * The "rvalue conversion".<br> 104 * The upper bound of most types is the type 105 * itself. Wildcards, on the other hand have upper 106 * and lower bounds. 107 * @param t a type 108 * @return the upper bound of the given type 109 */ 110 public Type upperBound(Type t) { 111 return upperBound.visit(t); 112 } 113 // where 114 private final MapVisitor<Void> upperBound = new MapVisitor<Void>() { 115 116 @Override 117 public Type visitWildcardType(WildcardType t, Void ignored) { 118 if (t.isSuperBound()) 119 return t.bound == null ? syms.objectType : t.bound.bound; 120 else 121 return visit(t.type); 122 } 123 124 @Override 125 public Type visitCapturedType(CapturedType t, Void ignored) { 126 return visit(t.bound); 127 } 128 }; 129 // </editor-fold> 130 131 // <editor-fold defaultstate="collapsed" desc="lowerBound"> 132 /** 133 * The "lvalue conversion".<br> 134 * The lower bound of most types is the type 135 * itself. Wildcards, on the other hand have upper 136 * and lower bounds. 137 * @param t a type 138 * @return the lower bound of the given type 139 */ 140 public Type lowerBound(Type t) { 141 return lowerBound.visit(t); 142 } 143 // where 144 private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() { 145 146 @Override 147 public Type visitWildcardType(WildcardType t, Void ignored) { 148 return t.isExtendsBound() ? syms.botType : visit(t.type); 149 } 150 151 @Override 152 public Type visitCapturedType(CapturedType t, Void ignored) { 153 return visit(t.getLowerBound()); 154 } 155 }; 156 // </editor-fold> 157 158 // <editor-fold defaultstate="collapsed" desc="isUnbounded"> 159 /** 160 * Checks that all the arguments to a class are unbounded 161 * wildcards or something else that doesn't make any restrictions 162 * on the arguments. If a class isUnbounded, a raw super- or 163 * subclass can be cast to it without a warning. 164 * @param t a type 165 * @return true iff the given type is unbounded or raw 166 */ 167 public boolean isUnbounded(Type t) { 168 return isUnbounded.visit(t); 169 } 170 // where 171 private final UnaryVisitor<Boolean> isUnbounded = new UnaryVisitor<Boolean>() { 172 173 public Boolean visitType(Type t, Void ignored) { 174 return true; 175 } 176 177 @Override 178 public Boolean visitClassType(ClassType t, Void ignored) { 179 List<Type> parms = t.tsym.type.allparams(); 180 List<Type> args = t.allparams(); 181 while (parms.nonEmpty()) { 182 WildcardType unb = new WildcardType(syms.objectType, 183 BoundKind.UNBOUND, 184 syms.boundClass, 185 (TypeVar)parms.head); 186 if (!containsType(args.head, unb)) 187 return false; 188 parms = parms.tail; 189 args = args.tail; 190 } 191 return true; 192 } 193 }; 194 // </editor-fold> 195 196 // <editor-fold defaultstate="collapsed" desc="asSub"> 197 /** 198 * Return the least specific subtype of t that starts with symbol 199 * sym. If none exists, return null. The least specific subtype 200 * is determined as follows: 201 * 202 * <p>If there is exactly one parameterized instance of sym that is a 203 * subtype of t, that parameterized instance is returned.<br> 204 * Otherwise, if the plain type or raw type `sym' is a subtype of 205 * type t, the type `sym' itself is returned. Otherwise, null is 206 * returned. 207 */ 208 public Type asSub(Type t, Symbol sym) { 209 return asSub.visit(t, sym); 210 } 211 // where 212 private final SimpleVisitor<Type,Symbol> asSub = new SimpleVisitor<Type,Symbol>() { 213 214 public Type visitType(Type t, Symbol sym) { 215 return null; 216 } 217 218 @Override 219 public Type visitClassType(ClassType t, Symbol sym) { 220 if (t.tsym == sym) 221 return t; 222 Type base = asSuper(sym.type, t.tsym); 223 if (base == null) 224 return null; 225 ListBuffer<Type> from = new ListBuffer<Type>(); 226 ListBuffer<Type> to = new ListBuffer<Type>(); 227 try { 228 adapt(base, t, from, to); 229 } catch (AdaptFailure ex) { 230 return null; 231 } 232 Type res = subst(sym.type, from.toList(), to.toList()); 233 if (!isSubtype(res, t)) 234 return null; 235 ListBuffer<Type> openVars = new ListBuffer<Type>(); 236 for (List<Type> l = sym.type.allparams(); 237 l.nonEmpty(); l = l.tail) 238 if (res.contains(l.head) && !t.contains(l.head)) 239 openVars.append(l.head); 240 if (openVars.nonEmpty()) { 241 if (t.isRaw()) { 242 // The subtype of a raw type is raw 243 res = erasure(res); 244 } else { 245 // Unbound type arguments default to ? 246 List<Type> opens = openVars.toList(); 247 ListBuffer<Type> qs = new ListBuffer<Type>(); 248 for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) { 249 qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head)); 250 } 251 res = subst(res, opens, qs.toList()); 252 } 253 } 254 return res; 255 } 256 257 @Override 258 public Type visitErrorType(ErrorType t, Symbol sym) { 259 return t; 260 } 261 }; 262 // </editor-fold> 263 264 // <editor-fold defaultstate="collapsed" desc="isConvertible"> 265 /** 266 * Is t a subtype of or convertiable via boxing/unboxing 267 * convertions to s? 268 */ 269 public boolean isConvertible(Type t, Type s, Warner warn) { 270 boolean tPrimitive = t.isPrimitive(); 271 boolean sPrimitive = s.isPrimitive(); 272 if (tPrimitive == sPrimitive) 273 return isSubtypeUnchecked(t, s, warn); 274 if (!allowBoxing) return false; 275 return tPrimitive 276 ? isSubtype(boxedClass(t).type, s) 277 : isSubtype(unboxedType(t), s); 278 } 279 280 /** 281 * Is t a subtype of or convertiable via boxing/unboxing 282 * convertions to s? 283 */ 284 public boolean isConvertible(Type t, Type s) { 285 return isConvertible(t, s, Warner.noWarnings); 286 } 287 // </editor-fold> 288 289 // <editor-fold defaultstate="collapsed" desc="isSubtype"> 290 /** 291 * Is t an unchecked subtype of s? 292 */ 293 public boolean isSubtypeUnchecked(Type t, Type s) { 294 return isSubtypeUnchecked(t, s, Warner.noWarnings); 295 } 296 /** 297 * Is t an unchecked subtype of s? 298 */ 299 public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) { 300 if (t.tag == ARRAY && s.tag == ARRAY) { 301 return (((ArrayType)t).elemtype.tag <= lastBaseTag) 302 ? isSameType(elemtype(t), elemtype(s)) 303 : isSubtypeUnchecked(elemtype(t), elemtype(s), warn); 304 } else if (isSubtype(t, s)) { 305 return true; 306 } 307 else if (t.tag == TYPEVAR) { 308 return isSubtypeUnchecked(t.getUpperBound(), s, warn); 309 } 310 else if (s.tag == UNDETVAR) { 311 UndetVar uv = (UndetVar)s; 312 if (uv.inst != null) 313 return isSubtypeUnchecked(t, uv.inst, warn); 314 } 315 else if (!s.isRaw()) { 316 Type t2 = asSuper(t, s.tsym); 317 if (t2 != null && t2.isRaw()) { 318 if (isReifiable(s)) 319 warn.silentUnchecked(); 320 else 321 warn.warnUnchecked(); 322 return true; 323 } 324 } 325 return false; 326 } 327 328 /** 329 * Is t a subtype of s?<br> 330 * (not defined for Method and ForAll types) 331 */ 332 final public boolean isSubtype(Type t, Type s) { 333 return isSubtype(t, s, true); 334 } 335 final public boolean isSubtypeNoCapture(Type t, Type s) { 336 return isSubtype(t, s, false); 337 } 338 public boolean isSubtype(Type t, Type s, boolean capture) { 339 if (t == s) 340 return true; 341 342 if (s.tag >= firstPartialTag) 343 return isSuperType(s, t); 344 345 if (s.isCompound()) { 346 for (Type s2 : interfaces(s).prepend(supertype(s))) { 347 if (!isSubtype(t, s2, capture)) 348 return false; 349 } 350 return true; 351 } 352 353 Type lower = lowerBound(s); 354 if (s != lower) 355 return isSubtype(capture ? capture(t) : t, lower, false); 356 357 return isSubtype.visit(capture ? capture(t) : t, s); 358 } 359 // where 360 private TypeRelation isSubtype = new TypeRelation() 361 { 362 public Boolean visitType(Type t, Type s) { 363 switch (t.tag) { 364 case BYTE: case CHAR: 365 return (t.tag == s.tag || 366 t.tag + 2 <= s.tag && s.tag <= DOUBLE); 367 case SHORT: case INT: case LONG: case FLOAT: case DOUBLE: 368 return t.tag <= s.tag && s.tag <= DOUBLE; 369 case BOOLEAN: case VOID: 370 return t.tag == s.tag; 371 case TYPEVAR: 372 return isSubtypeNoCapture(t.getUpperBound(), s); 373 case BOT: 374 return 375 s.tag == BOT || s.tag == CLASS || 376 s.tag == ARRAY || s.tag == TYPEVAR || 377 s.tag == FUNCTION; 378 case NONE: 379 return false; 380 default: 381 throw new AssertionError("isSubtype " + t.tag); 382 } 383 } 384 385 private Set<TypePair> cache = new HashSet<TypePair>(); 386 387 private boolean containsTypeRecursive(Type t, Type s) { 388 TypePair pair = new TypePair(t, s); 389 if (cache.add(pair)) { 390 try { 391 return containsType(t.getTypeArguments(), 392 s.getTypeArguments()); 393 } finally { 394 cache.remove(pair); 395 } 396 } else { 397 return containsType(t.getTypeArguments(), 398 rewriteSupers(s).getTypeArguments()); 399 } 400 } 401 402 private Type rewriteSupers(Type t) { 403 if (!t.isParameterized()) 404 return t; 405 ListBuffer<Type> from = lb(); 406 ListBuffer<Type> to = lb(); 407 adaptSelf(t, from, to); 408 if (from.isEmpty()) 409 return t; 410 ListBuffer<Type> rewrite = lb(); 411 boolean changed = false; 412 for (Type orig : to.toList()) { 413 Type s = rewriteSupers(orig); 414 if (s.isSuperBound() && !s.isExtendsBound()) { 415 s = new WildcardType(syms.objectType, 416 BoundKind.UNBOUND, 417 syms.boundClass); 418 changed = true; 419 } else if (s != orig) { 420 s = new WildcardType(upperBound(s), 421 BoundKind.EXTENDS, 422 syms.boundClass); 423 changed = true; 424 } 425 rewrite.append(s); 426 } 427 if (changed) 428 return subst(t.tsym.type, from.toList(), rewrite.toList()); 429 else 430 return t; 431 } 432 433 @Override 434 public Boolean visitClassType(ClassType t, Type s) { 435 Type sup = asSuper(t, s.tsym); 436 return sup != null 437 && sup.tsym == s.tsym 438 // You're not allowed to write 439 // Vector<Object> vec = new Vector<String>(); 440 // But with wildcards you can write 441 // Vector<? extends Object> vec = new Vector<String>(); 442 // which means that subtype checking must be done 443 // here instead of same-type checking (via containsType). 444 && (!s.isParameterized() || containsTypeRecursive(s, sup)) 445 && isSubtypeNoCapture(sup.getEnclosingType(), 446 s.getEnclosingType()); 447 } 448 449 @Override 450 public Boolean visitMethodType(MethodType t, Type s) { 451 if (s.tsym == syms.objectType.tsym || s.tsym == syms.methodHandleType.tsym) 452 return true; 453 454 if (s.tag != FUNCTION) 455 return false; 456 457 //check covariance/contravariance 458 MethodType mType = (MethodType) s; 459 if (!(isSubtypeNoCapture(t.restype, mType.restype))) 460 return false; 461 462 List<Type> lt = t.argtypes; 463 List<Type> lmType = mType.argtypes; 464 while (lt.nonEmpty() && lmType.nonEmpty()) { 465 if (!(isSubtypeNoCapture(lmType.head, lt.head))) 466 return false; 467 lt = lt.tail; 468 lmType = lmType.tail; 469 } 470 return lt.isEmpty() && lmType.isEmpty(); 471 } 472 473 @Override 474 public Boolean visitArrayType(ArrayType t, Type s) { 475 if (s.tag == ARRAY) { 476 if (t.elemtype.tag <= lastBaseTag) 477 return isSameType(t.elemtype, elemtype(s)); 478 else 479 return isSubtypeNoCapture(t.elemtype, elemtype(s)); 480 } 481 482 if (s.tag == CLASS) { 483 Name sname = s.tsym.getQualifiedName(); 484 return sname == names.java_lang_Object 485 || sname == names.java_lang_Cloneable 486 || sname == names.java_io_Serializable; 487 } 488 489 return false; 490 } 491 492 @Override 493 public Boolean visitUndetVar(UndetVar t, Type s) { 494 //todo: test against origin needed? or replace with substitution? 495 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN) 496 return true; 497 498 if (t.inst != null) 499 return isSubtypeNoCapture(t.inst, s); // TODO: ", warn"? 500 501 t.hibounds = t.hibounds.prepend(s); 502 return true; 503 } 504 505 @Override 506 public Boolean visitErrorType(ErrorType t, Type s) { 507 return true; 508 } 509 }; 510 511 /** 512 * Is t a subtype of every type in given list `ts'?<br> 513 * (not defined for Method and ForAll types)<br> 514 * Allows unchecked conversions. 515 */ 516 public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) { 517 for (List<Type> l = ts; l.nonEmpty(); l = l.tail) 518 if (!isSubtypeUnchecked(t, l.head, warn)) 519 return false; 520 return true; 521 } 522 523 /** 524 * Are corresponding elements of ts subtypes of ss? If lists are 525 * of different length, return false. 526 */ 527 public boolean isSubtypes(List<Type> ts, List<Type> ss) { 528 while (ts.tail != null && ss.tail != null 529 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && 530 isSubtype(ts.head, ss.head)) { 531 ts = ts.tail; 532 ss = ss.tail; 533 } 534 return ts.tail == null && ss.tail == null; 535 /*inlined: ts.isEmpty() && ss.isEmpty();*/ 536 } 537 538 /** 539 * Are corresponding elements of ts subtypes of ss, allowing 540 * unchecked conversions? If lists are of different length, 541 * return false. 542 **/ 543 public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) { 544 while (ts.tail != null && ss.tail != null 545 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && 546 isSubtypeUnchecked(ts.head, ss.head, warn)) { 547 ts = ts.tail; 548 ss = ss.tail; 549 } 550 return ts.tail == null && ss.tail == null; 551 /*inlined: ts.isEmpty() && ss.isEmpty();*/ 552 } 553 // </editor-fold> 554 555 // <editor-fold defaultstate="collapsed" desc="isSuperType"> 556 /** 557 * Is t a supertype of s? 558 */ 559 public boolean isSuperType(Type t, Type s) { 560 switch (t.tag) { 561 case ERROR: 562 return true; 563 case UNDETVAR: { 564 UndetVar undet = (UndetVar)t; 565 if (t == s || 566 undet.qtype == s || 567 s.tag == ERROR || 568 s.tag == BOT) return true; 569 if (undet.inst != null) 570 return isSubtype(s, undet.inst); 571 undet.lobounds = undet.lobounds.prepend(s); 572 return true; 573 } 574 default: 575 return isSubtype(s, t); 576 } 577 } 578 // </editor-fold> 579 580 // <editor-fold defaultstate="collapsed" desc="isSameType"> 581 /** 582 * Are corresponding elements of the lists the same type? If 583 * lists are of different length, return false. 584 */ 585 public boolean isSameTypes(List<Type> ts, List<Type> ss) { 586 while (ts.tail != null && ss.tail != null 587 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && 588 isSameType(ts.head, ss.head)) { 589 ts = ts.tail; 590 ss = ss.tail; 591 } 592 return ts.tail == null && ss.tail == null; 593 /*inlined: ts.isEmpty() && ss.isEmpty();*/ 594 } 595 596 /** 597 * Is t the same type as s? 598 */ 599 public boolean isSameType(Type t, Type s) { 600 return isSameType.visit(t, s); 601 } 602 // where 603 private TypeRelation isSameType = new TypeRelation() { 604 605 public Boolean visitType(Type t, Type s) { 606 if (t == s) 607 return true; 608 609 if (s.tag >= firstPartialTag) 610 return visit(s, t); 611 612 switch (t.tag) { 613 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: 614 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE: 615 return t.tag == s.tag; 616 case TYPEVAR: 617 return s.isSuperBound() 618 && !s.isExtendsBound() 619 && visit(t, upperBound(s)); 620 default: 621 throw new AssertionError("isSameType " + t.tag); 622 } 623 } 624 625 @Override 626 public Boolean visitWildcardType(WildcardType t, Type s) { 627 if (s.tag >= firstPartialTag) 628 return visit(s, t); 629 else 630 return false; 631 } 632 633 @Override 634 public Boolean visitClassType(ClassType t, Type s) { 635 if (t == s) 636 return true; 637 638 if (s.tag >= firstPartialTag) 639 return visit(s, t); 640 641 if (s.isSuperBound() && !s.isExtendsBound()) 642 return visit(t, upperBound(s)) && visit(t, lowerBound(s)); 643 644 if (t.isCompound() && s.isCompound()) { 645 if (!visit(supertype(t), supertype(s))) 646 return false; 647 648 HashSet<SingletonType> set = new HashSet<SingletonType>(); 649 for (Type x : interfaces(t)) 650 set.add(new SingletonType(x)); 651 for (Type x : interfaces(s)) { 652 if (!set.remove(new SingletonType(x))) 653 return false; 654 } 655 return (set.size() == 0); 656 } 657 return t.tsym == s.tsym 658 && visit(t.getEnclosingType(), s.getEnclosingType()) 659 && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments()); 660 } 661 662 @Override 663 public Boolean visitArrayType(ArrayType t, Type s) { 664 if (t == s) 665 return true; 666 667 if (s.tag >= firstPartialTag) 668 return visit(s, t); 669 670 return s.tag == ARRAY 671 && containsTypeEquivalent(t.elemtype, elemtype(s)); 672 } 673 674 @Override 675 public Boolean visitMethodType(MethodType t, Type s) { 676 // isSameType for methods does not take thrown 677 // exceptions into account! 678 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType()); 679 } 680 681 @Override 682 public Boolean visitPackageType(PackageType t, Type s) { 683 return t == s; 684 } 685 686 @Override 687 public Boolean visitForAll(ForAll t, Type s) { 688 if (s.tag != FORALL) 689 return false; 690 691 ForAll forAll = (ForAll)s; 692 return hasSameBounds(t, forAll) 693 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars)); 694 } 695 696 @Override 697 public Boolean visitUndetVar(UndetVar t, Type s) { 698 if (s.tag == WILDCARD) 699 // FIXME, this might be leftovers from before capture conversion 700 return false; 701 702 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN) 703 return true; 704 705 if (t.inst != null) 706 return visit(t.inst, s); 707 708 t.inst = fromUnknownFun.apply(s); 709 for (List<Type> l = t.lobounds; l.nonEmpty(); l = l.tail) { 710 if (!isSubtype(l.head, t.inst)) 711 return false; 712 } 713 for (List<Type> l = t.hibounds; l.nonEmpty(); l = l.tail) { 714 if (!isSubtype(t.inst, l.head)) 715 return false; 716 } 717 return true; 718 } 719 720 @Override 721 public Boolean visitErrorType(ErrorType t, Type s) { 722 return true; 723 } 724 }; 725 // </editor-fold> 726 727 // <editor-fold defaultstate="collapsed" desc="fromUnknownFun"> 728 /** 729 * A mapping that turns all unknown types in this type to fresh 730 * unknown variables. 731 */ 732 public Mapping fromUnknownFun = new Mapping("fromUnknownFun") { 733 public Type apply(Type t) { 734 if (t.tag == UNKNOWN) return new UndetVar(t); 735 else return t.map(this); 736 } 737 }; 738 // </editor-fold> 739 740 // <editor-fold defaultstate="collapsed" desc="Contains Type"> 741 public boolean containedBy(Type t, Type s) { 742 switch (t.tag) { 743 case UNDETVAR: 744 if (s.tag == WILDCARD) { 745 UndetVar undetvar = (UndetVar)t; 746 WildcardType wt = (WildcardType)s; 747 switch(wt.kind) { 748 case UNBOUND: //similar to ? extends Object 749 case EXTENDS: { 750 Type bound = upperBound(s); 751 // We should check the new upper bound against any of the 752 // undetvar's lower bounds. 753 for (Type t2 : undetvar.lobounds) { 754 if (!isSubtype(t2, bound)) 755 return false; 756 } 757 undetvar.hibounds = undetvar.hibounds.prepend(bound); 758 break; 759 } 760 case SUPER: { 761 Type bound = lowerBound(s); 762 // We should check the new lower bound against any of the 763 // undetvar's lower bounds. 764 for (Type t2 : undetvar.hibounds) { 765 if (!isSubtype(bound, t2)) 766 return false; 767 } 768 undetvar.lobounds = undetvar.lobounds.prepend(bound); 769 break; 770 } 771 } 772 return true; 773 } else { 774 return isSameType(t, s); 775 } 776 case ERROR: 777 return true; 778 default: 779 return containsType(s, t); 780 } 781 } 782 783 boolean containsType(List<Type> ts, List<Type> ss) { 784 while (ts.nonEmpty() && ss.nonEmpty() 785 && containsType(ts.head, ss.head)) { 786 ts = ts.tail; 787 ss = ss.tail; 788 } 789 return ts.isEmpty() && ss.isEmpty(); 790 } 791 792 /** 793 * Check if t contains s. 794 * 795 * <p>T contains S if: 796 * 797 * <p>{@code L(T) <: L(S) && U(S) <: U(T)} 798 * 799 * <p>This relation is only used by ClassType.isSubtype(), that 800 * is, 801 * 802 * <p>{@code C<S> <: C<T> if T contains S.} 803 * 804 * <p>Because of F-bounds, this relation can lead to infinite 805 * recursion. Thus we must somehow break that recursion. Notice 806 * that containsType() is only called from ClassType.isSubtype(). 807 * Since the arguments have already been checked against their 808 * bounds, we know: 809 * 810 * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)} 811 * 812 * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)} 813 * 814 * @param t a type 815 * @param s a type 816 */ 817 public boolean containsType(Type t, Type s) { 818 return containsType.visit(t, s); 819 } 820 // where 821 private TypeRelation containsType = new TypeRelation() { 822 823 private Type U(Type t) { 824 while (t.tag == WILDCARD) { 825 WildcardType w = (WildcardType)t; 826 if (w.isSuperBound()) 827 return w.bound == null ? syms.objectType : w.bound.bound; 828 else 829 t = w.type; 830 } 831 return t; 832 } 833 834 private Type L(Type t) { 835 while (t.tag == WILDCARD) { 836 WildcardType w = (WildcardType)t; 837 if (w.isExtendsBound()) 838 return syms.botType; 839 else 840 t = w.type; 841 } 842 return t; 843 } 844 845 public Boolean visitType(Type t, Type s) { 846 if (s.tag >= firstPartialTag) 847 return containedBy(s, t); 848 else 849 return isSameType(t, s); 850 } 851 852 void debugContainsType(WildcardType t, Type s) { 853 System.err.println(); 854 System.err.format(" does %s contain %s?%n", t, s); 855 System.err.format(" %s U(%s) <: U(%s) %s = %s%n", 856 upperBound(s), s, t, U(t), 857 t.isSuperBound() 858 || isSubtypeNoCapture(upperBound(s), U(t))); 859 System.err.format(" %s L(%s) <: L(%s) %s = %s%n", 860 L(t), t, s, lowerBound(s), 861 t.isExtendsBound() 862 || isSubtypeNoCapture(L(t), lowerBound(s))); 863 System.err.println(); 864 } 865 866 @Override 867 public Boolean visitWildcardType(WildcardType t, Type s) { 868 if (s.tag >= firstPartialTag) 869 return containedBy(s, t); 870 else { 871 // debugContainsType(t, s); 872 return isSameWildcard(t, s) 873 || isCaptureOf(s, t) 874 || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) && 875 (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t)))); 876 } 877 } 878 879 @Override 880 public Boolean visitUndetVar(UndetVar t, Type s) { 881 if (s.tag != WILDCARD) 882 return isSameType(t, s); 883 else 884 return false; 885 } 886 887 @Override 888 public Boolean visitErrorType(ErrorType t, Type s) { 889 return true; 890 } 891 }; 892 893 public boolean isCaptureOf(Type s, WildcardType t) { 894 if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured()) 895 return false; 896 return isSameWildcard(t, ((CapturedType)s).wildcard); 897 } 898 899 public boolean isSameWildcard(WildcardType t, Type s) { 900 if (s.tag != WILDCARD) 901 return false; 902 WildcardType w = (WildcardType)s; 903 return w.kind == t.kind && w.type == t.type; 904 } 905 906 public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) { 907 while (ts.nonEmpty() && ss.nonEmpty() 908 && containsTypeEquivalent(ts.head, ss.head)) { 909 ts = ts.tail; 910 ss = ss.tail; 911 } 912 return ts.isEmpty() && ss.isEmpty(); 913 } 914 // </editor-fold> 915 916 // <editor-fold defaultstate="collapsed" desc="isCastable"> 917 public boolean isCastable(Type t, Type s) { 918 return isCastable(t, s, Warner.noWarnings); 919 } 920 921 /** 922 * Is t is castable to s?<br> 923 * s is assumed to be an erased type.<br> 924 * (not defined for Method and ForAll types). 925 */ 926 public boolean isCastable(Type t, Type s, Warner warn) { 927 if (t == s) 928 return true; 929 930 if (t.isPrimitive() != s.isPrimitive()) 931 return allowBoxing && isConvertible(t, s, warn); 932 933 if (warn != warnStack.head) { 934 try { 935 warnStack = warnStack.prepend(warn); 936 return isCastable.visit(t,s); 937 } finally { 938 warnStack = warnStack.tail; 939 } 940 } else { 941 return isCastable.visit(t,s); 942 } 943 } 944 // where 945 private TypeRelation isCastable = new TypeRelation() { 946 947 public Boolean visitType(Type t, Type s) { 948 if (s.tag == ERROR) 949 return true; 950 951 switch (t.tag) { 952 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: 953 case DOUBLE: 954 return s.tag <= DOUBLE; 955 case BOOLEAN: 956 return s.tag == BOOLEAN; 957 case VOID: 958 return false; 959 case BOT: 960 return isSubtype(t, s); 961 default: 962 throw new AssertionError(); 963 } 964 } 965 966 @Override 967 public Boolean visitWildcardType(WildcardType t, Type s) { 968 return isCastable(upperBound(t), s, warnStack.head); 969 } 970 971 @Override 972 public Boolean visitClassType(ClassType t, Type s) { 973 if (s.tag == ERROR || s.tag == BOT) 974 return true; 975 976 if (s.tag == TYPEVAR) { 977 if (isCastable(s.getUpperBound(), t, Warner.noWarnings)) { 978 warnStack.head.warnUnchecked(); 979 return true; 980 } else { 981 return false; 982 } 983 } 984 985 if (t.isCompound()) { 986 Warner oldWarner = warnStack.head; 987 warnStack.head = Warner.noWarnings; 988 if (!visit(supertype(t), s)) 989 return false; 990 for (Type intf : interfaces(t)) { 991 if (!visit(intf, s)) 992 return false; 993 } 994 if (warnStack.head.unchecked == true) 995 oldWarner.warnUnchecked(); 996 return true; 997 } 998 999 if (s.isCompound()) { 1000 // call recursively to reuse the above code 1001 return visitClassType((ClassType)s, t); 1002 } 1003 1004 if (s.tag == CLASS || s.tag == ARRAY) { 1005 boolean upcast; 1006 if ((upcast = isSubtype(erasure(t), erasure(s))) 1007 || isSubtype(erasure(s), erasure(t))) { 1008 if (!upcast && s.tag == ARRAY) { 1009 if (!isReifiable(s)) 1010 warnStack.head.warnUnchecked(); 1011 return true; 1012 } else if (s.isRaw()) { 1013 return true; 1014 } else if (t.isRaw()) { 1015 if (!isUnbounded(s)) 1016 warnStack.head.warnUnchecked(); 1017 return true; 1018 } 1019 // Assume |a| <: |b| 1020 final Type a = upcast ? t : s; 1021 final Type b = upcast ? s : t; 1022 final boolean HIGH = true; 1023 final boolean LOW = false; 1024 final boolean DONT_REWRITE_TYPEVARS = false; 1025 Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS); 1026 Type aLow = rewriteQuantifiers(a, LOW, DONT_REWRITE_TYPEVARS); 1027 Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS); 1028 Type bLow = rewriteQuantifiers(b, LOW, DONT_REWRITE_TYPEVARS); 1029 Type lowSub = asSub(bLow, aLow.tsym); 1030 Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym); 1031 if (highSub == null) { 1032 final boolean REWRITE_TYPEVARS = true; 1033 aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS); 1034 aLow = rewriteQuantifiers(a, LOW, REWRITE_TYPEVARS); 1035 bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS); 1036 bLow = rewriteQuantifiers(b, LOW, REWRITE_TYPEVARS); 1037 lowSub = asSub(bLow, aLow.tsym); 1038 highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym); 1039 } 1040 if (highSub != null) { 1041 assert a.tsym == highSub.tsym && a.tsym == lowSub.tsym 1042 : a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym; 1043 if (!disjointTypes(aHigh.allparams(), highSub.allparams()) 1044 && !disjointTypes(aHigh.allparams(), lowSub.allparams()) 1045 && !disjointTypes(aLow.allparams(), highSub.allparams()) 1046 && !disjointTypes(aLow.allparams(), lowSub.allparams())) { 1047 if (upcast ? giveWarning(a, b) : 1048 giveWarning(b, a)) 1049 warnStack.head.warnUnchecked(); 1050 return true; 1051 } 1052 } 1053 if (isReifiable(s)) 1054 return isSubtypeUnchecked(a, b); 1055 else 1056 return isSubtypeUnchecked(a, b, warnStack.head); 1057 } 1058 1059 // Sidecast 1060 if (s.tag == CLASS) { 1061 if ((s.tsym.flags() & INTERFACE) != 0) { 1062 return ((t.tsym.flags() & FINAL) == 0) 1063 ? sideCast(t, s, warnStack.head) 1064 : sideCastFinal(t, s, warnStack.head); 1065 } else if ((t.tsym.flags() & INTERFACE) != 0) { 1066 return ((s.tsym.flags() & FINAL) == 0) 1067 ? sideCast(t, s, warnStack.head) 1068 : sideCastFinal(t, s, warnStack.head); 1069 } else { 1070 // unrelated class types 1071 return false; 1072 } 1073 } 1074 } 1075 return false; 1076 } 1077 1078 @Override 1079 public Boolean visitArrayType(ArrayType t, Type s) { 1080 switch (s.tag) { 1081 case ERROR: 1082 case BOT: 1083 return true; 1084 case TYPEVAR: 1085 if (isCastable(s, t, Warner.noWarnings)) { 1086 warnStack.head.warnUnchecked(); 1087 return true; 1088 } else { 1089 return false; 1090 } 1091 case CLASS: 1092 return isSubtype(t, s); 1093 case ARRAY: 1094 if (elemtype(t).tag <= lastBaseTag) { 1095 return elemtype(t).tag == elemtype(s).tag; 1096 } else { 1097 return visit(elemtype(t), elemtype(s)); 1098 } 1099 default: 1100 return false; 1101 } 1102 } 1103 1104 @Override 1105 public Boolean visitTypeVar(TypeVar t, Type s) { 1106 switch (s.tag) { 1107 case ERROR: 1108 case BOT: 1109 return true; 1110 case TYPEVAR: 1111 if (isSubtype(t, s)) { 1112 return true; 1113 } else if (isCastable(t.bound, s, Warner.noWarnings)) { 1114 warnStack.head.warnUnchecked(); 1115 return true; 1116 } else { 1117 return false; 1118 } 1119 default: 1120 return isCastable(t.bound, s, warnStack.head); 1121 } 1122 } 1123 1124 @Override 1125 public Boolean visitMethodType(MethodType t, Type s) { 1126 if (isSubtype(t, s)) 1127 return true; 1128 if (s.tsym == syms.methodHandleType.tsym) { 1129 warnStack.head.warnUnchecked(); 1130 return true; 1131 } 1132 if (s.tag != METHOD) 1133 return false; 1134 return isCastable(s, t); 1135 } 1136 1137 @Override 1138 public Boolean visitErrorType(ErrorType t, Type s) { 1139 return true; 1140 } 1141 }; 1142 // </editor-fold> 1143 1144 // <editor-fold defaultstate="collapsed" desc="disjointTypes"> 1145 public boolean disjointTypes(List<Type> ts, List<Type> ss) { 1146 while (ts.tail != null && ss.tail != null) { 1147 if (disjointType(ts.head, ss.head)) return true; 1148 ts = ts.tail; 1149 ss = ss.tail; 1150 } 1151 return false; 1152 } 1153 1154 /** 1155 * Two types or wildcards are considered disjoint if it can be 1156 * proven that no type can be contained in both. It is 1157 * conservative in that it is allowed to say that two types are 1158 * not disjoint, even though they actually are. 1159 * 1160 * The type C<X> is castable to C<Y> exactly if X and Y are not 1161 * disjoint. 1162 */ 1163 public boolean disjointType(Type t, Type s) { 1164 return disjointType.visit(t, s); 1165 } 1166 // where 1167 private TypeRelation disjointType = new TypeRelation() { 1168 1169 private Set<TypePair> cache = new HashSet<TypePair>(); 1170 1171 public Boolean visitType(Type t, Type s) { 1172 if (s.tag == WILDCARD) 1173 return visit(s, t); 1174 else 1175 return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t); 1176 } 1177 1178 private boolean isCastableRecursive(Type t, Type s) { 1179 TypePair pair = new TypePair(t, s); 1180 if (cache.add(pair)) { 1181 try { 1182 return Types.this.isCastable(t, s); 1183 } finally { 1184 cache.remove(pair); 1185 } 1186 } else { 1187 return true; 1188 } 1189 } 1190 1191 private boolean notSoftSubtypeRecursive(Type t, Type s) { 1192 TypePair pair = new TypePair(t, s); 1193 if (cache.add(pair)) { 1194 try { 1195 return Types.this.notSoftSubtype(t, s); 1196 } finally { 1197 cache.remove(pair); 1198 } 1199 } else { 1200 return false; 1201 } 1202 } 1203 1204 @Override 1205 public Boolean visitWildcardType(WildcardType t, Type s) { 1206 if (t.isUnbound()) 1207 return false; 1208 1209 if (s.tag != WILDCARD) { 1210 if (t.isExtendsBound()) 1211 return notSoftSubtypeRecursive(s, t.type); 1212 else // isSuperBound() 1213 return notSoftSubtypeRecursive(t.type, s); 1214 } 1215 1216 if (s.isUnbound()) 1217 return false; 1218 1219 if (t.isExtendsBound()) { 1220 if (s.isExtendsBound()) 1221 return !isCastableRecursive(t.type, upperBound(s)); 1222 else if (s.isSuperBound()) 1223 return notSoftSubtypeRecursive(lowerBound(s), t.type); 1224 } else if (t.isSuperBound()) { 1225 if (s.isExtendsBound()) 1226 return notSoftSubtypeRecursive(t.type, upperBound(s)); 1227 } 1228 return false; 1229 } 1230 }; 1231 // </editor-fold> 1232 1233 // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes"> 1234 /** 1235 * Returns the lower bounds of the formals of a method. 1236 */ 1237 public List<Type> lowerBoundArgtypes(Type t) { 1238 return map(t.getParameterTypes(), lowerBoundMapping); 1239 } 1240 private final Mapping lowerBoundMapping = new Mapping("lowerBound") { 1241 public Type apply(Type t) { 1242 return lowerBound(t); 1243 } 1244 }; 1245 // </editor-fold> 1246 1247 // <editor-fold defaultstate="collapsed" desc="notSoftSubtype"> 1248 /** 1249 * This relation answers the question: is impossible that 1250 * something of type `t' can be a subtype of `s'? This is 1251 * different from the question "is `t' not a subtype of `s'?" 1252 * when type variables are involved: Integer is not a subtype of T 1253 * where <T extends Number> but it is not true that Integer cannot 1254 * possibly be a subtype of T. 1255 */ 1256 public boolean notSoftSubtype(Type t, Type s) { 1257 if (t == s) return false; 1258 if (t.tag == TYPEVAR) { 1259 TypeVar tv = (TypeVar) t; 1260 if (s.tag == TYPEVAR) 1261 s = s.getUpperBound(); 1262 return !isCastable(tv.bound, 1263 s, 1264 Warner.noWarnings); 1265 } 1266 if (s.tag != WILDCARD) 1267 s = upperBound(s); 1268 if (s.tag == TYPEVAR) 1269 s = s.getUpperBound(); 1270 1271 return !isSubtype(t, s); 1272 } 1273 // </editor-fold> 1274 1275 // <editor-fold defaultstate="collapsed" desc="isReifiable"> 1276 public boolean isReifiable(Type t) { 1277 return isReifiable.visit(t); 1278 } 1279 // where 1280 private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() { 1281 1282 public Boolean visitType(Type t, Void ignored) { 1283 return true; 1284 } 1285 1286 @Override 1287 public Boolean visitClassType(ClassType t, Void ignored) { 1288 if (t.isCompound()) 1289 return false; 1290 else { 1291 if (!t.isParameterized()) 1292 return true; 1293 1294 for (Type param : t.allparams()) { 1295 if (!param.isUnbound()) 1296 return false; 1297 } 1298 return true; 1299 } 1300 } 1301 1302 @Override 1303 public Boolean visitArrayType(ArrayType t, Void ignored) { 1304 return visit(t.elemtype); 1305 } 1306 1307 @Override 1308 public Boolean visitTypeVar(TypeVar t, Void ignored) { 1309 return false; 1310 } 1311 1312 @Override 1313 public Boolean visitMethodType(MethodType t, Void ignored) { 1314 if (!isReifiable(t.restype)) 1315 return false; 1316 for(List<Type> l = t.argtypes; l.isEmpty(); l = l.tail) { 1317 if (!isReifiable(l.head)) 1318 return false; 1319 } 1320 return true; 1321 } 1322 }; 1323 // </editor-fold> 1324 1325 // <editor-fold defaultstate="collapsed" desc="Array Utils"> 1326 public boolean isArray(Type t) { 1327 while (t.tag == WILDCARD) 1328 t = upperBound(t); 1329 return t.tag == ARRAY; 1330 } 1331 1332 /** 1333 * The element type of an array. 1334 */ 1335 public Type elemtype(Type t) { 1336 switch (t.tag) { 1337 case WILDCARD: 1338 return elemtype(upperBound(t)); 1339 case ARRAY: 1340 return ((ArrayType)t).elemtype; 1341 case FORALL: 1342 return elemtype(((ForAll)t).qtype); 1343 case ERROR: 1344 return t; 1345 default: 1346 return null; 1347 } 1348 } 1349 1350 /** 1351 * Mapping to take element type of an arraytype 1352 */ 1353 private Mapping elemTypeFun = new Mapping ("elemTypeFun") { 1354 public Type apply(Type t) { return elemtype(t); } 1355 }; 1356 1357 /** 1358 * The number of dimensions of an array type. 1359 */ 1360 public int dimensions(Type t) { 1361 int result = 0; 1362 while (t.tag == ARRAY) { 1363 result++; 1364 t = elemtype(t); 1365 } 1366 return result; 1367 } 1368 // </editor-fold> 1369 1370 // <editor-fold defaultstate="collapsed" desc="asSuper"> 1371 /** 1372 * Return the (most specific) base type of t that starts with the 1373 * given symbol. If none exists, return null. 1374 * 1375 * @param t a type 1376 * @param sym a symbol 1377 */ 1378 public Type asSuper(Type t, Symbol sym) { 1379 return asSuper.visit(t, sym); 1380 } 1381 // where 1382 private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() { 1383 1384 public Type visitType(Type t, Symbol sym) { 1385 return null; 1386 } 1387 1388 @Override 1389 public Type visitClassType(ClassType t, Symbol sym) { 1390 if (t.tsym == sym) 1391 return t; 1392 1393 Type st = supertype(t); 1394 if (st.tag == CLASS || st.tag == TYPEVAR || st.tag == ERROR) { 1395 Type x = asSuper(st, sym); 1396 if (x != null) 1397 return x; 1398 } 1399 if ((sym.flags() & INTERFACE) != 0) { 1400 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) { 1401 Type x = asSuper(l.head, sym); 1402 if (x != null) 1403 return x; 1404 } 1405 } 1406 return null; 1407 } 1408 1409 @Override 1410 public Type visitArrayType(ArrayType t, Symbol sym) { 1411 return isSubtype(t, sym.type) ? sym.type : null; 1412 } 1413 1414 @Override 1415 public Type visitTypeVar(TypeVar t, Symbol sym) { 1416 if (t.tsym == sym) 1417 return t; 1418 else 1419 return asSuper(t.bound, sym); 1420 } 1421 1422 @Override 1423 public Type visitErrorType(ErrorType t, Symbol sym) { 1424 return t; 1425 } 1426 }; 1427 1428 /** 1429 * Return the base type of t or any of its outer types that starts 1430 * with the given symbol. If none exists, return null. 1431 * 1432 * @param t a type 1433 * @param sym a symbol 1434 */ 1435 public Type asOuterSuper(Type t, Symbol sym) { 1436 switch (t.tag) { 1437 case CLASS: 1438 do { 1439 Type s = asSuper(t, sym); 1440 if (s != null) return s; 1441 t = t.getEnclosingType(); 1442 } while (t.tag == CLASS); 1443 return null; 1444 case ARRAY: 1445 return isSubtype(t, sym.type) ? sym.type : null; 1446 case TYPEVAR: 1447 return asSuper(t, sym); 1448 case ERROR: 1449 return t; 1450 default: 1451 return null; 1452 } 1453 } 1454 1455 /** 1456 * Return the base type of t or any of its enclosing types that 1457 * starts with the given symbol. If none exists, return null. 1458 * 1459 * @param t a type 1460 * @param sym a symbol 1461 */ 1462 public Type asEnclosingSuper(Type t, Symbol sym) { 1463 switch (t.tag) { 1464 case CLASS: 1465 do { 1466 Type s = asSuper(t, sym); 1467 if (s != null) return s; 1468 Type outer = t.getEnclosingType(); 1469 t = (outer.tag == CLASS) ? outer : 1470 (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type : 1471 Type.noType; 1472 } while (t.tag == CLASS); 1473 return null; 1474 case ARRAY: 1475 return isSubtype(t, sym.type) ? sym.type : null; 1476 case TYPEVAR: 1477 return asSuper(t, sym); 1478 case ERROR: 1479 return t; 1480 default: 1481 return null; 1482 } 1483 } 1484 // </editor-fold> 1485 1486 // <editor-fold defaultstate="collapsed" desc="memberType"> 1487 /** 1488 * The type of given symbol, seen as a member of t. 1489 * 1490 * @param t a type 1491 * @param sym a symbol 1492 */ 1493 public Type memberType(Type t, Symbol sym) { 1494 return (sym.flags() & STATIC) != 0 1495 ? sym.type 1496 : memberType.visit(t, sym); 1497 } 1498 // where 1499 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() { 1500 1501 public Type visitType(Type t, Symbol sym) { 1502 return sym.type; 1503 } 1504 1505 @Override 1506 public Type visitWildcardType(WildcardType t, Symbol sym) { 1507 return memberType(upperBound(t), sym); 1508 } 1509 1510 @Override 1511 public Type visitClassType(ClassType t, Symbol sym) { 1512 Symbol owner = sym.owner; 1513 long flags = sym.flags(); 1514 if (((flags & STATIC) == 0) && owner.type.isParameterized()) { 1515 Type base = asOuterSuper(t, owner); 1516 //if t is an intersection type T = CT & I1 & I2 ... & In 1517 //its supertypes CT, I1, ... In might contain wildcards 1518 //so we need to go through capture conversion 1519 base = t.isCompound() ? capture(base) : base; 1520 if (base != null) { 1521 List<Type> ownerParams = owner.type.allparams(); 1522 List<Type> baseParams = base.allparams(); 1523 if (ownerParams.nonEmpty()) { 1524 if (baseParams.isEmpty()) { 1525 // then base is a raw type 1526 return erasure(sym.type); 1527 } else { 1528 return subst(sym.type, ownerParams, baseParams); 1529 } 1530 } 1531 } 1532 } 1533 return sym.type; 1534 } 1535 1536 @Override 1537 public Type visitTypeVar(TypeVar t, Symbol sym) { 1538 return memberType(t.bound, sym); 1539 } 1540 1541 @Override 1542 public Type visitErrorType(ErrorType t, Symbol sym) { 1543 return t; 1544 } 1545 }; 1546 // </editor-fold> 1547 1548 // <editor-fold defaultstate="collapsed" desc="isAssignable"> 1549 public boolean isAssignable(Type t, Type s) { 1550 return isAssignable(t, s, Warner.noWarnings); 1551 } 1552 1553 /** 1554 * Is t assignable to s?<br> 1555 * Equivalent to subtype except for constant values and raw 1556 * types.<br> 1557 * (not defined for Method and ForAll types) 1558 */ 1559 public boolean isAssignable(Type t, Type s, Warner warn) { 1560 if (t.tag == ERROR) 1561 return true; 1562 if (t.tag <= INT && t.constValue() != null) { 1563 int value = ((Number)t.constValue()).intValue(); 1564 switch (s.tag) { 1565 case BYTE: 1566 if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE) 1567 return true; 1568 break; 1569 case CHAR: 1570 if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE) 1571 return true; 1572 break; 1573 case SHORT: 1574 if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE) 1575 return true; 1576 break; 1577 case INT: 1578 return true; 1579 case CLASS: 1580 switch (unboxedType(s).tag) { 1581 case BYTE: 1582 case CHAR: 1583 case SHORT: 1584 return isAssignable(t, unboxedType(s), warn); 1585 } 1586 break; 1587 } 1588 } 1589 return isConvertible(t, s, warn); 1590 } 1591 // </editor-fold> 1592 1593 // <editor-fold defaultstate="collapsed" desc="erasure"> 1594 /** 1595 * The erasure of t {@code |t|} -- the type that results when all 1596 * type parameters in t are deleted. 1597 */ 1598 public Type erasure(Type t) { 1599 return erasure(t, false); 1600 } 1601 //where 1602 private Type erasure(Type t, boolean recurse) { 1603 if (t.tag <= lastBaseTag) 1604 return t; /* fast special case */ 1605 else 1606 return erasure.visit(t, recurse); 1607 } 1608 // where 1609 private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() { 1610 public Type visitType(Type t, Boolean recurse) { 1611 if (t.tag <= lastBaseTag) 1612 return t; /*fast special case*/ 1613 else 1614 return t.map(recurse ? erasureRecFun : erasureFun); 1615 } 1616 1617 @Override 1618 public Type visitWildcardType(WildcardType t, Boolean recurse) { 1619 return erasure(upperBound(t), recurse); 1620 } 1621 1622 @Override 1623 public Type visitClassType(ClassType t, Boolean recurse) { 1624 Type erased = t.tsym.erasure(Types.this); 1625 if (recurse) { 1626 erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym); 1627 } 1628 return erased; 1629 } 1630 1631 @Override 1632 public Type visitTypeVar(TypeVar t, Boolean recurse) { 1633 return erasure(t.bound, recurse); 1634 } 1635 1636 @Override 1637 public Type visitMethodType(MethodType t, Boolean recurse) { 1638 if (t.tag == FUNCTION) 1639 return syms.methodHandleType; 1640 return super.visitMethodType(t, recurse); 1641 } 1642 1643 @Override 1644 public Type visitErrorType(ErrorType t, Boolean recurse) { 1645 return t; 1646 } 1647 }; 1648 1649 private Mapping erasureFun = new Mapping ("erasure") { 1650 public Type apply(Type t) { return erasure(t); } 1651 }; 1652 1653 private Mapping erasureRecFun = new Mapping ("erasureRecursive") { 1654 public Type apply(Type t) { return erasureRecursive(t); } 1655 }; 1656 1657 public List<Type> erasure(List<Type> ts) { 1658 return Type.map(ts, erasureFun); 1659 } 1660 1661 public Type erasureRecursive(Type t) { 1662 return erasure(t, true); 1663 } 1664 1665 public List<Type> erasureRecursive(List<Type> ts) { 1666 return Type.map(ts, erasureRecFun); 1667 } 1668 // </editor-fold> 1669 1670 // <editor-fold defaultstate="collapsed" desc="makeCompoundType"> 1671 /** 1672 * Make a compound type from non-empty list of types 1673 * 1674 * @param bounds the types from which the compound type is formed 1675 * @param supertype is objectType if all bounds are interfaces, 1676 * null otherwise. 1677 */ 1678 public Type makeCompoundType(List<Type> bounds, 1679 Type supertype) { 1680 ClassSymbol bc = 1681 new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC, 1682 Type.moreInfo 1683 ? names.fromString(bounds.toString()) 1684 : names.empty, 1685 syms.noSymbol); 1686 if (bounds.head.tag == TYPEVAR) 1687 // error condition, recover 1688 bc.erasure_field = syms.objectType; 1689 else 1690 bc.erasure_field = erasure(bounds.head); 1691 bc.members_field = new Scope(bc); 1692 ClassType bt = (ClassType)bc.type; 1693 bt.allparams_field = List.nil(); 1694 if (supertype != null) { 1695 bt.supertype_field = supertype; 1696 bt.interfaces_field = bounds; 1697 } else { 1698 bt.supertype_field = bounds.head; 1699 bt.interfaces_field = bounds.tail; 1700 } 1701 assert bt.supertype_field.tsym.completer != null 1702 || !bt.supertype_field.isInterface() 1703 : bt.supertype_field; 1704 return bt; 1705 } 1706 1707 /** 1708 * Same as {@link #makeCompoundType(List,Type)}, except that the 1709 * second parameter is computed directly. Note that this might 1710 * cause a symbol completion. Hence, this version of 1711 * makeCompoundType may not be called during a classfile read. 1712 */ 1713 public Type makeCompoundType(List<Type> bounds) { 1714 Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ? 1715 supertype(bounds.head) : null; 1716 return makeCompoundType(bounds, supertype); 1717 } 1718 1719 /** 1720 * A convenience wrapper for {@link #makeCompoundType(List)}; the 1721 * arguments are converted to a list and passed to the other 1722 * method. Note that this might cause a symbol completion. 1723 * Hence, this version of makeCompoundType may not be called 1724 * during a classfile read. 1725 */ 1726 public Type makeCompoundType(Type bound1, Type bound2) { 1727 return makeCompoundType(List.of(bound1, bound2)); 1728 } 1729 // </editor-fold> 1730 1731 // <editor-fold defaultstate="collapsed" desc="supertype"> 1732 public Type supertype(Type t) { 1733 return supertype.visit(t); 1734 } 1735 // where 1736 private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() { 1737 1738 public Type visitType(Type t, Void ignored) { 1739 // A note on wildcards: there is no good way to 1740 // determine a supertype for a super bounded wildcard. 1741 return null; 1742 } 1743 1744 @Override 1745 public Type visitClassType(ClassType t, Void ignored) { 1746 if (t.supertype_field == null) { 1747 Type supertype = ((ClassSymbol)t.tsym).getSuperclass(); 1748 // An interface has no superclass; its supertype is Object. 1749 if (t.isInterface()) 1750 supertype = ((ClassType)t.tsym.type).supertype_field; 1751 if (t.supertype_field == null) { 1752 List<Type> actuals = classBound(t).allparams(); 1753 List<Type> formals = t.tsym.type.allparams(); 1754 if (t.hasErasedSupertypes()) { 1755 t.supertype_field = erasureRecursive(supertype); 1756 } else if (formals.nonEmpty()) { 1757 t.supertype_field = subst(supertype, formals, actuals); 1758 } 1759 else { 1760 t.supertype_field = supertype; 1761 } 1762 } 1763 } 1764 return t.supertype_field; 1765 } 1766 1767 /** 1768 * The supertype is always a class type. If the type 1769 * variable's bounds start with a class type, this is also 1770 * the supertype. Otherwise, the supertype is 1771 * java.lang.Object. 1772 */ 1773 @Override 1774 public Type visitTypeVar(TypeVar t, Void ignored) { 1775 if (t.bound.tag == TYPEVAR || 1776 (!t.bound.isCompound() && !t.bound.isInterface())) { 1777 return t.bound; 1778 } else { 1779 return supertype(t.bound); 1780 } 1781 } 1782 1783 @Override 1784 public Type visitArrayType(ArrayType t, Void ignored) { 1785 if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType)) 1786 return arraySuperType(); 1787 else 1788 return new ArrayType(supertype(t.elemtype), t.tsym); 1789 } 1790 1791 @Override 1792 public Type visitErrorType(ErrorType t, Void ignored) { 1793 return t; 1794 } 1795 }; 1796 // </editor-fold> 1797 1798 // <editor-fold defaultstate="collapsed" desc="interfaces"> 1799 /** 1800 * Return the interfaces implemented by this class. 1801 */ 1802 public List<Type> interfaces(Type t) { 1803 return interfaces.visit(t); 1804 } 1805 // where 1806 private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() { 1807 1808 public List<Type> visitType(Type t, Void ignored) { 1809 return List.nil(); 1810 } 1811 1812 @Override 1813 public List<Type> visitClassType(ClassType t, Void ignored) { 1814 if (t.interfaces_field == null) { 1815 List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces(); 1816 if (t.interfaces_field == null) { 1817 // If t.interfaces_field is null, then t must 1818 // be a parameterized type (not to be confused 1819 // with a generic type declaration). 1820 // Terminology: 1821 // Parameterized type: List<String> 1822 // Generic type declaration: class List<E> { ... } 1823 // So t corresponds to List<String> and 1824 // t.tsym.type corresponds to List<E>. 1825 // The reason t must be parameterized type is 1826 // that completion will happen as a side 1827 // effect of calling 1828 // ClassSymbol.getInterfaces. Since 1829 // t.interfaces_field is null after 1830 // completion, we can assume that t is not the 1831 // type of a class/interface declaration. 1832 assert t != t.tsym.type : t.toString(); 1833 List<Type> actuals = t.allparams(); 1834 List<Type> formals = t.tsym.type.allparams(); 1835 if (t.hasErasedSupertypes()) { 1836 t.interfaces_field = erasureRecursive(interfaces); 1837 } else if (formals.nonEmpty()) { 1838 t.interfaces_field = 1839 upperBounds(subst(interfaces, formals, actuals)); 1840 } 1841 else { 1842 t.interfaces_field = interfaces; 1843 } 1844 } 1845 } 1846 return t.interfaces_field; 1847 } 1848 1849 @Override 1850 public List<Type> visitTypeVar(TypeVar t, Void ignored) { 1851 if (t.bound.isCompound()) 1852 return interfaces(t.bound); 1853 1854 if (t.bound.isInterface()) 1855 return List.of(t.bound); 1856 1857 return List.nil(); 1858 } 1859 }; 1860 // </editor-fold> 1861 1862 // <editor-fold defaultstate="collapsed" desc="isDerivedRaw"> 1863 Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>(); 1864 1865 public boolean isDerivedRaw(Type t) { 1866 Boolean result = isDerivedRawCache.get(t); 1867 if (result == null) { 1868 result = isDerivedRawInternal(t); 1869 isDerivedRawCache.put(t, result); 1870 } 1871 return result; 1872 } 1873 1874 public boolean isDerivedRawInternal(Type t) { 1875 if (t.isErroneous()) 1876 return false; 1877 return 1878 t.isRaw() || 1879 supertype(t) != null && isDerivedRaw(supertype(t)) || 1880 isDerivedRaw(interfaces(t)); 1881 } 1882 1883 public boolean isDerivedRaw(List<Type> ts) { 1884 List<Type> l = ts; 1885 while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail; 1886 return l.nonEmpty(); 1887 } 1888 // </editor-fold> 1889 1890 // <editor-fold defaultstate="collapsed" desc="setBounds"> 1891 /** 1892 * Set the bounds field of the given type variable to reflect a 1893 * (possibly multiple) list of bounds. 1894 * @param t a type variable 1895 * @param bounds the bounds, must be nonempty 1896 * @param supertype is objectType if all bounds are interfaces, 1897 * null otherwise. 1898 */ 1899 public void setBounds(TypeVar t, List<Type> bounds, Type supertype) { 1900 if (bounds.tail.isEmpty()) 1901 t.bound = bounds.head; 1902 else 1903 t.bound = makeCompoundType(bounds, supertype); 1904 t.rank_field = -1; 1905 } 1906 1907 /** 1908 * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that 1909 * third parameter is computed directly. Note that this test 1910 * might cause a symbol completion. Hence, this version of 1911 * setBounds may not be called during a classfile read. 1912 */ 1913 public void setBounds(TypeVar t, List<Type> bounds) { 1914 Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ? 1915 supertype(bounds.head) : null; 1916 setBounds(t, bounds, supertype); 1917 t.rank_field = -1; 1918 } 1919 // </editor-fold> 1920 1921 // <editor-fold defaultstate="collapsed" desc="getBounds"> 1922 /** 1923 * Return list of bounds of the given type variable. 1924 */ 1925 public List<Type> getBounds(TypeVar t) { 1926 if (t.bound.isErroneous() || !t.bound.isCompound()) 1927 return List.of(t.bound); 1928 else if ((erasure(t).tsym.flags() & INTERFACE) == 0) 1929 return interfaces(t).prepend(supertype(t)); 1930 else 1931 // No superclass was given in bounds. 1932 // In this case, supertype is Object, erasure is first interface. 1933 return interfaces(t); 1934 } 1935 // </editor-fold> 1936 1937 // <editor-fold defaultstate="collapsed" desc="classBound"> 1938 /** 1939 * If the given type is a (possibly selected) type variable, 1940 * return the bounding class of this type, otherwise return the 1941 * type itself. 1942 */ 1943 public Type classBound(Type t) { 1944 return classBound.visit(t); 1945 } 1946 // where 1947 private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() { 1948 1949 public Type visitType(Type t, Void ignored) { 1950 return t; 1951 } 1952 1953 @Override 1954 public Type visitClassType(ClassType t, Void ignored) { 1955 Type outer1 = classBound(t.getEnclosingType()); 1956 if (outer1 != t.getEnclosingType()) 1957 return new ClassType(outer1, t.getTypeArguments(), t.tsym); 1958 else 1959 return t; 1960 } 1961 1962 @Override 1963 public Type visitTypeVar(TypeVar t, Void ignored) { 1964 return classBound(supertype(t)); 1965 } 1966 1967 @Override 1968 public Type visitErrorType(ErrorType t, Void ignored) { 1969 return t; 1970 } 1971 }; 1972 // </editor-fold> 1973 1974 // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence"> 1975 /** 1976 * Returns true iff the first signature is a <em>sub 1977 * signature</em> of the other. This is <b>not</b> an equivalence 1978 * relation. 1979 * 1980 * @see "The Java Language Specification, Third Ed. (8.4.2)." 1981 * @see #overrideEquivalent(Type t, Type s) 1982 * @param t first signature (possibly raw). 1983 * @param s second signature (could be subjected to erasure). 1984 * @return true if t is a sub signature of s. 1985 */ 1986 public boolean isSubSignature(Type t, Type s) { 1987 return hasSameArgs(t, s) || hasSameArgs(t, erasure(s)); 1988 } 1989 1990 /** 1991 * Returns true iff these signatures are related by <em>override 1992 * equivalence</em>. This is the natural extension of 1993 * isSubSignature to an equivalence relation. 1994 * 1995 * @see "The Java Language Specification, Third Ed. (8.4.2)." 1996 * @see #isSubSignature(Type t, Type s) 1997 * @param t a signature (possible raw, could be subjected to 1998 * erasure). 1999 * @param s a signature (possible raw, could be subjected to 2000 * erasure). 2001 * @return true if either argument is a sub signature of the other. 2002 */ 2003 public boolean overrideEquivalent(Type t, Type s) { 2004 return hasSameArgs(t, s) || 2005 hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s); 2006 } 2007 2008 private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache_check = 2009 new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>>(); 2010 2011 private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache_nocheck = 2012 new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>>(); 2013 2014 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult) { 2015 Map<MethodSymbol, SoftReference<Map<TypeSymbol, MethodSymbol>>> implCache = checkResult ? 2016 implCache_check : implCache_nocheck; 2017 SoftReference<Map<TypeSymbol, MethodSymbol>> ref_cache = implCache.get(ms); 2018 Map<TypeSymbol, MethodSymbol> cache = ref_cache != null ? ref_cache.get() : null; 2019 if (cache == null) { 2020 cache = new HashMap<TypeSymbol, MethodSymbol>(); 2021 implCache.put(ms, new SoftReference<Map<TypeSymbol, MethodSymbol>>(cache)); 2022 } 2023 MethodSymbol impl = cache.get(origin); 2024 if (impl == null) { 2025 for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) { 2026 while (t.tag == TYPEVAR) 2027 t = t.getUpperBound(); 2028 TypeSymbol c = t.tsym; 2029 for (Scope.Entry e = c.members().lookup(ms.name); 2030 e.scope != null; 2031 e = e.next()) { 2032 if (e.sym.kind == Kinds.MTH) { 2033 MethodSymbol m = (MethodSymbol) e.sym; 2034 if (m.overrides(ms, origin, types, checkResult) && 2035 (m.flags() & SYNTHETIC) == 0) { 2036 impl = m; 2037 cache.put(origin, m); 2038 return impl; 2039 } 2040 } 2041 } 2042 } 2043 } 2044 return impl; 2045 } 2046 2047 /** 2048 * Does t have the same arguments as s? It is assumed that both 2049 * types are (possibly polymorphic) method types. Monomorphic 2050 * method types "have the same arguments", if their argument lists 2051 * are equal. Polymorphic method types "have the same arguments", 2052 * if they have the same arguments after renaming all type 2053 * variables of one to corresponding type variables in the other, 2054 * where correspondence is by position in the type parameter list. 2055 */ 2056 public boolean hasSameArgs(Type t, Type s) { 2057 return hasSameArgs.visit(t, s); 2058 } 2059 // where 2060 private TypeRelation hasSameArgs = new TypeRelation() { 2061 2062 public Boolean visitType(Type t, Type s) { 2063 throw new AssertionError(); 2064 } 2065 2066 @Override 2067 public Boolean visitMethodType(MethodType t, Type s) { 2068 return (s.tag == METHOD || s.tag == FUNCTION) 2069 && containsTypeEquivalent(t.argtypes, s.getParameterTypes()); 2070 } 2071 2072 @Override 2073 public Boolean visitForAll(ForAll t, Type s) { 2074 if (s.tag != FORALL) 2075 return false; 2076 2077 ForAll forAll = (ForAll)s; 2078 return hasSameBounds(t, forAll) 2079 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars)); 2080 } 2081 2082 @Override 2083 public Boolean visitErrorType(ErrorType t, Type s) { 2084 return false; 2085 } 2086 }; 2087 // </editor-fold> 2088 2089 // <editor-fold defaultstate="collapsed" desc="subst"> 2090 public List<Type> subst(List<Type> ts, 2091 List<Type> from, 2092 List<Type> to) { 2093 return new Subst(from, to).subst(ts); 2094 } 2095 2096 /** 2097 * Substitute all occurrences of a type in `from' with the 2098 * corresponding type in `to' in 't'. Match lists `from' and `to' 2099 * from the right: If lists have different length, discard leading 2100 * elements of the longer list. 2101 */ 2102 public Type subst(Type t, List<Type> from, List<Type> to) { 2103 return new Subst(from, to).subst(t); 2104 } 2105 2106 private class Subst extends UnaryVisitor<Type> { 2107 List<Type> from; 2108 List<Type> to; 2109 2110 public Subst(List<Type> from, List<Type> to) { 2111 int fromLength = from.length(); 2112 int toLength = to.length(); 2113 while (fromLength > toLength) { 2114 fromLength--; 2115 from = from.tail; 2116 } 2117 while (fromLength < toLength) { 2118 toLength--; 2119 to = to.tail; 2120 } 2121 this.from = from; 2122 this.to = to; 2123 } 2124 2125 Type subst(Type t) { 2126 if (from.tail == null) 2127 return t; 2128 else 2129 return visit(t); 2130 } 2131 2132 List<Type> subst(List<Type> ts) { 2133 if (from.tail == null) 2134 return ts; 2135 boolean wild = false; 2136 if (ts.nonEmpty() && from.nonEmpty()) { 2137 Type head1 = subst(ts.head); 2138 List<Type> tail1 = subst(ts.tail); 2139 if (head1 != ts.head || tail1 != ts.tail) 2140 return tail1.prepend(head1); 2141 } 2142 return ts; 2143 } 2144 2145 public Type visitType(Type t, Void ignored) { 2146 return t; 2147 } 2148 2149 @Override 2150 public Type visitMethodType(MethodType t, Void ignored) { 2151 List<Type> argtypes = subst(t.argtypes); 2152 Type restype = subst(t.restype); 2153 List<Type> thrown = subst(t.thrown); 2154 if (argtypes == t.argtypes && 2155 restype == t.restype && 2156 thrown == t.thrown) 2157 return t; 2158 else 2159 return new MethodType(t.tag, argtypes, restype, thrown, t.tsym); 2160 } 2161 2162 @Override 2163 public Type visitTypeVar(TypeVar t, Void ignored) { 2164 for (List<Type> from = this.from, to = this.to; 2165 from.nonEmpty(); 2166 from = from.tail, to = to.tail) { 2167 if (t == from.head) { 2168 return to.head.withTypeVar(t); 2169 } 2170 } 2171 return t; 2172 } 2173 2174 @Override 2175 public Type visitClassType(ClassType t, Void ignored) { 2176 if (!t.isCompound()) { 2177 List<Type> typarams = t.getTypeArguments(); 2178 List<Type> typarams1 = subst(typarams); 2179 Type outer = t.getEnclosingType(); 2180 Type outer1 = subst(outer); 2181 if (typarams1 == typarams && outer1 == outer) 2182 return t; 2183 else 2184 return new ClassType(outer1, typarams1, t.tsym); 2185 } else { 2186 Type st = subst(supertype(t)); 2187 List<Type> is = upperBounds(subst(interfaces(t))); 2188 if (st == supertype(t) && is == interfaces(t)) 2189 return t; 2190 else 2191 return makeCompoundType(is.prepend(st)); 2192 } 2193 } 2194 2195 @Override 2196 public Type visitWildcardType(WildcardType t, Void ignored) { 2197 Type bound = t.type; 2198 if (t.kind != BoundKind.UNBOUND) 2199 bound = subst(bound); 2200 if (bound == t.type) { 2201 return t; 2202 } else { 2203 if (t.isExtendsBound() && bound.isExtendsBound()) 2204 bound = upperBound(bound); 2205 return new WildcardType(bound, t.kind, syms.boundClass, t.bound); 2206 } 2207 } 2208 2209 @Override 2210 public Type visitArrayType(ArrayType t, Void ignored) { 2211 Type elemtype = subst(t.elemtype); 2212 if (elemtype == t.elemtype) 2213 return t; 2214 else 2215 return new ArrayType(upperBound(elemtype), t.tsym); 2216 } 2217 2218 @Override 2219 public Type visitForAll(ForAll t, Void ignored) { 2220 List<Type> tvars1 = substBounds(t.tvars, from, to); 2221 Type qtype1 = subst(t.qtype); 2222 if (tvars1 == t.tvars && qtype1 == t.qtype) { 2223 return t; 2224 } else if (tvars1 == t.tvars) { 2225 return new ForAll(tvars1, qtype1); 2226 } else { 2227 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1)); 2228 } 2229 } 2230 2231 @Override 2232 public Type visitErrorType(ErrorType t, Void ignored) { 2233 return t; 2234 } 2235 } 2236 2237 public List<Type> substBounds(List<Type> tvars, 2238 List<Type> from, 2239 List<Type> to) { 2240 if (tvars.isEmpty()) 2241 return tvars; 2242 ListBuffer<Type> newBoundsBuf = lb(); 2243 boolean changed = false; 2244 // calculate new bounds 2245 for (Type t : tvars) { 2246 TypeVar tv = (TypeVar) t; 2247 Type bound = subst(tv.bound, from, to); 2248 if (bound != tv.bound) 2249 changed = true; 2250 newBoundsBuf.append(bound); 2251 } 2252 if (!changed) 2253 return tvars; 2254 ListBuffer<Type> newTvars = lb(); 2255 // create new type variables without bounds 2256 for (Type t : tvars) { 2257 newTvars.append(new TypeVar(t.tsym, null, syms.botType)); 2258 } 2259 // the new bounds should use the new type variables in place 2260 // of the old 2261 List<Type> newBounds = newBoundsBuf.toList(); 2262 from = tvars; 2263 to = newTvars.toList(); 2264 for (; !newBounds.isEmpty(); newBounds = newBounds.tail) { 2265 newBounds.head = subst(newBounds.head, from, to); 2266 } 2267 newBounds = newBoundsBuf.toList(); 2268 // set the bounds of new type variables to the new bounds 2269 for (Type t : newTvars.toList()) { 2270 TypeVar tv = (TypeVar) t; 2271 tv.bound = newBounds.head; 2272 newBounds = newBounds.tail; 2273 } 2274 return newTvars.toList(); 2275 } 2276 2277 public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) { 2278 Type bound1 = subst(t.bound, from, to); 2279 if (bound1 == t.bound) 2280 return t; 2281 else { 2282 // create new type variable without bounds 2283 TypeVar tv = new TypeVar(t.tsym, null, syms.botType); 2284 // the new bound should use the new type variable in place 2285 // of the old 2286 tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv)); 2287 return tv; 2288 } 2289 } 2290 // </editor-fold> 2291 2292 // <editor-fold defaultstate="collapsed" desc="hasSameBounds"> 2293 /** 2294 * Does t have the same bounds for quantified variables as s? 2295 */ 2296 boolean hasSameBounds(ForAll t, ForAll s) { 2297 List<Type> l1 = t.tvars; 2298 List<Type> l2 = s.tvars; 2299 while (l1.nonEmpty() && l2.nonEmpty() && 2300 isSameType(l1.head.getUpperBound(), 2301 subst(l2.head.getUpperBound(), 2302 s.tvars, 2303 t.tvars))) { 2304 l1 = l1.tail; 2305 l2 = l2.tail; 2306 } 2307 return l1.isEmpty() && l2.isEmpty(); 2308 } 2309 // </editor-fold> 2310 2311 // <editor-fold defaultstate="collapsed" desc="newInstances"> 2312 /** Create new vector of type variables from list of variables 2313 * changing all recursive bounds from old to new list. 2314 */ 2315 public List<Type> newInstances(List<Type> tvars) { 2316 List<Type> tvars1 = Type.map(tvars, newInstanceFun); 2317 for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) { 2318 TypeVar tv = (TypeVar) l.head; 2319 tv.bound = subst(tv.bound, tvars, tvars1); 2320 } 2321 return tvars1; 2322 } 2323 static private Mapping newInstanceFun = new Mapping("newInstanceFun") { 2324 public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); } 2325 }; 2326 // </editor-fold> 2327 2328 // <editor-fold defaultstate="collapsed" desc="createErrorType"> 2329 public Type createErrorType(Type originalType) { 2330 return new ErrorType(originalType, syms.errSymbol); 2331 } 2332 2333 public Type createErrorType(ClassSymbol c, Type originalType) { 2334 return new ErrorType(c, originalType); 2335 } 2336 2337 public Type createErrorType(Name name, TypeSymbol container, Type originalType) { 2338 return new ErrorType(name, container, originalType); 2339 } 2340 // </editor-fold> 2341 2342 // <editor-fold defaultstate="collapsed" desc="rank"> 2343 /** 2344 * The rank of a class is the length of the longest path between 2345 * the class and java.lang.Object in the class inheritance 2346 * graph. Undefined for all but reference types. 2347 */ 2348 public int rank(Type t) { 2349 switch(t.tag) { 2350 case CLASS: { 2351 ClassType cls = (ClassType)t; 2352 if (cls.rank_field < 0) { 2353 Name fullname = cls.tsym.getQualifiedName(); 2354 if (fullname == names.java_lang_Object) 2355 cls.rank_field = 0; 2356 else { 2357 int r = rank(supertype(cls)); 2358 for (List<Type> l = interfaces(cls); 2359 l.nonEmpty(); 2360 l = l.tail) { 2361 if (rank(l.head) > r) 2362 r = rank(l.head); 2363 } 2364 cls.rank_field = r + 1; 2365 } 2366 } 2367 return cls.rank_field; 2368 } 2369 case TYPEVAR: { 2370 TypeVar tvar = (TypeVar)t; 2371 if (tvar.rank_field < 0) { 2372 int r = rank(supertype(tvar)); 2373 for (List<Type> l = interfaces(tvar); 2374 l.nonEmpty(); 2375 l = l.tail) { 2376 if (rank(l.head) > r) r = rank(l.head); 2377 } 2378 tvar.rank_field = r + 1; 2379 } 2380 return tvar.rank_field; 2381 } 2382 case ERROR: 2383 return 0; 2384 default: 2385 throw new AssertionError(); 2386 } 2387 } 2388 // </editor-fold> 2389 2390 /** 2391 * Helper method for generating a string representation of a given type 2392 * accordingly to a given locale 2393 */ 2394 public String toString(Type t, Locale locale) { 2395 return Printer.createStandardPrinter(messages).visit(t, locale); 2396 } 2397 2398 /** 2399 * Helper method for generating a string representation of a given type 2400 * accordingly to a given locale 2401 */ 2402 public String toString(Symbol t, Locale locale) { 2403 return Printer.createStandardPrinter(messages).visit(t, locale); 2404 } 2405 2406 // <editor-fold defaultstate="collapsed" desc="toString"> 2407 /** 2408 * This toString is slightly more descriptive than the one on Type. 2409 * 2410 * @deprecated Types.toString(Type t, Locale l) provides better support 2411 * for localization 2412 */ 2413 @Deprecated 2414 public String toString(Type t) { 2415 if (t.tag == FORALL) { 2416 ForAll forAll = (ForAll)t; 2417 return typaramsString(forAll.tvars) + forAll.qtype; 2418 } 2419 return "" + t; 2420 } 2421 // where 2422 private String typaramsString(List<Type> tvars) { 2423 StringBuffer s = new StringBuffer(); 2424 s.append('<'); 2425 boolean first = true; 2426 for (Type t : tvars) { 2427 if (!first) s.append(", "); 2428 first = false; 2429 appendTyparamString(((TypeVar)t), s); 2430 } 2431 s.append('>'); 2432 return s.toString(); 2433 } 2434 private void appendTyparamString(TypeVar t, StringBuffer buf) { 2435 buf.append(t); 2436 if (t.bound == null || 2437 t.bound.tsym.getQualifiedName() == names.java_lang_Object) 2438 return; 2439 buf.append(" extends "); // Java syntax; no need for i18n 2440 Type bound = t.bound; 2441 if (!bound.isCompound()) { 2442 buf.append(bound); 2443 } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) { 2444 buf.append(supertype(t)); 2445 for (Type intf : interfaces(t)) { 2446 buf.append('&'); 2447 buf.append(intf); 2448 } 2449 } else { 2450 // No superclass was given in bounds. 2451 // In this case, supertype is Object, erasure is first interface. 2452 boolean first = true; 2453 for (Type intf : interfaces(t)) { 2454 if (!first) buf.append('&'); 2455 first = false; 2456 buf.append(intf); 2457 } 2458 } 2459 } 2460 // </editor-fold> 2461 2462 // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types"> 2463 /** 2464 * A cache for closures. 2465 * 2466 * <p>A closure is a list of all the supertypes and interfaces of 2467 * a class or interface type, ordered by ClassSymbol.precedes 2468 * (that is, subclasses come first, arbitrary but fixed 2469 * otherwise). 2470 */ 2471 private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>(); 2472 2473 /** 2474 * Returns the closure of a class or interface type. 2475 */ 2476 public List<Type> closure(Type t) { 2477 List<Type> cl = closureCache.get(t); 2478 if (cl == null) { 2479 Type st = supertype(t); 2480 if (!t.isCompound()) { 2481 if (st.tag == CLASS) { 2482 cl = insert(closure(st), t); 2483 } else if (st.tag == TYPEVAR) { 2484 cl = closure(st).prepend(t); 2485 } else { 2486 cl = List.of(t); 2487 } 2488 } else { 2489 cl = closure(supertype(t)); 2490 } 2491 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) 2492 cl = union(cl, closure(l.head)); 2493 closureCache.put(t, cl); 2494 } 2495 return cl; 2496 } 2497 2498 /** 2499 * Insert a type in a closure 2500 */ 2501 public List<Type> insert(List<Type> cl, Type t) { 2502 if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) { 2503 return cl.prepend(t); 2504 } else if (cl.head.tsym.precedes(t.tsym, this)) { 2505 return insert(cl.tail, t).prepend(cl.head); 2506 } else { 2507 return cl; 2508 } 2509 } 2510 2511 /** 2512 * Form the union of two closures 2513 */ 2514 public List<Type> union(List<Type> cl1, List<Type> cl2) { 2515 if (cl1.isEmpty()) { 2516 return cl2; 2517 } else if (cl2.isEmpty()) { 2518 return cl1; 2519 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) { 2520 return union(cl1.tail, cl2).prepend(cl1.head); 2521 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { 2522 return union(cl1, cl2.tail).prepend(cl2.head); 2523 } else { 2524 return union(cl1.tail, cl2.tail).prepend(cl1.head); 2525 } 2526 } 2527 2528 /** 2529 * Intersect two closures 2530 */ 2531 public List<Type> intersect(List<Type> cl1, List<Type> cl2) { 2532 if (cl1 == cl2) 2533 return cl1; 2534 if (cl1.isEmpty() || cl2.isEmpty()) 2535 return List.nil(); 2536 if (cl1.head.tsym.precedes(cl2.head.tsym, this)) 2537 return intersect(cl1.tail, cl2); 2538 if (cl2.head.tsym.precedes(cl1.head.tsym, this)) 2539 return intersect(cl1, cl2.tail); 2540 if (isSameType(cl1.head, cl2.head)) 2541 return intersect(cl1.tail, cl2.tail).prepend(cl1.head); 2542 if (cl1.head.tsym == cl2.head.tsym && 2543 cl1.head.tag == CLASS && cl2.head.tag == CLASS) { 2544 if (cl1.head.isParameterized() && cl2.head.isParameterized()) { 2545 Type merge = merge(cl1.head,cl2.head); 2546 return intersect(cl1.tail, cl2.tail).prepend(merge); 2547 } 2548 if (cl1.head.isRaw() || cl2.head.isRaw()) 2549 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head)); 2550 } 2551 return intersect(cl1.tail, cl2.tail); 2552 } 2553 // where 2554 class TypePair { 2555 final Type t1; 2556 final Type t2; 2557 TypePair(Type t1, Type t2) { 2558 this.t1 = t1; 2559 this.t2 = t2; 2560 } 2561 @Override 2562 public int hashCode() { 2563 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2); 2564 } 2565 @Override 2566 public boolean equals(Object obj) { 2567 if (!(obj instanceof TypePair)) 2568 return false; 2569 TypePair typePair = (TypePair)obj; 2570 return isSameType(t1, typePair.t1) 2571 && isSameType(t2, typePair.t2); 2572 } 2573 } 2574 Set<TypePair> mergeCache = new HashSet<TypePair>(); 2575 private Type merge(Type c1, Type c2) { 2576 ClassType class1 = (ClassType) c1; 2577 List<Type> act1 = class1.getTypeArguments(); 2578 ClassType class2 = (ClassType) c2; 2579 List<Type> act2 = class2.getTypeArguments(); 2580 ListBuffer<Type> merged = new ListBuffer<Type>(); 2581 List<Type> typarams = class1.tsym.type.getTypeArguments(); 2582 2583 while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) { 2584 if (containsType(act1.head, act2.head)) { 2585 merged.append(act1.head); 2586 } else if (containsType(act2.head, act1.head)) { 2587 merged.append(act2.head); 2588 } else { 2589 TypePair pair = new TypePair(c1, c2); 2590 Type m; 2591 if (mergeCache.add(pair)) { 2592 m = new WildcardType(lub(upperBound(act1.head), 2593 upperBound(act2.head)), 2594 BoundKind.EXTENDS, 2595 syms.boundClass); 2596 mergeCache.remove(pair); 2597 } else { 2598 m = new WildcardType(syms.objectType, 2599 BoundKind.UNBOUND, 2600 syms.boundClass); 2601 } 2602 merged.append(m.withTypeVar(typarams.head)); 2603 } 2604 act1 = act1.tail; 2605 act2 = act2.tail; 2606 typarams = typarams.tail; 2607 } 2608 assert(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty()); 2609 return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym); 2610 } 2611 2612 /** 2613 * Return the minimum type of a closure, a compound type if no 2614 * unique minimum exists. 2615 */ 2616 private Type compoundMin(List<Type> cl) { 2617 if (cl.isEmpty()) return syms.objectType; 2618 List<Type> compound = closureMin(cl); 2619 if (compound.isEmpty()) 2620 return null; 2621 else if (compound.tail.isEmpty()) 2622 return compound.head; 2623 else 2624 return makeCompoundType(compound); 2625 } 2626 2627 /** 2628 * Return the minimum types of a closure, suitable for computing 2629 * compoundMin or glb. 2630 */ 2631 private List<Type> closureMin(List<Type> cl) { 2632 ListBuffer<Type> classes = lb(); 2633 ListBuffer<Type> interfaces = lb(); 2634 while (!cl.isEmpty()) { 2635 Type current = cl.head; 2636 if (current.isInterface()) 2637 interfaces.append(current); 2638 else 2639 classes.append(current); 2640 ListBuffer<Type> candidates = lb(); 2641 for (Type t : cl.tail) { 2642 if (!isSubtypeNoCapture(current, t)) 2643 candidates.append(t); 2644 } 2645 cl = candidates.toList(); 2646 } 2647 return classes.appendList(interfaces).toList(); 2648 } 2649 2650 /** 2651 * Return the least upper bound of pair of types. if the lub does 2652 * not exist return null. 2653 */ 2654 public Type lub(Type t1, Type t2) { 2655 return lub(List.of(t1, t2)); 2656 } 2657 2658 /** 2659 * Return the least upper bound (lub) of set of types. If the lub 2660 * does not exist return the type of null (bottom). 2661 */ 2662 public Type lub(List<Type> ts) { 2663 final int ARRAY_BOUND = 1; 2664 final int CLASS_BOUND = 2; 2665 int boundkind = 0; 2666 for (Type t : ts) { 2667 switch (t.tag) { 2668 case CLASS: 2669 boundkind |= CLASS_BOUND; 2670 break; 2671 case ARRAY: 2672 boundkind |= ARRAY_BOUND; 2673 break; 2674 case TYPEVAR: 2675 do { 2676 t = t.getUpperBound(); 2677 } while (t.tag == TYPEVAR); 2678 if (t.tag == ARRAY) { 2679 boundkind |= ARRAY_BOUND; 2680 } else { 2681 boundkind |= CLASS_BOUND; 2682 } 2683 break; 2684 default: 2685 if (t.isPrimitive()) 2686 return syms.errType; 2687 } 2688 } 2689 switch (boundkind) { 2690 case 0: 2691 return syms.botType; 2692 2693 case ARRAY_BOUND: 2694 // calculate lub(A[], B[]) 2695 List<Type> elements = Type.map(ts, elemTypeFun); 2696 for (Type t : elements) { 2697 if (t.isPrimitive()) { 2698 // if a primitive type is found, then return 2699 // arraySuperType unless all the types are the 2700 // same 2701 Type first = ts.head; 2702 for (Type s : ts.tail) { 2703 if (!isSameType(first, s)) { 2704 // lub(int[], B[]) is Cloneable & Serializable 2705 return arraySuperType(); 2706 } 2707 } 2708 // all the array types are the same, return one 2709 // lub(int[], int[]) is int[] 2710 return first; 2711 } 2712 } 2713 // lub(A[], B[]) is lub(A, B)[] 2714 return new ArrayType(lub(elements), syms.arrayClass); 2715 2716 case CLASS_BOUND: 2717 // calculate lub(A, B) 2718 while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR) 2719 ts = ts.tail; 2720 assert !ts.isEmpty(); 2721 List<Type> cl = closure(ts.head); 2722 for (Type t : ts.tail) { 2723 if (t.tag == CLASS || t.tag == TYPEVAR) 2724 cl = intersect(cl, closure(t)); 2725 } 2726 return compoundMin(cl); 2727 2728 default: 2729 // calculate lub(A, B[]) 2730 List<Type> classes = List.of(arraySuperType()); 2731 for (Type t : ts) { 2732 if (t.tag != ARRAY) // Filter out any arrays 2733 classes = classes.prepend(t); 2734 } 2735 // lub(A, B[]) is lub(A, arraySuperType) 2736 return lub(classes); 2737 } 2738 } 2739 // where 2740 private Type arraySuperType = null; 2741 private Type arraySuperType() { 2742 // initialized lazily to avoid problems during compiler startup 2743 if (arraySuperType == null) { 2744 synchronized (this) { 2745 if (arraySuperType == null) { 2746 // JLS 10.8: all arrays implement Cloneable and Serializable. 2747 arraySuperType = makeCompoundType(List.of(syms.serializableType, 2748 syms.cloneableType), 2749 syms.objectType); 2750 } 2751 } 2752 } 2753 return arraySuperType; 2754 } 2755 // </editor-fold> 2756 2757 // <editor-fold defaultstate="collapsed" desc="Greatest lower bound"> 2758 public Type glb(List<Type> ts) { 2759 Type t1 = ts.head; 2760 for (Type t2 : ts.tail) { 2761 if (t1.isErroneous()) 2762 return t1; 2763 t1 = glb(t1, t2); 2764 } 2765 return t1; 2766 } 2767 //where 2768 public Type glb(Type t, Type s) { 2769 if (s == null) 2770 return t; 2771 else if (isSubtypeNoCapture(t, s)) 2772 return t; 2773 else if (isSubtypeNoCapture(s, t)) 2774 return s; 2775 2776 List<Type> closure = union(closure(t), closure(s)); 2777 List<Type> bounds = closureMin(closure); 2778 2779 if (bounds.isEmpty()) { // length == 0 2780 return syms.objectType; 2781 } else if (bounds.tail.isEmpty()) { // length == 1 2782 return bounds.head; 2783 } else { // length > 1 2784 int classCount = 0; 2785 for (Type bound : bounds) 2786 if (!bound.isInterface()) 2787 classCount++; 2788 if (classCount > 1) 2789 return createErrorType(t); 2790 } 2791 return makeCompoundType(bounds); 2792 } 2793 // </editor-fold> 2794 2795 // <editor-fold defaultstate="collapsed" desc="hashCode"> 2796 /** 2797 * Compute a hash code on a type. 2798 */ 2799 public static int hashCode(Type t) { 2800 return hashCode.visit(t); 2801 } 2802 // where 2803 private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() { 2804 2805 public Integer visitType(Type t, Void ignored) { 2806 return t.tag; 2807 } 2808 2809 @Override 2810 public Integer visitClassType(ClassType t, Void ignored) { 2811 int result = visit(t.getEnclosingType()); 2812 result *= 127; 2813 result += t.tsym.flatName().hashCode(); 2814 for (Type s : t.getTypeArguments()) { 2815 result *= 127; 2816 result += visit(s); 2817 } 2818 return result; 2819 } 2820 2821 @Override 2822 public Integer visitWildcardType(WildcardType t, Void ignored) { 2823 int result = t.kind.hashCode(); 2824 if (t.type != null) { 2825 result *= 127; 2826 result += visit(t.type); 2827 } 2828 return result; 2829 } 2830 2831 @Override 2832 public Integer visitArrayType(ArrayType t, Void ignored) { 2833 return visit(t.elemtype) + 12; 2834 } 2835 2836 @Override 2837 public Integer visitTypeVar(TypeVar t, Void ignored) { 2838 return System.identityHashCode(t.tsym); 2839 } 2840 2841 @Override 2842 public Integer visitUndetVar(UndetVar t, Void ignored) { 2843 return System.identityHashCode(t); 2844 } 2845 2846 @Override 2847 public Integer visitErrorType(ErrorType t, Void ignored) { 2848 return 0; 2849 } 2850 }; 2851 // </editor-fold> 2852 2853 // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable"> 2854 /** 2855 * Does t have a result that is a subtype of the result type of s, 2856 * suitable for covariant returns? It is assumed that both types 2857 * are (possibly polymorphic) method types. Monomorphic method 2858 * types are handled in the obvious way. Polymorphic method types 2859 * require renaming all type variables of one to corresponding 2860 * type variables in the other, where correspondence is by 2861 * position in the type parameter list. */ 2862 public boolean resultSubtype(Type t, Type s, Warner warner) { 2863 List<Type> tvars = t.getTypeArguments(); 2864 List<Type> svars = s.getTypeArguments(); 2865 Type tres = t.getReturnType(); 2866 Type sres = subst(s.getReturnType(), svars, tvars); 2867 return covariantReturnType(tres, sres, warner); 2868 } 2869 2870 /** 2871 * Return-Type-Substitutable. 2872 * @see <a href="http://java.sun.com/docs/books/jls/">The Java 2873 * Language Specification, Third Ed. (8.4.5)</a> 2874 */ 2875 public boolean returnTypeSubstitutable(Type r1, Type r2) { 2876 if (hasSameArgs(r1, r2)) 2877 return resultSubtype(r1, r2, Warner.noWarnings); 2878 else 2879 return covariantReturnType(r1.getReturnType(), 2880 erasure(r2.getReturnType()), 2881 Warner.noWarnings); 2882 } 2883 2884 public boolean returnTypeSubstitutable(Type r1, 2885 Type r2, Type r2res, 2886 Warner warner) { 2887 if (isSameType(r1.getReturnType(), r2res)) 2888 return true; 2889 if (r1.getReturnType().isPrimitive() || r2res.isPrimitive()) 2890 return false; 2891 2892 if (hasSameArgs(r1, r2)) 2893 return covariantReturnType(r1.getReturnType(), r2res, warner); 2894 if (!source.allowCovariantReturns()) 2895 return false; 2896 if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner)) 2897 return true; 2898 if (!isSubtype(r1.getReturnType(), erasure(r2res))) 2899 return false; 2900 warner.warnUnchecked(); 2901 return true; 2902 } 2903 2904 /** 2905 * Is t an appropriate return type in an overrider for a 2906 * method that returns s? 2907 */ 2908 public boolean covariantReturnType(Type t, Type s, Warner warner) { 2909 return 2910 isSameType(t, s) || 2911 source.allowCovariantReturns() && 2912 !t.isPrimitive() && 2913 !s.isPrimitive() && 2914 isAssignable(t, s, warner); 2915 } 2916 // </editor-fold> 2917 2918 // <editor-fold defaultstate="collapsed" desc="Box/unbox support"> 2919 /** 2920 * Return the class that boxes the given primitive. 2921 */ 2922 public ClassSymbol boxedClass(Type t) { 2923 return reader.enterClass(syms.boxedName[t.tag]); 2924 } 2925 2926 /** 2927 * Return the primitive type corresponding to a boxed type. 2928 */ 2929 public Type unboxedType(Type t) { 2930 if (allowBoxing) { 2931 for (int i=0; i<syms.boxedName.length; i++) { 2932 Name box = syms.boxedName[i]; 2933 if (box != null && 2934 asSuper(t, reader.enterClass(box)) != null) 2935 return syms.typeOfTag[i]; 2936 } 2937 } 2938 return Type.noType; 2939 } 2940 // </editor-fold> 2941 2942 // <editor-fold defaultstate="collapsed" desc="Capture conversion"> 2943 /* 2944 * JLS 3rd Ed. 5.1.10 Capture Conversion: 2945 * 2946 * Let G name a generic type declaration with n formal type 2947 * parameters A1 ... An with corresponding bounds U1 ... Un. There 2948 * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>, 2949 * where, for 1 <= i <= n: 2950 * 2951 * + If Ti is a wildcard type argument (4.5.1) of the form ? then 2952 * Si is a fresh type variable whose upper bound is 2953 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null 2954 * type. 2955 * 2956 * + If Ti is a wildcard type argument of the form ? extends Bi, 2957 * then Si is a fresh type variable whose upper bound is 2958 * glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is 2959 * the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is 2960 * a compile-time error if for any two classes (not interfaces) 2961 * Vi and Vj,Vi is not a subclass of Vj or vice versa. 2962 * 2963 * + If Ti is a wildcard type argument of the form ? super Bi, 2964 * then Si is a fresh type variable whose upper bound is 2965 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi. 2966 * 2967 * + Otherwise, Si = Ti. 2968 * 2969 * Capture conversion on any type other than a parameterized type 2970 * (4.5) acts as an identity conversion (5.1.1). Capture 2971 * conversions never require a special action at run time and 2972 * therefore never throw an exception at run time. 2973 * 2974 * Capture conversion is not applied recursively. 2975 */ 2976 /** 2977 * Capture conversion as specified by JLS 3rd Ed. 2978 */ 2979 2980 public List<Type> capture(List<Type> ts) { 2981 List<Type> buf = List.nil(); 2982 for (Type t : ts) { 2983 buf = buf.prepend(capture(t)); 2984 } 2985 return buf.reverse(); 2986 } 2987 public Type capture(Type t) { 2988 if (t.tag != CLASS) 2989 return t; 2990 ClassType cls = (ClassType)t; 2991 if (cls.isRaw() || !cls.isParameterized()) 2992 return cls; 2993 2994 ClassType G = (ClassType)cls.asElement().asType(); 2995 List<Type> A = G.getTypeArguments(); 2996 List<Type> T = cls.getTypeArguments(); 2997 List<Type> S = freshTypeVariables(T); 2998 2999 List<Type> currentA = A; 3000 List<Type> currentT = T; 3001 List<Type> currentS = S; 3002 boolean captured = false; 3003 while (!currentA.isEmpty() && 3004 !currentT.isEmpty() && 3005 !currentS.isEmpty()) { 3006 if (currentS.head != currentT.head) { 3007 captured = true; 3008 WildcardType Ti = (WildcardType)currentT.head; 3009 Type Ui = currentA.head.getUpperBound(); 3010 CapturedType Si = (CapturedType)currentS.head; 3011 if (Ui == null) 3012 Ui = syms.objectType; 3013 switch (Ti.kind) { 3014 case UNBOUND: 3015 Si.bound = subst(Ui, A, S); 3016 Si.lower = syms.botType; 3017 break; 3018 case EXTENDS: 3019 Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S)); 3020 Si.lower = syms.botType; 3021 break; 3022 case SUPER: 3023 Si.bound = subst(Ui, A, S); 3024 Si.lower = Ti.getSuperBound(); 3025 break; 3026 } 3027 if (Si.bound == Si.lower) 3028 currentS.head = Si.bound; 3029 } 3030 currentA = currentA.tail; 3031 currentT = currentT.tail; 3032 currentS = currentS.tail; 3033 } 3034 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty()) 3035 return erasure(t); // some "rare" type involved 3036 3037 if (captured) 3038 return new ClassType(cls.getEnclosingType(), S, cls.tsym); 3039 else 3040 return t; 3041 } 3042 // where 3043 public List<Type> freshTypeVariables(List<Type> types) { 3044 ListBuffer<Type> result = lb(); 3045 for (Type t : types) { 3046 if (t.tag == WILDCARD) { 3047 Type bound = ((WildcardType)t).getExtendsBound(); 3048 if (bound == null) 3049 bound = syms.objectType; 3050 result.append(new CapturedType(capturedName, 3051 syms.noSymbol, 3052 bound, 3053 syms.botType, 3054 (WildcardType)t)); 3055 } else { 3056 result.append(t); 3057 } 3058 } 3059 return result.toList(); 3060 } 3061 // </editor-fold> 3062 3063 // <editor-fold defaultstate="collapsed" desc="Internal utility methods"> 3064 private List<Type> upperBounds(List<Type> ss) { 3065 if (ss.isEmpty()) return ss; 3066 Type head = upperBound(ss.head); 3067 List<Type> tail = upperBounds(ss.tail); 3068 if (head != ss.head || tail != ss.tail) 3069 return tail.prepend(head); 3070 else 3071 return ss; 3072 } 3073 3074 private boolean sideCast(Type from, Type to, Warner warn) { 3075 // We are casting from type $from$ to type $to$, which are 3076 // non-final unrelated types. This method 3077 // tries to reject a cast by transferring type parameters 3078 // from $to$ to $from$ by common superinterfaces. 3079 boolean reverse = false; 3080 Type target = to; 3081 if ((to.tsym.flags() & INTERFACE) == 0) { 3082 assert (from.tsym.flags() & INTERFACE) != 0; 3083 reverse = true; 3084 to = from; 3085 from = target; 3086 } 3087 List<Type> commonSupers = superClosure(to, erasure(from)); 3088 boolean giveWarning = commonSupers.isEmpty(); 3089 // The arguments to the supers could be unified here to 3090 // get a more accurate analysis 3091 while (commonSupers.nonEmpty()) { 3092 Type t1 = asSuper(from, commonSupers.head.tsym); 3093 Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym); 3094 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) 3095 return false; 3096 giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)); 3097 commonSupers = commonSupers.tail; 3098 } 3099 if (giveWarning && !isReifiable(reverse ? from : to)) 3100 warn.warnUnchecked(); 3101 if (!source.allowCovariantReturns()) 3102 // reject if there is a common method signature with 3103 // incompatible return types. 3104 chk.checkCompatibleAbstracts(warn.pos(), from, to); 3105 return true; 3106 } 3107 3108 private boolean sideCastFinal(Type from, Type to, Warner warn) { 3109 // We are casting from type $from$ to type $to$, which are 3110 // unrelated types one of which is final and the other of 3111 // which is an interface. This method 3112 // tries to reject a cast by transferring type parameters 3113 // from the final class to the interface. 3114 boolean reverse = false; 3115 Type target = to; 3116 if ((to.tsym.flags() & INTERFACE) == 0) { 3117 assert (from.tsym.flags() & INTERFACE) != 0; 3118 reverse = true; 3119 to = from; 3120 from = target; 3121 } 3122 assert (from.tsym.flags() & FINAL) != 0; 3123 Type t1 = asSuper(from, to.tsym); 3124 if (t1 == null) return false; 3125 Type t2 = to; 3126 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) 3127 return false; 3128 if (!source.allowCovariantReturns()) 3129 // reject if there is a common method signature with 3130 // incompatible return types. 3131 chk.checkCompatibleAbstracts(warn.pos(), from, to); 3132 if (!isReifiable(target) && 3133 (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2))) 3134 warn.warnUnchecked(); 3135 return true; 3136 } 3137 3138 private boolean giveWarning(Type from, Type to) { 3139 Type subFrom = asSub(from, to.tsym); 3140 return to.isParameterized() && 3141 (!(isUnbounded(to) || 3142 isSubtype(from, to) || 3143 ((subFrom != null) && isSameType(subFrom, to)))); 3144 } 3145 3146 private List<Type> superClosure(Type t, Type s) { 3147 List<Type> cl = List.nil(); 3148 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) { 3149 if (isSubtype(s, erasure(l.head))) { 3150 cl = insert(cl, l.head); 3151 } else { 3152 cl = union(cl, superClosure(l.head, s)); 3153 } 3154 } 3155 return cl; 3156 } 3157 3158 private boolean containsTypeEquivalent(Type t, Type s) { 3159 return 3160 isSameType(t, s) || // shortcut 3161 containsType(t, s) && containsType(s, t); 3162 } 3163 3164 // <editor-fold defaultstate="collapsed" desc="adapt"> 3165 /** 3166 * Adapt a type by computing a substitution which maps a source 3167 * type to a target type. 3168 * 3169 * @param source the source type 3170 * @param target the target type 3171 * @param from the type variables of the computed substitution 3172 * @param to the types of the computed substitution. 3173 */ 3174 public void adapt(Type source, 3175 Type target, 3176 ListBuffer<Type> from, 3177 ListBuffer<Type> to) throws AdaptFailure { 3178 new Adapter(from, to).adapt(source, target); 3179 } 3180 3181 class Adapter extends SimpleVisitor<Void, Type> { 3182 3183 ListBuffer<Type> from; 3184 ListBuffer<Type> to; 3185 Map<Symbol,Type> mapping; 3186 3187 Adapter(ListBuffer<Type> from, ListBuffer<Type> to) { 3188 this.from = from; 3189 this.to = to; 3190 mapping = new HashMap<Symbol,Type>(); 3191 } 3192 3193 public void adapt(Type source, Type target) throws AdaptFailure { 3194 visit(source, target); 3195 List<Type> fromList = from.toList(); 3196 List<Type> toList = to.toList(); 3197 while (!fromList.isEmpty()) { 3198 Type val = mapping.get(fromList.head.tsym); 3199 if (toList.head != val) 3200 toList.head = val; 3201 fromList = fromList.tail; 3202 toList = toList.tail; 3203 } 3204 } 3205 3206 @Override 3207 public Void visitClassType(ClassType source, Type target) throws AdaptFailure { 3208 if (target.tag == CLASS) 3209 adaptRecursive(source.allparams(), target.allparams()); 3210 return null; 3211 } 3212 3213 @Override 3214 public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure { 3215 if (target.tag == ARRAY) 3216 adaptRecursive(elemtype(source), elemtype(target)); 3217 return null; 3218 } 3219 3220 @Override 3221 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { 3222 if (source.isExtendsBound()) 3223 adaptRecursive(upperBound(source), upperBound(target)); 3224 else if (source.isSuperBound()) 3225 adaptRecursive(lowerBound(source), lowerBound(target)); 3226 return null; 3227 } 3228 3229 @Override 3230 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure { 3231 // Check to see if there is 3232 // already a mapping for $source$, in which case 3233 // the old mapping will be merged with the new 3234 Type val = mapping.get(source.tsym); 3235 if (val != null) { 3236 if (val.isSuperBound() && target.isSuperBound()) { 3237 val = isSubtype(lowerBound(val), lowerBound(target)) 3238 ? target : val; 3239 } else if (val.isExtendsBound() && target.isExtendsBound()) { 3240 val = isSubtype(upperBound(val), upperBound(target)) 3241 ? val : target; 3242 } else if (!isSameType(val, target)) { 3243 throw new AdaptFailure(); 3244 } 3245 } else { 3246 val = target; 3247 from.append(source); 3248 to.append(target); 3249 } 3250 mapping.put(source.tsym, val); 3251 return null; 3252 } 3253 3254 @Override 3255 public Void visitType(Type source, Type target) { 3256 return null; 3257 } 3258 3259 private Set<TypePair> cache = new HashSet<TypePair>(); 3260 3261 private void adaptRecursive(Type source, Type target) { 3262 TypePair pair = new TypePair(source, target); 3263 if (cache.add(pair)) { 3264 try { 3265 visit(source, target); 3266 } finally { 3267 cache.remove(pair); 3268 } 3269 } 3270 } 3271 3272 private void adaptRecursive(List<Type> source, List<Type> target) { 3273 if (source.length() == target.length()) { 3274 while (source.nonEmpty()) { 3275 adaptRecursive(source.head, target.head); 3276 source = source.tail; 3277 target = target.tail; 3278 } 3279 } 3280 } 3281 } 3282 3283 public static class AdaptFailure extends RuntimeException { 3284 static final long serialVersionUID = -7490231548272701566L; 3285 } 3286 3287 private void adaptSelf(Type t, 3288 ListBuffer<Type> from, 3289 ListBuffer<Type> to) { 3290 try { 3291 //if (t.tsym.type != t) 3292 adapt(t.tsym.type, t, from, to); 3293 } catch (AdaptFailure ex) { 3294 // Adapt should never fail calculating a mapping from 3295 // t.tsym.type to t as there can be no merge problem. 3296 throw new AssertionError(ex); 3297 } 3298 } 3299 // </editor-fold> 3300 3301 /** 3302 * Rewrite all type variables (universal quantifiers) in the given 3303 * type to wildcards (existential quantifiers). This is used to 3304 * determine if a cast is allowed. For example, if high is true 3305 * and {@code T <: Number}, then {@code List<T>} is rewritten to 3306 * {@code List<? extends Number>}. Since {@code List<Integer> <: 3307 * List<? extends Number>} a {@code List<T>} can be cast to {@code 3308 * List<Integer>} with a warning. 3309 * @param t a type 3310 * @param high if true return an upper bound; otherwise a lower 3311 * bound 3312 * @param rewriteTypeVars only rewrite captured wildcards if false; 3313 * otherwise rewrite all type variables 3314 * @return the type rewritten with wildcards (existential 3315 * quantifiers) only 3316 */ 3317 private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) { 3318 return new Rewriter(high, rewriteTypeVars).rewrite(t); 3319 } 3320 3321 class Rewriter extends UnaryVisitor<Type> { 3322 3323 boolean high; 3324 boolean rewriteTypeVars; 3325 3326 Rewriter(boolean high, boolean rewriteTypeVars) { 3327 this.high = high; 3328 this.rewriteTypeVars = rewriteTypeVars; 3329 } 3330 3331 Type rewrite(Type t) { 3332 ListBuffer<Type> from = new ListBuffer<Type>(); 3333 ListBuffer<Type> to = new ListBuffer<Type>(); 3334 adaptSelf(t, from, to); 3335 ListBuffer<Type> rewritten = new ListBuffer<Type>(); 3336 List<Type> formals = from.toList(); 3337 boolean changed = false; 3338 for (Type arg : to.toList()) { 3339 Type bound = visit(arg); 3340 if (arg != bound) { 3341 changed = true; 3342 bound = high ? makeExtendsWildcard(bound, (TypeVar)formals.head) 3343 : makeSuperWildcard(bound, (TypeVar)formals.head); 3344 } 3345 rewritten.append(bound); 3346 formals = formals.tail; 3347 } 3348 if (changed) 3349 return subst(t.tsym.type, from.toList(), rewritten.toList()); 3350 else 3351 return t; 3352 } 3353 3354 public Type visitType(Type t, Void s) { 3355 return high ? upperBound(t) : lowerBound(t); 3356 } 3357 3358 @Override 3359 public Type visitCapturedType(CapturedType t, Void s) { 3360 return visitWildcardType(t.wildcard, null); 3361 } 3362 3363 @Override 3364 public Type visitTypeVar(TypeVar t, Void s) { 3365 if (rewriteTypeVars) 3366 return high ? t.bound : syms.botType; 3367 else 3368 return t; 3369 } 3370 3371 @Override 3372 public Type visitWildcardType(WildcardType t, Void s) { 3373 Type bound = high ? t.getExtendsBound() : 3374 t.getSuperBound(); 3375 if (bound == null) 3376 bound = high ? syms.objectType : syms.botType; 3377 return bound; 3378 } 3379 } 3380 3381 /** 3382 * Create a wildcard with the given upper (extends) bound; create 3383 * an unbounded wildcard if bound is Object. 3384 * 3385 * @param bound the upper bound 3386 * @param formal the formal type parameter that will be 3387 * substituted by the wildcard 3388 */ 3389 private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) { 3390 if (bound == syms.objectType) { 3391 return new WildcardType(syms.objectType, 3392 BoundKind.UNBOUND, 3393 syms.boundClass, 3394 formal); 3395 } else { 3396 return new WildcardType(bound, 3397 BoundKind.EXTENDS, 3398 syms.boundClass, 3399 formal); 3400 } 3401 } 3402 3403 /** 3404 * Create a wildcard with the given lower (super) bound; create an 3405 * unbounded wildcard if bound is bottom (type of {@code null}). 3406 * 3407 * @param bound the lower bound 3408 * @param formal the formal type parameter that will be 3409 * substituted by the wildcard 3410 */ 3411 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) { 3412 if (bound.tag == BOT) { 3413 return new WildcardType(syms.objectType, 3414 BoundKind.UNBOUND, 3415 syms.boundClass, 3416 formal); 3417 } else { 3418 return new WildcardType(bound, 3419 BoundKind.SUPER, 3420 syms.boundClass, 3421 formal); 3422 } 3423 } 3424 3425 /** 3426 * A wrapper for a type that allows use in sets. 3427 */ 3428 class SingletonType { 3429 final Type t; 3430 SingletonType(Type t) { 3431 this.t = t; 3432 } 3433 public int hashCode() { 3434 return Types.this.hashCode(t); 3435 } 3436 public boolean equals(Object obj) { 3437 return (obj instanceof SingletonType) && 3438 isSameType(t, ((SingletonType)obj).t); 3439 } 3440 public String toString() { 3441 return t.toString(); 3442 } 3443 } 3444 // </editor-fold> 3445 3446 // <editor-fold defaultstate="collapsed" desc="Visitors"> 3447 /** 3448 * A default visitor for types. All visitor methods except 3449 * visitType are implemented by delegating to visitType. Concrete 3450 * subclasses must provide an implementation of visitType and can 3451 * override other methods as needed. 3452 * 3453 * @param <R> the return type of the operation implemented by this 3454 * visitor; use Void if no return type is needed. 3455 * @param <S> the type of the second argument (the first being the 3456 * type itself) of the operation implemented by this visitor; use 3457 * Void if a second argument is not needed. 3458 */ 3459 public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> { 3460 final public R visit(Type t, S s) { return t.accept(this, s); } 3461 public R visitClassType(ClassType t, S s) { return visitType(t, s); } 3462 public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); } 3463 public R visitArrayType(ArrayType t, S s) { return visitType(t, s); } 3464 public R visitMethodType(MethodType t, S s) { return visitType(t, s); } 3465 public R visitPackageType(PackageType t, S s) { return visitType(t, s); } 3466 public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); } 3467 public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); } 3468 public R visitForAll(ForAll t, S s) { return visitType(t, s); } 3469 public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); } 3470 public R visitErrorType(ErrorType t, S s) { return visitType(t, s); } 3471 } 3472 3473 /** 3474 * A default visitor for symbols. All visitor methods except 3475 * visitSymbol are implemented by delegating to visitSymbol. Concrete 3476 * subclasses must provide an implementation of visitSymbol and can 3477 * override other methods as needed. 3478 * 3479 * @param <R> the return type of the operation implemented by this 3480 * visitor; use Void if no return type is needed. 3481 * @param <S> the type of the second argument (the first being the 3482 * symbol itself) of the operation implemented by this visitor; use 3483 * Void if a second argument is not needed. 3484 */ 3485 public static abstract class DefaultSymbolVisitor<R,S> implements Symbol.Visitor<R,S> { 3486 final public R visit(Symbol s, S arg) { return s.accept(this, arg); } 3487 public R visitClassSymbol(ClassSymbol s, S arg) { return visitSymbol(s, arg); } 3488 public R visitMethodSymbol(MethodSymbol s, S arg) { return visitSymbol(s, arg); } 3489 public R visitOperatorSymbol(OperatorSymbol s, S arg) { return visitSymbol(s, arg); } 3490 public R visitPackageSymbol(PackageSymbol s, S arg) { return visitSymbol(s, arg); } 3491 public R visitTypeSymbol(TypeSymbol s, S arg) { return visitSymbol(s, arg); } 3492 public R visitVarSymbol(VarSymbol s, S arg) { return visitSymbol(s, arg); } 3493 } 3494 3495 /** 3496 * A <em>simple</em> visitor for types. This visitor is simple as 3497 * captured wildcards, for-all types (generic methods), and 3498 * undetermined type variables (part of inference) are hidden. 3499 * Captured wildcards are hidden by treating them as type 3500 * variables and the rest are hidden by visiting their qtypes. 3501 * 3502 * @param <R> the return type of the operation implemented by this 3503 * visitor; use Void if no return type is needed. 3504 * @param <S> the type of the second argument (the first being the 3505 * type itself) of the operation implemented by this visitor; use 3506 * Void if a second argument is not needed. 3507 */ 3508 public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> { 3509 @Override 3510 public R visitCapturedType(CapturedType t, S s) { 3511 return visitTypeVar(t, s); 3512 } 3513 @Override 3514 public R visitForAll(ForAll t, S s) { 3515 return visit(t.qtype, s); 3516 } 3517 @Override 3518 public R visitUndetVar(UndetVar t, S s) { 3519 return visit(t.qtype, s); 3520 } 3521 } 3522 3523 /** 3524 * A plain relation on types. That is a 2-ary function on the 3525 * form Type × Type → Boolean. 3526 * <!-- In plain text: Type x Type -> Boolean --> 3527 */ 3528 public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {} 3529 3530 /** 3531 * A convenience visitor for implementing operations that only 3532 * require one argument (the type itself), that is, unary 3533 * operations. 3534 * 3535 * @param <R> the return type of the operation implemented by this 3536 * visitor; use Void if no return type is needed. 3537 */ 3538 public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> { 3539 final public R visit(Type t) { return t.accept(this, null); } 3540 } 3541 3542 /** 3543 * A visitor for implementing a mapping from types to types. The 3544 * default behavior of this class is to implement the identity 3545 * mapping (mapping a type to itself). This can be overridden in 3546 * subclasses. 3547 * 3548 * @param <S> the type of the second argument (the first being the 3549 * type itself) of this mapping; use Void if a second argument is 3550 * not needed. 3551 */ 3552 public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> { 3553 final public Type visit(Type t) { return t.accept(this, null); } 3554 public Type visitType(Type t, S s) { return t; } 3555 } 3556 // </editor-fold> 3557 }