1 /* 2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.javac.code; 27 28 import java.lang.ref.SoftReference; 29 import java.util.Comparator; 30 import java.util.HashSet; 31 import java.util.HashMap; 32 import java.util.Locale; 33 import java.util.Map; 34 import java.util.Set; 35 import java.util.WeakHashMap; 36 37 import javax.lang.model.type.TypeKind; 38 39 import com.sun.tools.javac.code.Attribute.RetentionPolicy; 40 import com.sun.tools.javac.code.Lint.LintCategory; 41 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; 42 import com.sun.tools.javac.comp.Check; 43 import com.sun.tools.javac.jvm.ClassReader; 44 import com.sun.tools.javac.util.*; 45 import static com.sun.tools.javac.code.BoundKind.*; 46 import static com.sun.tools.javac.code.Flags.*; 47 import static com.sun.tools.javac.code.Scope.*; 48 import static com.sun.tools.javac.code.Symbol.*; 49 import static com.sun.tools.javac.code.Type.*; 50 import static com.sun.tools.javac.code.TypeTag.*; 51 import static com.sun.tools.javac.jvm.ClassFile.externalize; 52 import static com.sun.tools.javac.util.ListBuffer.lb; 53 54 /** 55 * Utility class containing various operations on types. 56 * 57 * <p>Unless other names are more illustrative, the following naming 58 * conventions should be observed in this file: 59 * 60 * <dl> 61 * <dt>t</dt> 62 * <dd>If the first argument to an operation is a type, it should be named t.</dd> 63 * <dt>s</dt> 64 * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd> 65 * <dt>ts</dt> 66 * <dd>If an operations takes a list of types, the first should be named ts.</dd> 67 * <dt>ss</dt> 68 * <dd>A second list of types should be named ss.</dd> 69 * </dl> 70 * 71 * <p><b>This is NOT part of any supported API. 72 * If you write code that depends on this, you do so at your own risk. 73 * This code and its internal interfaces are subject to change or 74 * deletion without notice.</b> 75 */ 76 public class Types { 77 protected static final Context.Key<Types> typesKey = 78 new Context.Key<Types>(); 79 80 final Symtab syms; 81 final JavacMessages messages; 82 final Names names; 83 final boolean allowBoxing; 84 final boolean allowCovariantReturns; 85 final boolean allowObjectToPrimitiveCast; 86 final boolean allowDefaultMethods; 87 final ClassReader reader; 88 final Check chk; 89 JCDiagnostic.Factory diags; 90 List<Warner> warnStack = List.nil(); 91 final Name capturedName; 92 private final FunctionDescriptorLookupError functionDescriptorLookupError; 93 94 public final Warner noWarnings; 95 96 // <editor-fold defaultstate="collapsed" desc="Instantiating"> 97 public static Types instance(Context context) { 98 Types instance = context.get(typesKey); 99 if (instance == null) 100 instance = new Types(context); 101 return instance; 102 } 103 104 protected Types(Context context) { 105 context.put(typesKey, this); 106 syms = Symtab.instance(context); 107 names = Names.instance(context); 108 Source source = Source.instance(context); 109 allowBoxing = source.allowBoxing(); 110 allowCovariantReturns = source.allowCovariantReturns(); 111 allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast(); 112 allowDefaultMethods = source.allowDefaultMethods(); 113 reader = ClassReader.instance(context); 114 chk = Check.instance(context); 115 capturedName = names.fromString("<captured wildcard>"); 116 messages = JavacMessages.instance(context); 117 diags = JCDiagnostic.Factory.instance(context); 118 functionDescriptorLookupError = new FunctionDescriptorLookupError(); 119 noWarnings = new Warner(null); 120 } 121 // </editor-fold> 122 123 // <editor-fold defaultstate="collapsed" desc="upperBound"> 124 /** 125 * The "rvalue conversion".<br> 126 * The upper bound of most types is the type 127 * itself. Wildcards, on the other hand have upper 128 * and lower bounds. 129 * @param t a type 130 * @return the upper bound of the given type 131 */ 132 public Type upperBound(Type t) { 133 return upperBound.visit(t); 134 } 135 // where 136 private final MapVisitor<Void> upperBound = new MapVisitor<Void>() { 137 138 @Override 139 public Type visitWildcardType(WildcardType t, Void ignored) { 140 if (t.isSuperBound()) 141 return t.bound == null ? syms.objectType : t.bound.bound; 142 else 143 return visit(t.type); 144 } 145 146 @Override 147 public Type visitCapturedType(CapturedType t, Void ignored) { 148 return visit(t.bound); 149 } 150 }; 151 // </editor-fold> 152 153 // <editor-fold defaultstate="collapsed" desc="lowerBound"> 154 /** 155 * The "lvalue conversion".<br> 156 * The lower bound of most types is the type 157 * itself. Wildcards, on the other hand have upper 158 * and lower bounds. 159 * @param t a type 160 * @return the lower bound of the given type 161 */ 162 public Type lowerBound(Type t) { 163 return lowerBound.visit(t); 164 } 165 // where 166 private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() { 167 168 @Override 169 public Type visitWildcardType(WildcardType t, Void ignored) { 170 return t.isExtendsBound() ? syms.botType : visit(t.type); 171 } 172 173 @Override 174 public Type visitCapturedType(CapturedType t, Void ignored) { 175 return visit(t.getLowerBound()); 176 } 177 }; 178 // </editor-fold> 179 180 // <editor-fold defaultstate="collapsed" desc="isUnbounded"> 181 /** 182 * Checks that all the arguments to a class are unbounded 183 * wildcards or something else that doesn't make any restrictions 184 * on the arguments. If a class isUnbounded, a raw super- or 185 * subclass can be cast to it without a warning. 186 * @param t a type 187 * @return true iff the given type is unbounded or raw 188 */ 189 public boolean isUnbounded(Type t) { 190 return isUnbounded.visit(t); 191 } 192 // where 193 private final UnaryVisitor<Boolean> isUnbounded = new UnaryVisitor<Boolean>() { 194 195 public Boolean visitType(Type t, Void ignored) { 196 return true; 197 } 198 199 @Override 200 public Boolean visitClassType(ClassType t, Void ignored) { 201 List<Type> parms = t.tsym.type.allparams(); 202 List<Type> args = t.allparams(); 203 while (parms.nonEmpty()) { 204 WildcardType unb = new WildcardType(syms.objectType, 205 BoundKind.UNBOUND, 206 syms.boundClass, 207 (TypeVar)parms.head); 208 if (!containsType(args.head, unb)) 209 return false; 210 parms = parms.tail; 211 args = args.tail; 212 } 213 return true; 214 } 215 }; 216 // </editor-fold> 217 218 // <editor-fold defaultstate="collapsed" desc="asSub"> 219 /** 220 * Return the least specific subtype of t that starts with symbol 221 * sym. If none exists, return null. The least specific subtype 222 * is determined as follows: 223 * 224 * <p>If there is exactly one parameterized instance of sym that is a 225 * subtype of t, that parameterized instance is returned.<br> 226 * Otherwise, if the plain type or raw type `sym' is a subtype of 227 * type t, the type `sym' itself is returned. Otherwise, null is 228 * returned. 229 */ 230 public Type asSub(Type t, Symbol sym) { 231 return asSub.visit(t, sym); 232 } 233 // where 234 private final SimpleVisitor<Type,Symbol> asSub = new SimpleVisitor<Type,Symbol>() { 235 236 public Type visitType(Type t, Symbol sym) { 237 return null; 238 } 239 240 @Override 241 public Type visitClassType(ClassType t, Symbol sym) { 242 if (t.tsym == sym) 243 return t; 244 Type base = asSuper(sym.type, t.tsym); 245 if (base == null) 246 return null; 247 ListBuffer<Type> from = new ListBuffer<Type>(); 248 ListBuffer<Type> to = new ListBuffer<Type>(); 249 try { 250 adapt(base, t, from, to); 251 } catch (AdaptFailure ex) { 252 return null; 253 } 254 Type res = subst(sym.type, from.toList(), to.toList()); 255 if (!isSubtype(res, t)) 256 return null; 257 ListBuffer<Type> openVars = new ListBuffer<Type>(); 258 for (List<Type> l = sym.type.allparams(); 259 l.nonEmpty(); l = l.tail) 260 if (res.contains(l.head) && !t.contains(l.head)) 261 openVars.append(l.head); 262 if (openVars.nonEmpty()) { 263 if (t.isRaw()) { 264 // The subtype of a raw type is raw 265 res = erasure(res); 266 } else { 267 // Unbound type arguments default to ? 268 List<Type> opens = openVars.toList(); 269 ListBuffer<Type> qs = new ListBuffer<Type>(); 270 for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) { 271 qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head)); 272 } 273 res = subst(res, opens, qs.toList()); 274 } 275 } 276 return res; 277 } 278 279 @Override 280 public Type visitErrorType(ErrorType t, Symbol sym) { 281 return t; 282 } 283 }; 284 // </editor-fold> 285 286 // <editor-fold defaultstate="collapsed" desc="isConvertible"> 287 /** 288 * Is t a subtype of or convertible via boxing/unboxing 289 * conversion to s? 290 */ 291 public boolean isConvertible(Type t, Type s, Warner warn) { 292 if (t.tag == ERROR) 293 return true; 294 boolean tPrimitive = t.isPrimitive(); 295 boolean sPrimitive = s.isPrimitive(); 296 if (tPrimitive == sPrimitive) { 297 return isSubtypeUnchecked(t, s, warn); 298 } 299 if (!allowBoxing) return false; 300 return tPrimitive 301 ? isSubtype(boxedClass(t).type, s) 302 : isSubtype(unboxedType(t), s); 303 } 304 305 /** 306 * Is t a subtype of or convertiable via boxing/unboxing 307 * convertions to s? 308 */ 309 public boolean isConvertible(Type t, Type s) { 310 return isConvertible(t, s, noWarnings); 311 } 312 // </editor-fold> 313 314 // <editor-fold defaultstate="collapsed" desc="findSam"> 315 316 /** 317 * Exception used to report a function descriptor lookup failure. The exception 318 * wraps a diagnostic that can be used to generate more details error 319 * messages. 320 */ 321 public static class FunctionDescriptorLookupError extends RuntimeException { 322 private static final long serialVersionUID = 0; 323 324 JCDiagnostic diagnostic; 325 326 FunctionDescriptorLookupError() { 327 this.diagnostic = null; 328 } 329 330 FunctionDescriptorLookupError setMessage(JCDiagnostic diag) { 331 this.diagnostic = diag; 332 return this; 333 } 334 335 public JCDiagnostic getDiagnostic() { 336 return diagnostic; 337 } 338 } 339 340 /** 341 * A cache that keeps track of function descriptors associated with given 342 * functional interfaces. 343 */ 344 class DescriptorCache { 345 346 private WeakHashMap<TypeSymbol, Entry> _map = new WeakHashMap<TypeSymbol, Entry>(); 347 348 class FunctionDescriptor { 349 Symbol descSym; 350 351 FunctionDescriptor(Symbol descSym) { 352 this.descSym = descSym; 353 } 354 355 public Symbol getSymbol() { 356 return descSym; 357 } 358 359 public Type getType(Type site) { 360 site = removeWildcards(site); 361 if (!chk.checkValidGenericType(site)) { 362 //if the inferred functional interface type is not well-formed, 363 //or if it's not a subtype of the original target, issue an error 364 throw failure(diags.fragment("no.suitable.functional.intf.inst", site)); 365 } 366 return memberType(site, descSym); 367 } 368 } 369 370 class Entry { 371 final FunctionDescriptor cachedDescRes; 372 final int prevMark; 373 374 public Entry(FunctionDescriptor cachedDescRes, 375 int prevMark) { 376 this.cachedDescRes = cachedDescRes; 377 this.prevMark = prevMark; 378 } 379 380 boolean matches(int mark) { 381 return this.prevMark == mark; 382 } 383 } 384 385 FunctionDescriptor get(TypeSymbol origin) throws FunctionDescriptorLookupError { 386 Entry e = _map.get(origin); 387 CompoundScope members = membersClosure(origin.type, false); 388 if (e == null || 389 !e.matches(members.getMark())) { 390 FunctionDescriptor descRes = findDescriptorInternal(origin, members); 391 _map.put(origin, new Entry(descRes, members.getMark())); 392 return descRes; 393 } 394 else { 395 return e.cachedDescRes; 396 } 397 } 398 399 /** 400 * Compute the function descriptor associated with a given functional interface 401 */ 402 public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, CompoundScope membersCache) throws FunctionDescriptorLookupError { 403 if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) { 404 //t must be an interface 405 throw failure("not.a.functional.intf", origin); 406 } 407 408 final ListBuffer<Symbol> abstracts = ListBuffer.lb(); 409 for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) { 410 Type mtype = memberType(origin.type, sym); 411 if (abstracts.isEmpty() || 412 (sym.name == abstracts.first().name && 413 overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) { 414 abstracts.append(sym); 415 } else { 416 //the target method(s) should be the only abstract members of t 417 throw failure("not.a.functional.intf.1", origin, 418 diags.fragment("incompatible.abstracts", Kinds.kindName(origin), origin)); 419 } 420 } 421 if (abstracts.isEmpty()) { 422 //t must define a suitable non-generic method 423 throw failure("not.a.functional.intf.1", origin, 424 diags.fragment("no.abstracts", Kinds.kindName(origin), origin)); 425 } else if (abstracts.size() == 1) { 426 return new FunctionDescriptor(abstracts.first()); 427 } else { // size > 1 428 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList()); 429 if (descRes == null) { 430 //we can get here if the functional interface is ill-formed 431 ListBuffer<JCDiagnostic> descriptors = ListBuffer.lb(); 432 for (Symbol desc : abstracts) { 433 String key = desc.type.getThrownTypes().nonEmpty() ? 434 "descriptor.throws" : "descriptor"; 435 descriptors.append(diags.fragment(key, desc.name, 436 desc.type.getParameterTypes(), 437 desc.type.getReturnType(), 438 desc.type.getThrownTypes())); 439 } 440 JCDiagnostic.MultilineDiagnostic incompatibleDescriptors = 441 new JCDiagnostic.MultilineDiagnostic(diags.fragment("incompatible.descs.in.functional.intf", 442 Kinds.kindName(origin), origin), descriptors.toList()); 443 throw failure(incompatibleDescriptors); 444 } 445 return descRes; 446 } 447 } 448 449 /** 450 * Compute a synthetic type for the target descriptor given a list 451 * of override-equivalent methods in the functional interface type. 452 * The resulting method type is a method type that is override-equivalent 453 * and return-type substitutable with each method in the original list. 454 */ 455 private FunctionDescriptor mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) { 456 //pick argument types - simply take the signature that is a 457 //subsignature of all other signatures in the list (as per JLS 8.4.2) 458 List<Symbol> mostSpecific = List.nil(); 459 outer: for (Symbol msym1 : methodSyms) { 460 Type mt1 = memberType(origin.type, msym1); 461 for (Symbol msym2 : methodSyms) { 462 Type mt2 = memberType(origin.type, msym2); 463 if (!isSubSignature(mt1, mt2)) { 464 continue outer; 465 } 466 } 467 mostSpecific = mostSpecific.prepend(msym1); 468 } 469 if (mostSpecific.isEmpty()) { 470 return null; 471 } 472 473 474 //pick return types - this is done in two phases: (i) first, the most 475 //specific return type is chosen using strict subtyping; if this fails, 476 //a second attempt is made using return type substitutability (see JLS 8.4.5) 477 boolean phase2 = false; 478 Symbol bestSoFar = null; 479 while (bestSoFar == null) { 480 outer: for (Symbol msym1 : mostSpecific) { 481 Type mt1 = memberType(origin.type, msym1); 482 for (Symbol msym2 : methodSyms) { 483 Type mt2 = memberType(origin.type, msym2); 484 if (phase2 ? 485 !returnTypeSubstitutable(mt1, mt2) : 486 !isSubtypeInternal(mt1.getReturnType(), mt2.getReturnType())) { 487 continue outer; 488 } 489 } 490 bestSoFar = msym1; 491 } 492 if (phase2) { 493 break; 494 } else { 495 phase2 = true; 496 } 497 } 498 if (bestSoFar == null) return null; 499 500 //merge thrown types - form the intersection of all the thrown types in 501 //all the signatures in the list 502 List<Type> thrown = null; 503 for (Symbol msym1 : methodSyms) { 504 Type mt1 = memberType(origin.type, msym1); 505 thrown = (thrown == null) ? 506 mt1.getThrownTypes() : 507 chk.intersect(mt1.getThrownTypes(), thrown); 508 } 509 510 final List<Type> thrown1 = thrown; 511 return new FunctionDescriptor(bestSoFar) { 512 @Override 513 public Type getType(Type origin) { 514 Type mt = memberType(origin, getSymbol()); 515 return createMethodTypeWithThrown(mt, thrown1); 516 } 517 }; 518 } 519 520 boolean isSubtypeInternal(Type s, Type t) { 521 return (s.isPrimitive() && t.isPrimitive()) ? 522 isSameType(t, s) : 523 isSubtype(s, t); 524 } 525 526 FunctionDescriptorLookupError failure(String msg, Object... args) { 527 return failure(diags.fragment(msg, args)); 528 } 529 530 FunctionDescriptorLookupError failure(JCDiagnostic diag) { 531 return functionDescriptorLookupError.setMessage(diag); 532 } 533 } 534 535 private DescriptorCache descCache = new DescriptorCache(); 536 537 /** 538 * Find the method descriptor associated to this class symbol - if the 539 * symbol 'origin' is not a functional interface, an exception is thrown. 540 */ 541 public Symbol findDescriptorSymbol(TypeSymbol origin) throws FunctionDescriptorLookupError { 542 return descCache.get(origin).getSymbol(); 543 } 544 545 /** 546 * Find the type of the method descriptor associated to this class symbol - 547 * if the symbol 'origin' is not a functional interface, an exception is thrown. 548 */ 549 public Type findDescriptorType(Type origin) throws FunctionDescriptorLookupError { 550 return descCache.get(origin.tsym).getType(origin); 551 } 552 553 /** 554 * Is given type a functional interface? 555 */ 556 public boolean isFunctionalInterface(TypeSymbol tsym) { 557 try { 558 findDescriptorSymbol(tsym); 559 return true; 560 } catch (FunctionDescriptorLookupError ex) { 561 return false; 562 } 563 } 564 565 public boolean isFunctionalInterface(Type site) { 566 try { 567 findDescriptorType(site); 568 return true; 569 } catch (FunctionDescriptorLookupError ex) { 570 return false; 571 } 572 } 573 574 public Type removeWildcards(Type site) { 575 Type capturedSite = capture(site); 576 if (capturedSite != site) { 577 Type formalInterface = site.tsym.type; 578 ListBuffer<Type> typeargs = ListBuffer.lb(); 579 List<Type> actualTypeargs = site.getTypeArguments(); 580 List<Type> capturedTypeargs = capturedSite.getTypeArguments(); 581 //simply replace the wildcards with its bound 582 for (Type t : formalInterface.getTypeArguments()) { 583 if (actualTypeargs.head.hasTag(WILDCARD)) { 584 WildcardType wt = (WildcardType)actualTypeargs.head; 585 Type bound; 586 switch (wt.kind) { 587 case EXTENDS: 588 case UNBOUND: 589 CapturedType capVar = (CapturedType)capturedTypeargs.head; 590 //use declared bound if it doesn't depend on formal type-args 591 bound = capVar.bound.containsAny(capturedSite.getTypeArguments()) ? 592 wt.type : capVar.bound; 593 break; 594 default: 595 bound = wt.type; 596 } 597 typeargs.append(bound); 598 } else { 599 typeargs.append(actualTypeargs.head); 600 } 601 actualTypeargs = actualTypeargs.tail; 602 capturedTypeargs = capturedTypeargs.tail; 603 } 604 return subst(formalInterface, formalInterface.getTypeArguments(), typeargs.toList()); 605 } else { 606 return site; 607 } 608 } 609 // </editor-fold> 610 611 /** 612 * Scope filter used to skip methods that should be ignored (such as methods 613 * overridden by j.l.Object) during function interface conversion interface check 614 */ 615 class DescriptorFilter implements Filter<Symbol> { 616 617 TypeSymbol origin; 618 619 DescriptorFilter(TypeSymbol origin) { 620 this.origin = origin; 621 } 622 623 @Override 624 public boolean accepts(Symbol sym) { 625 return sym.kind == Kinds.MTH && 626 (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT && 627 !overridesObjectMethod(origin, sym) && 628 (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0; 629 } 630 }; 631 632 // <editor-fold defaultstate="collapsed" desc="isSubtype"> 633 /** 634 * Is t an unchecked subtype of s? 635 */ 636 public boolean isSubtypeUnchecked(Type t, Type s) { 637 return isSubtypeUnchecked(t, s, noWarnings); 638 } 639 /** 640 * Is t an unchecked subtype of s? 641 */ 642 public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) { 643 boolean result = isSubtypeUncheckedInternal(t, s, warn); 644 if (result) { 645 checkUnsafeVarargsConversion(t, s, warn); 646 } 647 return result; 648 } 649 //where 650 private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) { 651 if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) { 652 t = t.unannotatedType(); 653 s = s.unannotatedType(); 654 if (((ArrayType)t).elemtype.isPrimitive()) { 655 return isSameType(elemtype(t), elemtype(s)); 656 } else { 657 return isSubtypeUnchecked(elemtype(t), elemtype(s), warn); 658 } 659 } else if (isSubtype(t, s)) { 660 return true; 661 } 662 else if (t.tag == TYPEVAR) { 663 return isSubtypeUnchecked(t.getUpperBound(), s, warn); 664 } 665 else if (!s.isRaw()) { 666 Type t2 = asSuper(t, s.tsym); 667 if (t2 != null && t2.isRaw()) { 668 if (isReifiable(s)) 669 warn.silentWarn(LintCategory.UNCHECKED); 670 else 671 warn.warn(LintCategory.UNCHECKED); 672 return true; 673 } 674 } 675 return false; 676 } 677 678 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { 679 if (t.tag != ARRAY || isReifiable(t)) 680 return; 681 t = t.unannotatedType(); 682 s = s.unannotatedType(); 683 ArrayType from = (ArrayType)t; 684 boolean shouldWarn = false; 685 switch (s.tag) { 686 case ARRAY: 687 ArrayType to = (ArrayType)s; 688 shouldWarn = from.isVarargs() && 689 !to.isVarargs() && 690 !isReifiable(from); 691 break; 692 case CLASS: 693 shouldWarn = from.isVarargs(); 694 break; 695 } 696 if (shouldWarn) { 697 warn.warn(LintCategory.VARARGS); 698 } 699 } 700 701 /** 702 * Is t a subtype of s?<br> 703 * (not defined for Method and ForAll types) 704 */ 705 final public boolean isSubtype(Type t, Type s) { 706 return isSubtype(t, s, true); 707 } 708 final public boolean isSubtypeNoCapture(Type t, Type s) { 709 return isSubtype(t, s, false); 710 } 711 public boolean isSubtype(Type t, Type s, boolean capture) { 712 if (t == s) 713 return true; 714 715 t = t.unannotatedType(); 716 s = s.unannotatedType(); 717 718 if (t == s) 719 return true; 720 721 if (s.isPartial()) 722 return isSuperType(s, t); 723 724 if (s.isCompound()) { 725 for (Type s2 : interfaces(s).prepend(supertype(s))) { 726 if (!isSubtype(t, s2, capture)) 727 return false; 728 } 729 return true; 730 } 731 732 Type lower = lowerBound(s); 733 if (s != lower) 734 return isSubtype(capture ? capture(t) : t, lower, false); 735 736 return isSubtype.visit(capture ? capture(t) : t, s); 737 } 738 // where 739 private TypeRelation isSubtype = new TypeRelation() 740 { 741 public Boolean visitType(Type t, Type s) { 742 switch (t.tag) { 743 case BYTE: 744 return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag())); 745 case CHAR: 746 return (!s.hasTag(SHORT) && t.getTag().isSubRangeOf(s.getTag())); 747 case SHORT: case INT: case LONG: 748 case FLOAT: case DOUBLE: 749 return t.getTag().isSubRangeOf(s.getTag()); 750 case BOOLEAN: case VOID: 751 return t.hasTag(s.getTag()); 752 case TYPEVAR: 753 return isSubtypeNoCapture(t.getUpperBound(), s); 754 case BOT: 755 return 756 s.hasTag(BOT) || s.hasTag(CLASS) || 757 s.hasTag(ARRAY) || s.hasTag(TYPEVAR); 758 case WILDCARD: //we shouldn't be here - avoids crash (see 7034495) 759 case NONE: 760 return false; 761 default: 762 throw new AssertionError("isSubtype " + t.tag); 763 } 764 } 765 766 private Set<TypePair> cache = new HashSet<TypePair>(); 767 768 private boolean containsTypeRecursive(Type t, Type s) { 769 TypePair pair = new TypePair(t, s); 770 if (cache.add(pair)) { 771 try { 772 return containsType(t.getTypeArguments(), 773 s.getTypeArguments()); 774 } finally { 775 cache.remove(pair); 776 } 777 } else { 778 return containsType(t.getTypeArguments(), 779 rewriteSupers(s).getTypeArguments()); 780 } 781 } 782 783 private Type rewriteSupers(Type t) { 784 if (!t.isParameterized()) 785 return t; 786 ListBuffer<Type> from = lb(); 787 ListBuffer<Type> to = lb(); 788 adaptSelf(t, from, to); 789 if (from.isEmpty()) 790 return t; 791 ListBuffer<Type> rewrite = lb(); 792 boolean changed = false; 793 for (Type orig : to.toList()) { 794 Type s = rewriteSupers(orig); 795 if (s.isSuperBound() && !s.isExtendsBound()) { 796 s = new WildcardType(syms.objectType, 797 BoundKind.UNBOUND, 798 syms.boundClass); 799 changed = true; 800 } else if (s != orig) { 801 s = new WildcardType(upperBound(s), 802 BoundKind.EXTENDS, 803 syms.boundClass); 804 changed = true; 805 } 806 rewrite.append(s); 807 } 808 if (changed) 809 return subst(t.tsym.type, from.toList(), rewrite.toList()); 810 else 811 return t; 812 } 813 814 @Override 815 public Boolean visitClassType(ClassType t, Type s) { 816 Type sup = asSuper(t, s.tsym); 817 return sup != null 818 && sup.tsym == s.tsym 819 // You're not allowed to write 820 // Vector<Object> vec = new Vector<String>(); 821 // But with wildcards you can write 822 // Vector<? extends Object> vec = new Vector<String>(); 823 // which means that subtype checking must be done 824 // here instead of same-type checking (via containsType). 825 && (!s.isParameterized() || containsTypeRecursive(s, sup)) 826 && isSubtypeNoCapture(sup.getEnclosingType(), 827 s.getEnclosingType()); 828 } 829 830 @Override 831 public Boolean visitArrayType(ArrayType t, Type s) { 832 if (s.tag == ARRAY) { 833 if (t.elemtype.isPrimitive()) 834 return isSameType(t.elemtype, elemtype(s)); 835 else 836 return isSubtypeNoCapture(t.elemtype, elemtype(s)); 837 } 838 839 if (s.tag == CLASS) { 840 Name sname = s.tsym.getQualifiedName(); 841 return sname == names.java_lang_Object 842 || sname == names.java_lang_Cloneable 843 || sname == names.java_io_Serializable; 844 } 845 846 return false; 847 } 848 849 @Override 850 public Boolean visitUndetVar(UndetVar t, Type s) { 851 //todo: test against origin needed? or replace with substitution? 852 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN) { 853 return true; 854 } else if (s.tag == BOT) { 855 //if 's' is 'null' there's no instantiated type U for which 856 //U <: s (but 'null' itself, which is not a valid type) 857 return false; 858 } 859 860 t.addBound(InferenceBound.UPPER, s, Types.this); 861 return true; 862 } 863 864 @Override 865 public Boolean visitErrorType(ErrorType t, Type s) { 866 return true; 867 } 868 }; 869 870 /** 871 * Is t a subtype of every type in given list `ts'?<br> 872 * (not defined for Method and ForAll types)<br> 873 * Allows unchecked conversions. 874 */ 875 public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) { 876 for (List<Type> l = ts; l.nonEmpty(); l = l.tail) 877 if (!isSubtypeUnchecked(t, l.head, warn)) 878 return false; 879 return true; 880 } 881 882 /** 883 * Are corresponding elements of ts subtypes of ss? If lists are 884 * of different length, return false. 885 */ 886 public boolean isSubtypes(List<Type> ts, List<Type> ss) { 887 while (ts.tail != null && ss.tail != null 888 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && 889 isSubtype(ts.head, ss.head)) { 890 ts = ts.tail; 891 ss = ss.tail; 892 } 893 return ts.tail == null && ss.tail == null; 894 /*inlined: ts.isEmpty() && ss.isEmpty();*/ 895 } 896 897 /** 898 * Are corresponding elements of ts subtypes of ss, allowing 899 * unchecked conversions? If lists are of different length, 900 * return false. 901 **/ 902 public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) { 903 while (ts.tail != null && ss.tail != null 904 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && 905 isSubtypeUnchecked(ts.head, ss.head, warn)) { 906 ts = ts.tail; 907 ss = ss.tail; 908 } 909 return ts.tail == null && ss.tail == null; 910 /*inlined: ts.isEmpty() && ss.isEmpty();*/ 911 } 912 // </editor-fold> 913 914 // <editor-fold defaultstate="collapsed" desc="isSuperType"> 915 /** 916 * Is t a supertype of s? 917 */ 918 public boolean isSuperType(Type t, Type s) { 919 switch (t.tag) { 920 case ERROR: 921 return true; 922 case UNDETVAR: { 923 UndetVar undet = (UndetVar)t; 924 if (t == s || 925 undet.qtype == s || 926 s.tag == ERROR || 927 s.tag == BOT) return true; 928 undet.addBound(InferenceBound.LOWER, s, this); 929 return true; 930 } 931 default: 932 return isSubtype(s, t); 933 } 934 } 935 // </editor-fold> 936 937 // <editor-fold defaultstate="collapsed" desc="isSameType"> 938 /** 939 * Are corresponding elements of the lists the same type? If 940 * lists are of different length, return false. 941 */ 942 public boolean isSameTypes(List<Type> ts, List<Type> ss) { 943 return isSameTypes(ts, ss, false); 944 } 945 public boolean isSameTypes(List<Type> ts, List<Type> ss, boolean strict) { 946 while (ts.tail != null && ss.tail != null 947 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && 948 isSameType(ts.head, ss.head, strict)) { 949 ts = ts.tail; 950 ss = ss.tail; 951 } 952 return ts.tail == null && ss.tail == null; 953 /*inlined: ts.isEmpty() && ss.isEmpty();*/ 954 } 955 956 /** 957 * Is t the same type as s? 958 */ 959 public boolean isSameType(Type t, Type s) { 960 return isSameType(t, s, false); 961 } 962 public boolean isSameType(Type t, Type s, boolean strict) { 963 return strict ? 964 isSameTypeStrict.visit(t, s) : 965 isSameTypeLoose.visit(t, s); 966 } 967 // where 968 abstract class SameTypeVisitor extends TypeRelation { 969 970 public Boolean visitType(Type t, Type s) { 971 if (t == s) 972 return true; 973 974 if (s.isPartial()) 975 return visit(s, t); 976 977 switch (t.tag) { 978 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: 979 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE: 980 return t.tag == s.tag; 981 case TYPEVAR: { 982 if (s.tag == TYPEVAR) { 983 //type-substitution does not preserve type-var types 984 //check that type var symbols and bounds are indeed the same 985 return sameTypeVars((TypeVar)t, (TypeVar)s); 986 } 987 else { 988 //special case for s == ? super X, where upper(s) = u 989 //check that u == t, where u has been set by Type.withTypeVar 990 return s.isSuperBound() && 991 !s.isExtendsBound() && 992 visit(t, upperBound(s)); 993 } 994 } 995 default: 996 throw new AssertionError("isSameType " + t.tag); 997 } 998 } 999 1000 abstract boolean sameTypeVars(TypeVar tv1, TypeVar tv2); 1001 1002 @Override 1003 public Boolean visitWildcardType(WildcardType t, Type s) { 1004 if (s.isPartial()) 1005 return visit(s, t); 1006 else 1007 return false; 1008 } 1009 1010 @Override 1011 public Boolean visitClassType(ClassType t, Type s) { 1012 if (t == s) 1013 return true; 1014 1015 if (s.isPartial()) 1016 return visit(s, t); 1017 1018 if (s.isSuperBound() && !s.isExtendsBound()) 1019 return visit(t, upperBound(s)) && visit(t, lowerBound(s)); 1020 1021 if (t.isCompound() && s.isCompound()) { 1022 if (!visit(supertype(t), supertype(s))) 1023 return false; 1024 1025 HashSet<UniqueType> set = new HashSet<UniqueType>(); 1026 for (Type x : interfaces(t)) 1027 set.add(new UniqueType(x, Types.this)); 1028 for (Type x : interfaces(s)) { 1029 if (!set.remove(new UniqueType(x, Types.this))) 1030 return false; 1031 } 1032 return (set.isEmpty()); 1033 } 1034 return t.tsym == s.tsym 1035 && visit(t.getEnclosingType(), s.getEnclosingType()) 1036 && containsTypes(t.getTypeArguments(), s.getTypeArguments()); 1037 } 1038 1039 abstract protected boolean containsTypes(List<Type> ts1, List<Type> ts2); 1040 1041 @Override 1042 public Boolean visitArrayType(ArrayType t, Type s) { 1043 if (t == s) 1044 return true; 1045 1046 if (s.isPartial()) 1047 return visit(s, t); 1048 1049 return s.hasTag(ARRAY) 1050 && containsTypeEquivalent(t.elemtype, elemtype(s)); 1051 } 1052 1053 @Override 1054 public Boolean visitMethodType(MethodType t, Type s) { 1055 // isSameType for methods does not take thrown 1056 // exceptions into account! 1057 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType()); 1058 } 1059 1060 @Override 1061 public Boolean visitPackageType(PackageType t, Type s) { 1062 return t == s; 1063 } 1064 1065 @Override 1066 public Boolean visitForAll(ForAll t, Type s) { 1067 if (s.tag != FORALL) 1068 return false; 1069 1070 ForAll forAll = (ForAll)s; 1071 return hasSameBounds(t, forAll) 1072 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars)); 1073 } 1074 1075 @Override 1076 public Boolean visitUndetVar(UndetVar t, Type s) { 1077 if (s.tag == WILDCARD) 1078 // FIXME, this might be leftovers from before capture conversion 1079 return false; 1080 1081 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN) 1082 return true; 1083 1084 t.addBound(InferenceBound.EQ, s, Types.this); 1085 1086 return true; 1087 } 1088 1089 @Override 1090 public Boolean visitErrorType(ErrorType t, Type s) { 1091 return true; 1092 } 1093 } 1094 1095 /** 1096 * Standard type-equality relation - type variables are considered 1097 * equals if they share the same type symbol. 1098 */ 1099 TypeRelation isSameTypeLoose = new SameTypeVisitor() { 1100 @Override 1101 boolean sameTypeVars(TypeVar tv1, TypeVar tv2) { 1102 return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound()); 1103 } 1104 @Override 1105 protected boolean containsTypes(List<Type> ts1, List<Type> ts2) { 1106 return containsTypeEquivalent(ts1, ts2); 1107 } 1108 }; 1109 1110 /** 1111 * Strict type-equality relation - type variables are considered 1112 * equals if they share the same object identity. 1113 */ 1114 TypeRelation isSameTypeStrict = new SameTypeVisitor() { 1115 @Override 1116 boolean sameTypeVars(TypeVar tv1, TypeVar tv2) { 1117 return tv1 == tv2; 1118 } 1119 @Override 1120 protected boolean containsTypes(List<Type> ts1, List<Type> ts2) { 1121 return isSameTypes(ts1, ts2, true); 1122 } 1123 1124 @Override 1125 public Boolean visitWildcardType(WildcardType t, Type s) { 1126 if (!s.hasTag(WILDCARD)) { 1127 return false; 1128 } else { 1129 WildcardType t2 = (WildcardType)s; 1130 return t.kind == t2.kind && 1131 isSameType(t.type, t2.type, true); 1132 } 1133 } 1134 }; 1135 // </editor-fold> 1136 1137 // <editor-fold defaultstate="collapsed" desc="Contains Type"> 1138 public boolean containedBy(Type t, Type s) { 1139 switch (t.tag) { 1140 case UNDETVAR: 1141 if (s.tag == WILDCARD) { 1142 UndetVar undetvar = (UndetVar)t; 1143 WildcardType wt = (WildcardType)s; 1144 switch(wt.kind) { 1145 case UNBOUND: //similar to ? extends Object 1146 case EXTENDS: { 1147 Type bound = upperBound(s); 1148 undetvar.addBound(InferenceBound.UPPER, bound, this); 1149 break; 1150 } 1151 case SUPER: { 1152 Type bound = lowerBound(s); 1153 undetvar.addBound(InferenceBound.LOWER, bound, this); 1154 break; 1155 } 1156 } 1157 return true; 1158 } else { 1159 return isSameType(t, s); 1160 } 1161 case ERROR: 1162 return true; 1163 default: 1164 return containsType(s, t); 1165 } 1166 } 1167 1168 boolean containsType(List<Type> ts, List<Type> ss) { 1169 while (ts.nonEmpty() && ss.nonEmpty() 1170 && containsType(ts.head, ss.head)) { 1171 ts = ts.tail; 1172 ss = ss.tail; 1173 } 1174 return ts.isEmpty() && ss.isEmpty(); 1175 } 1176 1177 /** 1178 * Check if t contains s. 1179 * 1180 * <p>T contains S if: 1181 * 1182 * <p>{@code L(T) <: L(S) && U(S) <: U(T)} 1183 * 1184 * <p>This relation is only used by ClassType.isSubtype(), that 1185 * is, 1186 * 1187 * <p>{@code C<S> <: C<T> if T contains S.} 1188 * 1189 * <p>Because of F-bounds, this relation can lead to infinite 1190 * recursion. Thus we must somehow break that recursion. Notice 1191 * that containsType() is only called from ClassType.isSubtype(). 1192 * Since the arguments have already been checked against their 1193 * bounds, we know: 1194 * 1195 * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)} 1196 * 1197 * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)} 1198 * 1199 * @param t a type 1200 * @param s a type 1201 */ 1202 public boolean containsType(Type t, Type s) { 1203 return containsType.visit(t, s); 1204 } 1205 // where 1206 private TypeRelation containsType = new TypeRelation() { 1207 1208 private Type U(Type t) { 1209 while (t.tag == WILDCARD) { 1210 WildcardType w = (WildcardType)t; 1211 if (w.isSuperBound()) 1212 return w.bound == null ? syms.objectType : w.bound.bound; 1213 else 1214 t = w.type; 1215 } 1216 return t; 1217 } 1218 1219 private Type L(Type t) { 1220 while (t.tag == WILDCARD) { 1221 WildcardType w = (WildcardType)t; 1222 if (w.isExtendsBound()) 1223 return syms.botType; 1224 else 1225 t = w.type; 1226 } 1227 return t; 1228 } 1229 1230 public Boolean visitType(Type t, Type s) { 1231 if (s.isPartial()) 1232 return containedBy(s, t); 1233 else 1234 return isSameType(t, s); 1235 } 1236 1237 // void debugContainsType(WildcardType t, Type s) { 1238 // System.err.println(); 1239 // System.err.format(" does %s contain %s?%n", t, s); 1240 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n", 1241 // upperBound(s), s, t, U(t), 1242 // t.isSuperBound() 1243 // || isSubtypeNoCapture(upperBound(s), U(t))); 1244 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n", 1245 // L(t), t, s, lowerBound(s), 1246 // t.isExtendsBound() 1247 // || isSubtypeNoCapture(L(t), lowerBound(s))); 1248 // System.err.println(); 1249 // } 1250 1251 @Override 1252 public Boolean visitWildcardType(WildcardType t, Type s) { 1253 if (s.isPartial()) 1254 return containedBy(s, t); 1255 else { 1256 // debugContainsType(t, s); 1257 return isSameWildcard(t, s) 1258 || isCaptureOf(s, t) 1259 || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) && 1260 (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t)))); 1261 } 1262 } 1263 1264 @Override 1265 public Boolean visitUndetVar(UndetVar t, Type s) { 1266 if (s.tag != WILDCARD) 1267 return isSameType(t, s); 1268 else 1269 return false; 1270 } 1271 1272 @Override 1273 public Boolean visitErrorType(ErrorType t, Type s) { 1274 return true; 1275 } 1276 }; 1277 1278 public boolean isCaptureOf(Type s, WildcardType t) { 1279 if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured()) 1280 return false; 1281 return isSameWildcard(t, ((CapturedType)s).wildcard); 1282 } 1283 1284 public boolean isSameWildcard(WildcardType t, Type s) { 1285 if (s.tag != WILDCARD) 1286 return false; 1287 WildcardType w = (WildcardType)s; 1288 return w.kind == t.kind && w.type == t.type; 1289 } 1290 1291 public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) { 1292 while (ts.nonEmpty() && ss.nonEmpty() 1293 && containsTypeEquivalent(ts.head, ss.head)) { 1294 ts = ts.tail; 1295 ss = ss.tail; 1296 } 1297 return ts.isEmpty() && ss.isEmpty(); 1298 } 1299 // </editor-fold> 1300 1301 /** 1302 * Can t and s be compared for equality? 1303 * 1304 */ 1305 public boolean isEqualityComparable(Type t, Type s, Warner warn) { 1306 if (t.tag == ERROR) 1307 return true; 1308 boolean tPrimitive = t.isPrimitive(); 1309 boolean sPrimitive = s.isPrimitive(); 1310 if (tPrimitive && sPrimitive) { 1311 return isSubtypeUnchecked(t, s, warn); 1312 } else if (!tPrimitive && !sPrimitive) 1313 return isCastable(t, s, warn); 1314 else if (allowBoxing) { 1315 return tPrimitive 1316 ? isSubtype(unboxedType(s), t) 1317 : isSubtype(unboxedType(t), s); 1318 } else 1319 return false; 1320 } 1321 1322 // <editor-fold defaultstate="collapsed" desc="isCastable"> 1323 public boolean isCastable(Type t, Type s) { 1324 return isCastable(t, s, noWarnings); 1325 } 1326 1327 /** 1328 * Is t is castable to s?<br> 1329 * s is assumed to be an erased type.<br> 1330 * (not defined for Method and ForAll types). 1331 */ 1332 public boolean isCastable(Type t, Type s, Warner warn) { 1333 if (t == s) 1334 return true; 1335 1336 if (t.isPrimitive() != s.isPrimitive()) 1337 return allowBoxing && ( 1338 isConvertible(t, s, warn) 1339 || (allowObjectToPrimitiveCast && 1340 s.isPrimitive() && 1341 isSubtype(boxedClass(s).type, t))); 1342 if (warn != warnStack.head) { 1343 try { 1344 warnStack = warnStack.prepend(warn); 1345 checkUnsafeVarargsConversion(t, s, warn); 1346 return isCastable.visit(t,s); 1347 } finally { 1348 warnStack = warnStack.tail; 1349 } 1350 } else { 1351 return isCastable.visit(t,s); 1352 } 1353 } 1354 // where 1355 private TypeRelation isCastable = new TypeRelation() { 1356 1357 public Boolean visitType(Type t, Type s) { 1358 if (s.tag == ERROR) 1359 return true; 1360 1361 switch (t.tag) { 1362 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: 1363 case DOUBLE: 1364 return s.isNumeric(); 1365 case BOOLEAN: 1366 return s.tag == BOOLEAN; 1367 case VOID: 1368 return false; 1369 case BOT: 1370 return isSubtype(t, s); 1371 default: 1372 throw new AssertionError(); 1373 } 1374 } 1375 1376 @Override 1377 public Boolean visitWildcardType(WildcardType t, Type s) { 1378 return isCastable(upperBound(t), s, warnStack.head); 1379 } 1380 1381 @Override 1382 public Boolean visitClassType(ClassType t, Type s) { 1383 if (s.tag == ERROR || s.tag == BOT) 1384 return true; 1385 1386 if (s.tag == TYPEVAR) { 1387 if (isCastable(t, s.getUpperBound(), noWarnings)) { 1388 warnStack.head.warn(LintCategory.UNCHECKED); 1389 return true; 1390 } else { 1391 return false; 1392 } 1393 } 1394 1395 if (t.isCompound() || s.isCompound()) { 1396 return !t.isCompound() ? 1397 visitIntersectionType((IntersectionClassType)s, t, true) : 1398 visitIntersectionType((IntersectionClassType)t, s, false); 1399 } 1400 1401 if (s.tag == CLASS || s.tag == ARRAY) { 1402 boolean upcast; 1403 if ((upcast = isSubtype(erasure(t), erasure(s))) 1404 || isSubtype(erasure(s), erasure(t))) { 1405 if (!upcast && s.tag == ARRAY) { 1406 if (!isReifiable(s)) 1407 warnStack.head.warn(LintCategory.UNCHECKED); 1408 return true; 1409 } else if (s.isRaw()) { 1410 return true; 1411 } else if (t.isRaw()) { 1412 if (!isUnbounded(s)) 1413 warnStack.head.warn(LintCategory.UNCHECKED); 1414 return true; 1415 } 1416 // Assume |a| <: |b| 1417 final Type a = upcast ? t : s; 1418 final Type b = upcast ? s : t; 1419 final boolean HIGH = true; 1420 final boolean LOW = false; 1421 final boolean DONT_REWRITE_TYPEVARS = false; 1422 Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS); 1423 Type aLow = rewriteQuantifiers(a, LOW, DONT_REWRITE_TYPEVARS); 1424 Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS); 1425 Type bLow = rewriteQuantifiers(b, LOW, DONT_REWRITE_TYPEVARS); 1426 Type lowSub = asSub(bLow, aLow.tsym); 1427 Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym); 1428 if (highSub == null) { 1429 final boolean REWRITE_TYPEVARS = true; 1430 aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS); 1431 aLow = rewriteQuantifiers(a, LOW, REWRITE_TYPEVARS); 1432 bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS); 1433 bLow = rewriteQuantifiers(b, LOW, REWRITE_TYPEVARS); 1434 lowSub = asSub(bLow, aLow.tsym); 1435 highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym); 1436 } 1437 if (highSub != null) { 1438 if (!(a.tsym == highSub.tsym && a.tsym == lowSub.tsym)) { 1439 Assert.error(a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym); 1440 } 1441 if (!disjointTypes(aHigh.allparams(), highSub.allparams()) 1442 && !disjointTypes(aHigh.allparams(), lowSub.allparams()) 1443 && !disjointTypes(aLow.allparams(), highSub.allparams()) 1444 && !disjointTypes(aLow.allparams(), lowSub.allparams())) { 1445 if (upcast ? giveWarning(a, b) : 1446 giveWarning(b, a)) 1447 warnStack.head.warn(LintCategory.UNCHECKED); 1448 return true; 1449 } 1450 } 1451 if (isReifiable(s)) 1452 return isSubtypeUnchecked(a, b); 1453 else 1454 return isSubtypeUnchecked(a, b, warnStack.head); 1455 } 1456 1457 // Sidecast 1458 if (s.tag == CLASS) { 1459 if ((s.tsym.flags() & INTERFACE) != 0) { 1460 return ((t.tsym.flags() & FINAL) == 0) 1461 ? sideCast(t, s, warnStack.head) 1462 : sideCastFinal(t, s, warnStack.head); 1463 } else if ((t.tsym.flags() & INTERFACE) != 0) { 1464 return ((s.tsym.flags() & FINAL) == 0) 1465 ? sideCast(t, s, warnStack.head) 1466 : sideCastFinal(t, s, warnStack.head); 1467 } else { 1468 // unrelated class types 1469 return false; 1470 } 1471 } 1472 } 1473 return false; 1474 } 1475 1476 boolean visitIntersectionType(IntersectionClassType ict, Type s, boolean reverse) { 1477 Warner warn = noWarnings; 1478 for (Type c : ict.getComponents()) { 1479 warn.clear(); 1480 if (reverse ? !isCastable(s, c, warn) : !isCastable(c, s, warn)) 1481 return false; 1482 } 1483 if (warn.hasLint(LintCategory.UNCHECKED)) 1484 warnStack.head.warn(LintCategory.UNCHECKED); 1485 return true; 1486 } 1487 1488 @Override 1489 public Boolean visitArrayType(ArrayType t, Type s) { 1490 switch (s.tag) { 1491 case ERROR: 1492 case BOT: 1493 return true; 1494 case TYPEVAR: 1495 if (isCastable(s, t, noWarnings)) { 1496 warnStack.head.warn(LintCategory.UNCHECKED); 1497 return true; 1498 } else { 1499 return false; 1500 } 1501 case CLASS: 1502 return isSubtype(t, s); 1503 case ARRAY: 1504 if (elemtype(t).isPrimitive() || elemtype(s).isPrimitive()) { 1505 return elemtype(t).tag == elemtype(s).tag; 1506 } else { 1507 return visit(elemtype(t), elemtype(s)); 1508 } 1509 default: 1510 return false; 1511 } 1512 } 1513 1514 @Override 1515 public Boolean visitTypeVar(TypeVar t, Type s) { 1516 switch (s.tag) { 1517 case ERROR: 1518 case BOT: 1519 return true; 1520 case TYPEVAR: 1521 if (isSubtype(t, s)) { 1522 return true; 1523 } else if (isCastable(t.bound, s, noWarnings)) { 1524 warnStack.head.warn(LintCategory.UNCHECKED); 1525 return true; 1526 } else { 1527 return false; 1528 } 1529 default: 1530 return isCastable(t.bound, s, warnStack.head); 1531 } 1532 } 1533 1534 @Override 1535 public Boolean visitErrorType(ErrorType t, Type s) { 1536 return true; 1537 } 1538 }; 1539 // </editor-fold> 1540 1541 // <editor-fold defaultstate="collapsed" desc="disjointTypes"> 1542 public boolean disjointTypes(List<Type> ts, List<Type> ss) { 1543 while (ts.tail != null && ss.tail != null) { 1544 if (disjointType(ts.head, ss.head)) return true; 1545 ts = ts.tail; 1546 ss = ss.tail; 1547 } 1548 return false; 1549 } 1550 1551 /** 1552 * Two types or wildcards are considered disjoint if it can be 1553 * proven that no type can be contained in both. It is 1554 * conservative in that it is allowed to say that two types are 1555 * not disjoint, even though they actually are. 1556 * 1557 * The type {@code C<X>} is castable to {@code C<Y>} exactly if 1558 * {@code X} and {@code Y} are not disjoint. 1559 */ 1560 public boolean disjointType(Type t, Type s) { 1561 return disjointType.visit(t, s); 1562 } 1563 // where 1564 private TypeRelation disjointType = new TypeRelation() { 1565 1566 private Set<TypePair> cache = new HashSet<TypePair>(); 1567 1568 public Boolean visitType(Type t, Type s) { 1569 if (s.tag == WILDCARD) 1570 return visit(s, t); 1571 else 1572 return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t); 1573 } 1574 1575 private boolean isCastableRecursive(Type t, Type s) { 1576 TypePair pair = new TypePair(t, s); 1577 if (cache.add(pair)) { 1578 try { 1579 return Types.this.isCastable(t, s); 1580 } finally { 1581 cache.remove(pair); 1582 } 1583 } else { 1584 return true; 1585 } 1586 } 1587 1588 private boolean notSoftSubtypeRecursive(Type t, Type s) { 1589 TypePair pair = new TypePair(t, s); 1590 if (cache.add(pair)) { 1591 try { 1592 return Types.this.notSoftSubtype(t, s); 1593 } finally { 1594 cache.remove(pair); 1595 } 1596 } else { 1597 return false; 1598 } 1599 } 1600 1601 @Override 1602 public Boolean visitWildcardType(WildcardType t, Type s) { 1603 if (t.isUnbound()) 1604 return false; 1605 1606 if (s.tag != WILDCARD) { 1607 if (t.isExtendsBound()) 1608 return notSoftSubtypeRecursive(s, t.type); 1609 else // isSuperBound() 1610 return notSoftSubtypeRecursive(t.type, s); 1611 } 1612 1613 if (s.isUnbound()) 1614 return false; 1615 1616 if (t.isExtendsBound()) { 1617 if (s.isExtendsBound()) 1618 return !isCastableRecursive(t.type, upperBound(s)); 1619 else if (s.isSuperBound()) 1620 return notSoftSubtypeRecursive(lowerBound(s), t.type); 1621 } else if (t.isSuperBound()) { 1622 if (s.isExtendsBound()) 1623 return notSoftSubtypeRecursive(t.type, upperBound(s)); 1624 } 1625 return false; 1626 } 1627 }; 1628 // </editor-fold> 1629 1630 // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes"> 1631 /** 1632 * Returns the lower bounds of the formals of a method. 1633 */ 1634 public List<Type> lowerBoundArgtypes(Type t) { 1635 return lowerBounds(t.getParameterTypes()); 1636 } 1637 public List<Type> lowerBounds(List<Type> ts) { 1638 return map(ts, lowerBoundMapping); 1639 } 1640 private final Mapping lowerBoundMapping = new Mapping("lowerBound") { 1641 public Type apply(Type t) { 1642 return lowerBound(t); 1643 } 1644 }; 1645 // </editor-fold> 1646 1647 // <editor-fold defaultstate="collapsed" desc="notSoftSubtype"> 1648 /** 1649 * This relation answers the question: is impossible that 1650 * something of type `t' can be a subtype of `s'? This is 1651 * different from the question "is `t' not a subtype of `s'?" 1652 * when type variables are involved: Integer is not a subtype of T 1653 * where {@code <T extends Number>} but it is not true that Integer cannot 1654 * possibly be a subtype of T. 1655 */ 1656 public boolean notSoftSubtype(Type t, Type s) { 1657 if (t == s) return false; 1658 if (t.tag == TYPEVAR) { 1659 TypeVar tv = (TypeVar) t; 1660 return !isCastable(tv.bound, 1661 relaxBound(s), 1662 noWarnings); 1663 } 1664 if (s.tag != WILDCARD) 1665 s = upperBound(s); 1666 1667 return !isSubtype(t, relaxBound(s)); 1668 } 1669 1670 private Type relaxBound(Type t) { 1671 if (t.tag == TYPEVAR) { 1672 while (t.tag == TYPEVAR) 1673 t = t.getUpperBound(); 1674 t = rewriteQuantifiers(t, true, true); 1675 } 1676 return t; 1677 } 1678 // </editor-fold> 1679 1680 // <editor-fold defaultstate="collapsed" desc="isReifiable"> 1681 public boolean isReifiable(Type t) { 1682 return isReifiable.visit(t); 1683 } 1684 // where 1685 private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() { 1686 1687 public Boolean visitType(Type t, Void ignored) { 1688 return true; 1689 } 1690 1691 @Override 1692 public Boolean visitClassType(ClassType t, Void ignored) { 1693 if (t.isCompound()) 1694 return false; 1695 else { 1696 if (!t.isParameterized()) 1697 return true; 1698 1699 for (Type param : t.allparams()) { 1700 if (!param.isUnbound()) 1701 return false; 1702 } 1703 return true; 1704 } 1705 } 1706 1707 @Override 1708 public Boolean visitArrayType(ArrayType t, Void ignored) { 1709 return visit(t.elemtype); 1710 } 1711 1712 @Override 1713 public Boolean visitTypeVar(TypeVar t, Void ignored) { 1714 return false; 1715 } 1716 }; 1717 // </editor-fold> 1718 1719 // <editor-fold defaultstate="collapsed" desc="Array Utils"> 1720 public boolean isArray(Type t) { 1721 while (t.tag == WILDCARD) 1722 t = upperBound(t); 1723 return t.tag == ARRAY; 1724 } 1725 1726 /** 1727 * The element type of an array. 1728 */ 1729 public Type elemtype(Type t) { 1730 switch (t.tag) { 1731 case WILDCARD: 1732 return elemtype(upperBound(t)); 1733 case ARRAY: 1734 t = t.unannotatedType(); 1735 return ((ArrayType)t).elemtype; 1736 case FORALL: 1737 return elemtype(((ForAll)t).qtype); 1738 case ERROR: 1739 return t; 1740 default: 1741 return null; 1742 } 1743 } 1744 1745 public Type elemtypeOrType(Type t) { 1746 Type elemtype = elemtype(t); 1747 return elemtype != null ? 1748 elemtype : 1749 t; 1750 } 1751 1752 /** 1753 * Mapping to take element type of an arraytype 1754 */ 1755 private Mapping elemTypeFun = new Mapping ("elemTypeFun") { 1756 public Type apply(Type t) { return elemtype(t); } 1757 }; 1758 1759 /** 1760 * The number of dimensions of an array type. 1761 */ 1762 public int dimensions(Type t) { 1763 int result = 0; 1764 while (t.tag == ARRAY) { 1765 result++; 1766 t = elemtype(t); 1767 } 1768 return result; 1769 } 1770 1771 /** 1772 * Returns an ArrayType with the component type t 1773 * 1774 * @param t The component type of the ArrayType 1775 * @return the ArrayType for the given component 1776 */ 1777 public ArrayType makeArrayType(Type t) { 1778 if (t.tag == VOID || 1779 t.tag == PACKAGE) { 1780 Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString()); 1781 } 1782 return new ArrayType(t, syms.arrayClass); 1783 } 1784 // </editor-fold> 1785 1786 // <editor-fold defaultstate="collapsed" desc="asSuper"> 1787 /** 1788 * Return the (most specific) base type of t that starts with the 1789 * given symbol. If none exists, return null. 1790 * 1791 * @param t a type 1792 * @param sym a symbol 1793 */ 1794 public Type asSuper(Type t, Symbol sym) { 1795 return asSuper.visit(t, sym); 1796 } 1797 // where 1798 private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() { 1799 1800 public Type visitType(Type t, Symbol sym) { 1801 return null; 1802 } 1803 1804 @Override 1805 public Type visitClassType(ClassType t, Symbol sym) { 1806 if (t.tsym == sym) 1807 return t; 1808 1809 Type st = supertype(t); 1810 if (st.tag == CLASS || st.tag == TYPEVAR || st.tag == ERROR) { 1811 Type x = asSuper(st, sym); 1812 if (x != null) 1813 return x; 1814 } 1815 if ((sym.flags() & INTERFACE) != 0) { 1816 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) { 1817 Type x = asSuper(l.head, sym); 1818 if (x != null) 1819 return x; 1820 } 1821 } 1822 return null; 1823 } 1824 1825 @Override 1826 public Type visitArrayType(ArrayType t, Symbol sym) { 1827 return isSubtype(t, sym.type) ? sym.type : null; 1828 } 1829 1830 @Override 1831 public Type visitTypeVar(TypeVar t, Symbol sym) { 1832 if (t.tsym == sym) 1833 return t; 1834 else 1835 return asSuper(t.bound, sym); 1836 } 1837 1838 @Override 1839 public Type visitErrorType(ErrorType t, Symbol sym) { 1840 return t; 1841 } 1842 }; 1843 1844 /** 1845 * Return the base type of t or any of its outer types that starts 1846 * with the given symbol. If none exists, return null. 1847 * 1848 * @param t a type 1849 * @param sym a symbol 1850 */ 1851 public Type asOuterSuper(Type t, Symbol sym) { 1852 switch (t.tag) { 1853 case CLASS: 1854 do { 1855 Type s = asSuper(t, sym); 1856 if (s != null) return s; 1857 t = t.getEnclosingType(); 1858 } while (t.tag == CLASS); 1859 return null; 1860 case ARRAY: 1861 return isSubtype(t, sym.type) ? sym.type : null; 1862 case TYPEVAR: 1863 return asSuper(t, sym); 1864 case ERROR: 1865 return t; 1866 default: 1867 return null; 1868 } 1869 } 1870 1871 /** 1872 * Return the base type of t or any of its enclosing types that 1873 * starts with the given symbol. If none exists, return null. 1874 * 1875 * @param t a type 1876 * @param sym a symbol 1877 */ 1878 public Type asEnclosingSuper(Type t, Symbol sym) { 1879 switch (t.tag) { 1880 case CLASS: 1881 do { 1882 Type s = asSuper(t, sym); 1883 if (s != null) return s; 1884 Type outer = t.getEnclosingType(); 1885 t = (outer.tag == CLASS) ? outer : 1886 (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type : 1887 Type.noType; 1888 } while (t.tag == CLASS); 1889 return null; 1890 case ARRAY: 1891 return isSubtype(t, sym.type) ? sym.type : null; 1892 case TYPEVAR: 1893 return asSuper(t, sym); 1894 case ERROR: 1895 return t; 1896 default: 1897 return null; 1898 } 1899 } 1900 // </editor-fold> 1901 1902 // <editor-fold defaultstate="collapsed" desc="memberType"> 1903 /** 1904 * The type of given symbol, seen as a member of t. 1905 * 1906 * @param t a type 1907 * @param sym a symbol 1908 */ 1909 public Type memberType(Type t, Symbol sym) { 1910 return (sym.flags() & STATIC) != 0 1911 ? sym.type 1912 : memberType.visit(t, sym); 1913 } 1914 // where 1915 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() { 1916 1917 public Type visitType(Type t, Symbol sym) { 1918 return sym.type; 1919 } 1920 1921 @Override 1922 public Type visitWildcardType(WildcardType t, Symbol sym) { 1923 return memberType(upperBound(t), sym); 1924 } 1925 1926 @Override 1927 public Type visitClassType(ClassType t, Symbol sym) { 1928 Symbol owner = sym.owner; 1929 long flags = sym.flags(); 1930 if (((flags & STATIC) == 0) && owner.type.isParameterized()) { 1931 Type base = asOuterSuper(t, owner); 1932 //if t is an intersection type T = CT & I1 & I2 ... & In 1933 //its supertypes CT, I1, ... In might contain wildcards 1934 //so we need to go through capture conversion 1935 base = t.isCompound() ? capture(base) : base; 1936 if (base != null) { 1937 List<Type> ownerParams = owner.type.allparams(); 1938 List<Type> baseParams = base.allparams(); 1939 if (ownerParams.nonEmpty()) { 1940 if (baseParams.isEmpty()) { 1941 // then base is a raw type 1942 return erasure(sym.type); 1943 } else { 1944 return subst(sym.type, ownerParams, baseParams); 1945 } 1946 } 1947 } 1948 } 1949 return sym.type; 1950 } 1951 1952 @Override 1953 public Type visitTypeVar(TypeVar t, Symbol sym) { 1954 return memberType(t.bound, sym); 1955 } 1956 1957 @Override 1958 public Type visitErrorType(ErrorType t, Symbol sym) { 1959 return t; 1960 } 1961 }; 1962 // </editor-fold> 1963 1964 // <editor-fold defaultstate="collapsed" desc="isAssignable"> 1965 public boolean isAssignable(Type t, Type s) { 1966 return isAssignable(t, s, noWarnings); 1967 } 1968 1969 /** 1970 * Is t assignable to s?<br> 1971 * Equivalent to subtype except for constant values and raw 1972 * types.<br> 1973 * (not defined for Method and ForAll types) 1974 */ 1975 public boolean isAssignable(Type t, Type s, Warner warn) { 1976 if (t.tag == ERROR) 1977 return true; 1978 if (t.tag.isSubRangeOf(INT) && t.constValue() != null) { 1979 int value = ((Number)t.constValue()).intValue(); 1980 switch (s.tag) { 1981 case BYTE: 1982 if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE) 1983 return true; 1984 break; 1985 case CHAR: 1986 if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE) 1987 return true; 1988 break; 1989 case SHORT: 1990 if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE) 1991 return true; 1992 break; 1993 case INT: 1994 return true; 1995 case CLASS: 1996 switch (unboxedType(s).tag) { 1997 case BYTE: 1998 case CHAR: 1999 case SHORT: 2000 return isAssignable(t, unboxedType(s), warn); 2001 } 2002 break; 2003 } 2004 } 2005 return isConvertible(t, s, warn); 2006 } 2007 // </editor-fold> 2008 2009 // <editor-fold defaultstate="collapsed" desc="erasure"> 2010 /** 2011 * The erasure of t {@code |t|} -- the type that results when all 2012 * type parameters in t are deleted. 2013 */ 2014 public Type erasure(Type t) { 2015 return eraseNotNeeded(t)? t : erasure(t, false); 2016 } 2017 //where 2018 private boolean eraseNotNeeded(Type t) { 2019 // We don't want to erase primitive types and String type as that 2020 // operation is idempotent. Also, erasing these could result in loss 2021 // of information such as constant values attached to such types. 2022 return (t.isPrimitive()) || (syms.stringType.tsym == t.tsym); 2023 } 2024 2025 private Type erasure(Type t, boolean recurse) { 2026 if (t.isPrimitive()) 2027 return t; /* fast special case */ 2028 else 2029 return erasure.visit(t, recurse); 2030 } 2031 // where 2032 private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() { 2033 public Type visitType(Type t, Boolean recurse) { 2034 if (t.isPrimitive()) 2035 return t; /*fast special case*/ 2036 else 2037 return t.map(recurse ? erasureRecFun : erasureFun); 2038 } 2039 2040 @Override 2041 public Type visitWildcardType(WildcardType t, Boolean recurse) { 2042 return erasure(upperBound(t), recurse); 2043 } 2044 2045 @Override 2046 public Type visitClassType(ClassType t, Boolean recurse) { 2047 Type erased = t.tsym.erasure(Types.this); 2048 if (recurse) { 2049 erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym); 2050 } 2051 return erased; 2052 } 2053 2054 @Override 2055 public Type visitTypeVar(TypeVar t, Boolean recurse) { 2056 return erasure(t.bound, recurse); 2057 } 2058 2059 @Override 2060 public Type visitErrorType(ErrorType t, Boolean recurse) { 2061 return t; 2062 } 2063 2064 @Override 2065 public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) { 2066 Type erased = erasure(t.underlyingType, recurse); 2067 if (erased.isAnnotated()) { 2068 // This can only happen when the underlying type is a 2069 // type variable and the upper bound of it is annotated. 2070 // The annotation on the type variable overrides the one 2071 // on the bound. 2072 erased = ((AnnotatedType)erased).underlyingType; 2073 } 2074 return new AnnotatedType(t.typeAnnotations, erased); 2075 } 2076 }; 2077 2078 private Mapping erasureFun = new Mapping ("erasure") { 2079 public Type apply(Type t) { return erasure(t); } 2080 }; 2081 2082 private Mapping erasureRecFun = new Mapping ("erasureRecursive") { 2083 public Type apply(Type t) { return erasureRecursive(t); } 2084 }; 2085 2086 public List<Type> erasure(List<Type> ts) { 2087 return Type.map(ts, erasureFun); 2088 } 2089 2090 public Type erasureRecursive(Type t) { 2091 return erasure(t, true); 2092 } 2093 2094 public List<Type> erasureRecursive(List<Type> ts) { 2095 return Type.map(ts, erasureRecFun); 2096 } 2097 // </editor-fold> 2098 2099 // <editor-fold defaultstate="collapsed" desc="makeCompoundType"> 2100 /** 2101 * Make a compound type from non-empty list of types 2102 * 2103 * @param bounds the types from which the compound type is formed 2104 * @param supertype is objectType if all bounds are interfaces, 2105 * null otherwise. 2106 */ 2107 public Type makeCompoundType(List<Type> bounds) { 2108 return makeCompoundType(bounds, bounds.head.tsym.isInterface()); 2109 } 2110 public Type makeCompoundType(List<Type> bounds, boolean allInterfaces) { 2111 Assert.check(bounds.nonEmpty()); 2112 Type firstExplicitBound = bounds.head; 2113 if (allInterfaces) { 2114 bounds = bounds.prepend(syms.objectType); 2115 } 2116 ClassSymbol bc = 2117 new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC, 2118 Type.moreInfo 2119 ? names.fromString(bounds.toString()) 2120 : names.empty, 2121 null, 2122 syms.noSymbol); 2123 bc.type = new IntersectionClassType(bounds, bc, allInterfaces); 2124 bc.erasure_field = (bounds.head.tag == TYPEVAR) ? 2125 syms.objectType : // error condition, recover 2126 erasure(firstExplicitBound); 2127 bc.members_field = new Scope(bc); 2128 return bc.type; 2129 } 2130 2131 /** 2132 * A convenience wrapper for {@link #makeCompoundType(List)}; the 2133 * arguments are converted to a list and passed to the other 2134 * method. Note that this might cause a symbol completion. 2135 * Hence, this version of makeCompoundType may not be called 2136 * during a classfile read. 2137 */ 2138 public Type makeCompoundType(Type bound1, Type bound2) { 2139 return makeCompoundType(List.of(bound1, bound2)); 2140 } 2141 // </editor-fold> 2142 2143 // <editor-fold defaultstate="collapsed" desc="supertype"> 2144 public Type supertype(Type t) { 2145 return supertype.visit(t); 2146 } 2147 // where 2148 private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() { 2149 2150 public Type visitType(Type t, Void ignored) { 2151 // A note on wildcards: there is no good way to 2152 // determine a supertype for a super bounded wildcard. 2153 return null; 2154 } 2155 2156 @Override 2157 public Type visitClassType(ClassType t, Void ignored) { 2158 if (t.supertype_field == null) { 2159 Type supertype = ((ClassSymbol)t.tsym).getSuperclass(); 2160 // An interface has no superclass; its supertype is Object. 2161 if (t.isInterface()) 2162 supertype = ((ClassType)t.tsym.type).supertype_field; 2163 if (t.supertype_field == null) { 2164 List<Type> actuals = classBound(t).allparams(); 2165 List<Type> formals = t.tsym.type.allparams(); 2166 if (t.hasErasedSupertypes()) { 2167 t.supertype_field = erasureRecursive(supertype); 2168 } else if (formals.nonEmpty()) { 2169 t.supertype_field = subst(supertype, formals, actuals); 2170 } 2171 else { 2172 t.supertype_field = supertype; 2173 } 2174 } 2175 } 2176 return t.supertype_field; 2177 } 2178 2179 /** 2180 * The supertype is always a class type. If the type 2181 * variable's bounds start with a class type, this is also 2182 * the supertype. Otherwise, the supertype is 2183 * java.lang.Object. 2184 */ 2185 @Override 2186 public Type visitTypeVar(TypeVar t, Void ignored) { 2187 if (t.bound.tag == TYPEVAR || 2188 (!t.bound.isCompound() && !t.bound.isInterface())) { 2189 return t.bound; 2190 } else { 2191 return supertype(t.bound); 2192 } 2193 } 2194 2195 @Override 2196 public Type visitArrayType(ArrayType t, Void ignored) { 2197 if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType)) 2198 return arraySuperType(); 2199 else 2200 return new ArrayType(supertype(t.elemtype), t.tsym); 2201 } 2202 2203 @Override 2204 public Type visitErrorType(ErrorType t, Void ignored) { 2205 return t; 2206 } 2207 }; 2208 // </editor-fold> 2209 2210 // <editor-fold defaultstate="collapsed" desc="interfaces"> 2211 /** 2212 * Return the interfaces implemented by this class. 2213 */ 2214 public List<Type> interfaces(Type t) { 2215 return interfaces.visit(t); 2216 } 2217 // where 2218 private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() { 2219 2220 public List<Type> visitType(Type t, Void ignored) { 2221 return List.nil(); 2222 } 2223 2224 @Override 2225 public List<Type> visitClassType(ClassType t, Void ignored) { 2226 if (t.interfaces_field == null) { 2227 List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces(); 2228 if (t.interfaces_field == null) { 2229 // If t.interfaces_field is null, then t must 2230 // be a parameterized type (not to be confused 2231 // with a generic type declaration). 2232 // Terminology: 2233 // Parameterized type: List<String> 2234 // Generic type declaration: class List<E> { ... } 2235 // So t corresponds to List<String> and 2236 // t.tsym.type corresponds to List<E>. 2237 // The reason t must be parameterized type is 2238 // that completion will happen as a side 2239 // effect of calling 2240 // ClassSymbol.getInterfaces. Since 2241 // t.interfaces_field is null after 2242 // completion, we can assume that t is not the 2243 // type of a class/interface declaration. 2244 Assert.check(t != t.tsym.type, t); 2245 List<Type> actuals = t.allparams(); 2246 List<Type> formals = t.tsym.type.allparams(); 2247 if (t.hasErasedSupertypes()) { 2248 t.interfaces_field = erasureRecursive(interfaces); 2249 } else if (formals.nonEmpty()) { 2250 t.interfaces_field = 2251 upperBounds(subst(interfaces, formals, actuals)); 2252 } 2253 else { 2254 t.interfaces_field = interfaces; 2255 } 2256 } 2257 } 2258 return t.interfaces_field; 2259 } 2260 2261 @Override 2262 public List<Type> visitTypeVar(TypeVar t, Void ignored) { 2263 if (t.bound.isCompound()) 2264 return interfaces(t.bound); 2265 2266 if (t.bound.isInterface()) 2267 return List.of(t.bound); 2268 2269 return List.nil(); 2270 } 2271 }; 2272 2273 public boolean isDirectSuperInterface(TypeSymbol isym, TypeSymbol origin) { 2274 for (Type i2 : interfaces(origin.type)) { 2275 if (isym == i2.tsym) return true; 2276 } 2277 return false; 2278 } 2279 // </editor-fold> 2280 2281 // <editor-fold defaultstate="collapsed" desc="isDerivedRaw"> 2282 Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>(); 2283 2284 public boolean isDerivedRaw(Type t) { 2285 Boolean result = isDerivedRawCache.get(t); 2286 if (result == null) { 2287 result = isDerivedRawInternal(t); 2288 isDerivedRawCache.put(t, result); 2289 } 2290 return result; 2291 } 2292 2293 public boolean isDerivedRawInternal(Type t) { 2294 if (t.isErroneous()) 2295 return false; 2296 return 2297 t.isRaw() || 2298 supertype(t) != null && isDerivedRaw(supertype(t)) || 2299 isDerivedRaw(interfaces(t)); 2300 } 2301 2302 public boolean isDerivedRaw(List<Type> ts) { 2303 List<Type> l = ts; 2304 while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail; 2305 return l.nonEmpty(); 2306 } 2307 // </editor-fold> 2308 2309 // <editor-fold defaultstate="collapsed" desc="setBounds"> 2310 /** 2311 * Set the bounds field of the given type variable to reflect a 2312 * (possibly multiple) list of bounds. 2313 * @param t a type variable 2314 * @param bounds the bounds, must be nonempty 2315 * @param supertype is objectType if all bounds are interfaces, 2316 * null otherwise. 2317 */ 2318 public void setBounds(TypeVar t, List<Type> bounds) { 2319 setBounds(t, bounds, bounds.head.tsym.isInterface()); 2320 } 2321 2322 /** 2323 * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that 2324 * third parameter is computed directly, as follows: if all 2325 * all bounds are interface types, the computed supertype is Object, 2326 * otherwise the supertype is simply left null (in this case, the supertype 2327 * is assumed to be the head of the bound list passed as second argument). 2328 * Note that this check might cause a symbol completion. Hence, this version of 2329 * setBounds may not be called during a classfile read. 2330 */ 2331 public void setBounds(TypeVar t, List<Type> bounds, boolean allInterfaces) { 2332 t.bound = bounds.tail.isEmpty() ? 2333 bounds.head : 2334 makeCompoundType(bounds, allInterfaces); 2335 t.rank_field = -1; 2336 } 2337 // </editor-fold> 2338 2339 // <editor-fold defaultstate="collapsed" desc="getBounds"> 2340 /** 2341 * Return list of bounds of the given type variable. 2342 */ 2343 public List<Type> getBounds(TypeVar t) { 2344 if (t.bound.hasTag(NONE)) 2345 return List.nil(); 2346 else if (t.bound.isErroneous() || !t.bound.isCompound()) 2347 return List.of(t.bound); 2348 else if ((erasure(t).tsym.flags() & INTERFACE) == 0) 2349 return interfaces(t).prepend(supertype(t)); 2350 else 2351 // No superclass was given in bounds. 2352 // In this case, supertype is Object, erasure is first interface. 2353 return interfaces(t); 2354 } 2355 // </editor-fold> 2356 2357 // <editor-fold defaultstate="collapsed" desc="classBound"> 2358 /** 2359 * If the given type is a (possibly selected) type variable, 2360 * return the bounding class of this type, otherwise return the 2361 * type itself. 2362 */ 2363 public Type classBound(Type t) { 2364 return classBound.visit(t); 2365 } 2366 // where 2367 private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() { 2368 2369 public Type visitType(Type t, Void ignored) { 2370 return t; 2371 } 2372 2373 @Override 2374 public Type visitClassType(ClassType t, Void ignored) { 2375 Type outer1 = classBound(t.getEnclosingType()); 2376 if (outer1 != t.getEnclosingType()) 2377 return new ClassType(outer1, t.getTypeArguments(), t.tsym); 2378 else 2379 return t; 2380 } 2381 2382 @Override 2383 public Type visitTypeVar(TypeVar t, Void ignored) { 2384 return classBound(supertype(t)); 2385 } 2386 2387 @Override 2388 public Type visitErrorType(ErrorType t, Void ignored) { 2389 return t; 2390 } 2391 }; 2392 // </editor-fold> 2393 2394 // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence"> 2395 /** 2396 * Returns true iff the first signature is a <em>sub 2397 * signature</em> of the other. This is <b>not</b> an equivalence 2398 * relation. 2399 * 2400 * @jls section 8.4.2. 2401 * @see #overrideEquivalent(Type t, Type s) 2402 * @param t first signature (possibly raw). 2403 * @param s second signature (could be subjected to erasure). 2404 * @return true if t is a sub signature of s. 2405 */ 2406 public boolean isSubSignature(Type t, Type s) { 2407 return isSubSignature(t, s, true); 2408 } 2409 2410 public boolean isSubSignature(Type t, Type s, boolean strict) { 2411 return hasSameArgs(t, s, strict) || hasSameArgs(t, erasure(s), strict); 2412 } 2413 2414 /** 2415 * Returns true iff these signatures are related by <em>override 2416 * equivalence</em>. This is the natural extension of 2417 * isSubSignature to an equivalence relation. 2418 * 2419 * @jls section 8.4.2. 2420 * @see #isSubSignature(Type t, Type s) 2421 * @param t a signature (possible raw, could be subjected to 2422 * erasure). 2423 * @param s a signature (possible raw, could be subjected to 2424 * erasure). 2425 * @return true if either argument is a sub signature of the other. 2426 */ 2427 public boolean overrideEquivalent(Type t, Type s) { 2428 return hasSameArgs(t, s) || 2429 hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s); 2430 } 2431 2432 public boolean overridesObjectMethod(TypeSymbol origin, Symbol msym) { 2433 for (Scope.Entry e = syms.objectType.tsym.members().lookup(msym.name) ; e.scope != null ; e = e.next()) { 2434 if (msym.overrides(e.sym, origin, Types.this, true)) { 2435 return true; 2436 } 2437 } 2438 return false; 2439 } 2440 2441 // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site"> 2442 class ImplementationCache { 2443 2444 private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>> _map = 2445 new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>>(); 2446 2447 class Entry { 2448 final MethodSymbol cachedImpl; 2449 final Filter<Symbol> implFilter; 2450 final boolean checkResult; 2451 final int prevMark; 2452 2453 public Entry(MethodSymbol cachedImpl, 2454 Filter<Symbol> scopeFilter, 2455 boolean checkResult, 2456 int prevMark) { 2457 this.cachedImpl = cachedImpl; 2458 this.implFilter = scopeFilter; 2459 this.checkResult = checkResult; 2460 this.prevMark = prevMark; 2461 } 2462 2463 boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, int mark) { 2464 return this.implFilter == scopeFilter && 2465 this.checkResult == checkResult && 2466 this.prevMark == mark; 2467 } 2468 } 2469 2470 MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) { 2471 SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms); 2472 Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null; 2473 if (cache == null) { 2474 cache = new HashMap<TypeSymbol, Entry>(); 2475 _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache)); 2476 } 2477 Entry e = cache.get(origin); 2478 CompoundScope members = membersClosure(origin.type, true); 2479 if (e == null || 2480 !e.matches(implFilter, checkResult, members.getMark())) { 2481 MethodSymbol impl = implementationInternal(ms, origin, checkResult, implFilter); 2482 cache.put(origin, new Entry(impl, implFilter, checkResult, members.getMark())); 2483 return impl; 2484 } 2485 else { 2486 return e.cachedImpl; 2487 } 2488 } 2489 2490 private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) { 2491 for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = supertype(t)) { 2492 while (t.tag == TYPEVAR) 2493 t = t.getUpperBound(); 2494 TypeSymbol c = t.tsym; 2495 for (Scope.Entry e = c.members().lookup(ms.name, implFilter); 2496 e.scope != null; 2497 e = e.next(implFilter)) { 2498 if (e.sym != null && 2499 e.sym.overrides(ms, origin, Types.this, checkResult)) 2500 return (MethodSymbol)e.sym; 2501 } 2502 } 2503 return null; 2504 } 2505 } 2506 2507 private ImplementationCache implCache = new ImplementationCache(); 2508 2509 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) { 2510 return implCache.get(ms, origin, checkResult, implFilter); 2511 } 2512 // </editor-fold> 2513 2514 // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site"> 2515 class MembersClosureCache extends SimpleVisitor<CompoundScope, Boolean> { 2516 2517 private WeakHashMap<TypeSymbol, Entry> _map = 2518 new WeakHashMap<TypeSymbol, Entry>(); 2519 2520 class Entry { 2521 final boolean skipInterfaces; 2522 final CompoundScope compoundScope; 2523 2524 public Entry(boolean skipInterfaces, CompoundScope compoundScope) { 2525 this.skipInterfaces = skipInterfaces; 2526 this.compoundScope = compoundScope; 2527 } 2528 2529 boolean matches(boolean skipInterfaces) { 2530 return this.skipInterfaces == skipInterfaces; 2531 } 2532 } 2533 2534 List<TypeSymbol> seenTypes = List.nil(); 2535 2536 /** members closure visitor methods **/ 2537 2538 public CompoundScope visitType(Type t, Boolean skipInterface) { 2539 return null; 2540 } 2541 2542 @Override 2543 public CompoundScope visitClassType(ClassType t, Boolean skipInterface) { 2544 if (seenTypes.contains(t.tsym)) { 2545 //this is possible when an interface is implemented in multiple 2546 //superclasses, or when a classs hierarchy is circular - in such 2547 //cases we don't need to recurse (empty scope is returned) 2548 return new CompoundScope(t.tsym); 2549 } 2550 try { 2551 seenTypes = seenTypes.prepend(t.tsym); 2552 ClassSymbol csym = (ClassSymbol)t.tsym; 2553 Entry e = _map.get(csym); 2554 if (e == null || !e.matches(skipInterface)) { 2555 CompoundScope membersClosure = new CompoundScope(csym); 2556 if (!skipInterface) { 2557 for (Type i : interfaces(t)) { 2558 membersClosure.addSubScope(visit(i, skipInterface)); 2559 } 2560 } 2561 membersClosure.addSubScope(visit(supertype(t), skipInterface)); 2562 membersClosure.addSubScope(csym.members()); 2563 e = new Entry(skipInterface, membersClosure); 2564 _map.put(csym, e); 2565 } 2566 return e.compoundScope; 2567 } 2568 finally { 2569 seenTypes = seenTypes.tail; 2570 } 2571 } 2572 2573 @Override 2574 public CompoundScope visitTypeVar(TypeVar t, Boolean skipInterface) { 2575 return visit(t.getUpperBound(), skipInterface); 2576 } 2577 } 2578 2579 private MembersClosureCache membersCache = new MembersClosureCache(); 2580 2581 public CompoundScope membersClosure(Type site, boolean skipInterface) { 2582 return membersCache.visit(site, skipInterface); 2583 } 2584 // </editor-fold> 2585 2586 2587 //where 2588 public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) { 2589 Filter<Symbol> filter = new MethodFilter(ms, site); 2590 List<MethodSymbol> candidates = List.nil(); 2591 for (Symbol s : membersClosure(site, false).getElements(filter)) { 2592 if (!site.tsym.isInterface() && !s.owner.isInterface()) { 2593 return List.of((MethodSymbol)s); 2594 } else if (!candidates.contains(s)) { 2595 candidates = candidates.prepend((MethodSymbol)s); 2596 } 2597 } 2598 return prune(candidates); 2599 } 2600 2601 public List<MethodSymbol> prune(List<MethodSymbol> methods) { 2602 ListBuffer<MethodSymbol> methodsMin = ListBuffer.lb(); 2603 for (MethodSymbol m1 : methods) { 2604 boolean isMin_m1 = true; 2605 for (MethodSymbol m2 : methods) { 2606 if (m1 == m2) continue; 2607 if (m2.owner != m1.owner && 2608 asSuper(m2.owner.type, m1.owner) != null) { 2609 isMin_m1 = false; 2610 break; 2611 } 2612 } 2613 if (isMin_m1) 2614 methodsMin.append(m1); 2615 } 2616 return methodsMin.toList(); 2617 } 2618 // where 2619 private class MethodFilter implements Filter<Symbol> { 2620 2621 Symbol msym; 2622 Type site; 2623 2624 MethodFilter(Symbol msym, Type site) { 2625 this.msym = msym; 2626 this.site = site; 2627 } 2628 2629 public boolean accepts(Symbol s) { 2630 return s.kind == Kinds.MTH && 2631 s.name == msym.name && 2632 s.isInheritedIn(site.tsym, Types.this) && 2633 overrideEquivalent(memberType(site, s), memberType(site, msym)); 2634 } 2635 }; 2636 // </editor-fold> 2637 2638 /** 2639 * Does t have the same arguments as s? It is assumed that both 2640 * types are (possibly polymorphic) method types. Monomorphic 2641 * method types "have the same arguments", if their argument lists 2642 * are equal. Polymorphic method types "have the same arguments", 2643 * if they have the same arguments after renaming all type 2644 * variables of one to corresponding type variables in the other, 2645 * where correspondence is by position in the type parameter list. 2646 */ 2647 public boolean hasSameArgs(Type t, Type s) { 2648 return hasSameArgs(t, s, true); 2649 } 2650 2651 public boolean hasSameArgs(Type t, Type s, boolean strict) { 2652 return hasSameArgs(t, s, strict ? hasSameArgs_strict : hasSameArgs_nonstrict); 2653 } 2654 2655 private boolean hasSameArgs(Type t, Type s, TypeRelation hasSameArgs) { 2656 return hasSameArgs.visit(t, s); 2657 } 2658 // where 2659 private class HasSameArgs extends TypeRelation { 2660 2661 boolean strict; 2662 2663 public HasSameArgs(boolean strict) { 2664 this.strict = strict; 2665 } 2666 2667 public Boolean visitType(Type t, Type s) { 2668 throw new AssertionError(); 2669 } 2670 2671 @Override 2672 public Boolean visitMethodType(MethodType t, Type s) { 2673 return s.tag == METHOD 2674 && containsTypeEquivalent(t.argtypes, s.getParameterTypes()); 2675 } 2676 2677 @Override 2678 public Boolean visitForAll(ForAll t, Type s) { 2679 if (s.tag != FORALL) 2680 return strict ? false : visitMethodType(t.asMethodType(), s); 2681 2682 ForAll forAll = (ForAll)s; 2683 return hasSameBounds(t, forAll) 2684 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars)); 2685 } 2686 2687 @Override 2688 public Boolean visitErrorType(ErrorType t, Type s) { 2689 return false; 2690 } 2691 }; 2692 2693 TypeRelation hasSameArgs_strict = new HasSameArgs(true); 2694 TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false); 2695 2696 // </editor-fold> 2697 2698 // <editor-fold defaultstate="collapsed" desc="subst"> 2699 public List<Type> subst(List<Type> ts, 2700 List<Type> from, 2701 List<Type> to) { 2702 return new Subst(from, to).subst(ts); 2703 } 2704 2705 /** 2706 * Substitute all occurrences of a type in `from' with the 2707 * corresponding type in `to' in 't'. Match lists `from' and `to' 2708 * from the right: If lists have different length, discard leading 2709 * elements of the longer list. 2710 */ 2711 public Type subst(Type t, List<Type> from, List<Type> to) { 2712 return new Subst(from, to).subst(t); 2713 } 2714 2715 private class Subst extends UnaryVisitor<Type> { 2716 List<Type> from; 2717 List<Type> to; 2718 2719 public Subst(List<Type> from, List<Type> to) { 2720 int fromLength = from.length(); 2721 int toLength = to.length(); 2722 while (fromLength > toLength) { 2723 fromLength--; 2724 from = from.tail; 2725 } 2726 while (fromLength < toLength) { 2727 toLength--; 2728 to = to.tail; 2729 } 2730 this.from = from; 2731 this.to = to; 2732 } 2733 2734 Type subst(Type t) { 2735 if (from.tail == null) 2736 return t; 2737 else 2738 return visit(t); 2739 } 2740 2741 List<Type> subst(List<Type> ts) { 2742 if (from.tail == null) 2743 return ts; 2744 boolean wild = false; 2745 if (ts.nonEmpty() && from.nonEmpty()) { 2746 Type head1 = subst(ts.head); 2747 List<Type> tail1 = subst(ts.tail); 2748 if (head1 != ts.head || tail1 != ts.tail) 2749 return tail1.prepend(head1); 2750 } 2751 return ts; 2752 } 2753 2754 public Type visitType(Type t, Void ignored) { 2755 return t; 2756 } 2757 2758 @Override 2759 public Type visitMethodType(MethodType t, Void ignored) { 2760 List<Type> argtypes = subst(t.argtypes); 2761 Type restype = subst(t.restype); 2762 List<Type> thrown = subst(t.thrown); 2763 if (argtypes == t.argtypes && 2764 restype == t.restype && 2765 thrown == t.thrown) 2766 return t; 2767 else 2768 return new MethodType(argtypes, restype, thrown, t.tsym); 2769 } 2770 2771 @Override 2772 public Type visitTypeVar(TypeVar t, Void ignored) { 2773 for (List<Type> from = this.from, to = this.to; 2774 from.nonEmpty(); 2775 from = from.tail, to = to.tail) { 2776 if (t == from.head) { 2777 return to.head.withTypeVar(t); 2778 } 2779 } 2780 return t; 2781 } 2782 2783 @Override 2784 public Type visitClassType(ClassType t, Void ignored) { 2785 if (!t.isCompound()) { 2786 List<Type> typarams = t.getTypeArguments(); 2787 List<Type> typarams1 = subst(typarams); 2788 Type outer = t.getEnclosingType(); 2789 Type outer1 = subst(outer); 2790 if (typarams1 == typarams && outer1 == outer) 2791 return t; 2792 else 2793 return new ClassType(outer1, typarams1, t.tsym); 2794 } else { 2795 Type st = subst(supertype(t)); 2796 List<Type> is = upperBounds(subst(interfaces(t))); 2797 if (st == supertype(t) && is == interfaces(t)) 2798 return t; 2799 else 2800 return makeCompoundType(is.prepend(st)); 2801 } 2802 } 2803 2804 @Override 2805 public Type visitWildcardType(WildcardType t, Void ignored) { 2806 Type bound = t.type; 2807 if (t.kind != BoundKind.UNBOUND) 2808 bound = subst(bound); 2809 if (bound == t.type) { 2810 return t; 2811 } else { 2812 if (t.isExtendsBound() && bound.isExtendsBound()) 2813 bound = upperBound(bound); 2814 return new WildcardType(bound, t.kind, syms.boundClass, t.bound); 2815 } 2816 } 2817 2818 @Override 2819 public Type visitArrayType(ArrayType t, Void ignored) { 2820 Type elemtype = subst(t.elemtype); 2821 if (elemtype == t.elemtype) 2822 return t; 2823 else 2824 return new ArrayType(upperBound(elemtype), t.tsym); 2825 } 2826 2827 @Override 2828 public Type visitForAll(ForAll t, Void ignored) { 2829 if (Type.containsAny(to, t.tvars)) { 2830 //perform alpha-renaming of free-variables in 't' 2831 //if 'to' types contain variables that are free in 't' 2832 List<Type> freevars = newInstances(t.tvars); 2833 t = new ForAll(freevars, 2834 Types.this.subst(t.qtype, t.tvars, freevars)); 2835 } 2836 List<Type> tvars1 = substBounds(t.tvars, from, to); 2837 Type qtype1 = subst(t.qtype); 2838 if (tvars1 == t.tvars && qtype1 == t.qtype) { 2839 return t; 2840 } else if (tvars1 == t.tvars) { 2841 return new ForAll(tvars1, qtype1); 2842 } else { 2843 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1)); 2844 } 2845 } 2846 2847 @Override 2848 public Type visitErrorType(ErrorType t, Void ignored) { 2849 return t; 2850 } 2851 } 2852 2853 public List<Type> substBounds(List<Type> tvars, 2854 List<Type> from, 2855 List<Type> to) { 2856 if (tvars.isEmpty()) 2857 return tvars; 2858 ListBuffer<Type> newBoundsBuf = lb(); 2859 boolean changed = false; 2860 // calculate new bounds 2861 for (Type t : tvars) { 2862 TypeVar tv = (TypeVar) t; 2863 Type bound = subst(tv.bound, from, to); 2864 if (bound != tv.bound) 2865 changed = true; 2866 newBoundsBuf.append(bound); 2867 } 2868 if (!changed) 2869 return tvars; 2870 ListBuffer<Type> newTvars = lb(); 2871 // create new type variables without bounds 2872 for (Type t : tvars) { 2873 newTvars.append(new TypeVar(t.tsym, null, syms.botType)); 2874 } 2875 // the new bounds should use the new type variables in place 2876 // of the old 2877 List<Type> newBounds = newBoundsBuf.toList(); 2878 from = tvars; 2879 to = newTvars.toList(); 2880 for (; !newBounds.isEmpty(); newBounds = newBounds.tail) { 2881 newBounds.head = subst(newBounds.head, from, to); 2882 } 2883 newBounds = newBoundsBuf.toList(); 2884 // set the bounds of new type variables to the new bounds 2885 for (Type t : newTvars.toList()) { 2886 TypeVar tv = (TypeVar) t; 2887 tv.bound = newBounds.head; 2888 newBounds = newBounds.tail; 2889 } 2890 return newTvars.toList(); 2891 } 2892 2893 public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) { 2894 Type bound1 = subst(t.bound, from, to); 2895 if (bound1 == t.bound) 2896 return t; 2897 else { 2898 // create new type variable without bounds 2899 TypeVar tv = new TypeVar(t.tsym, null, syms.botType); 2900 // the new bound should use the new type variable in place 2901 // of the old 2902 tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv)); 2903 return tv; 2904 } 2905 } 2906 // </editor-fold> 2907 2908 // <editor-fold defaultstate="collapsed" desc="hasSameBounds"> 2909 /** 2910 * Does t have the same bounds for quantified variables as s? 2911 */ 2912 boolean hasSameBounds(ForAll t, ForAll s) { 2913 List<Type> l1 = t.tvars; 2914 List<Type> l2 = s.tvars; 2915 while (l1.nonEmpty() && l2.nonEmpty() && 2916 isSameType(l1.head.getUpperBound(), 2917 subst(l2.head.getUpperBound(), 2918 s.tvars, 2919 t.tvars))) { 2920 l1 = l1.tail; 2921 l2 = l2.tail; 2922 } 2923 return l1.isEmpty() && l2.isEmpty(); 2924 } 2925 // </editor-fold> 2926 2927 // <editor-fold defaultstate="collapsed" desc="newInstances"> 2928 /** Create new vector of type variables from list of variables 2929 * changing all recursive bounds from old to new list. 2930 */ 2931 public List<Type> newInstances(List<Type> tvars) { 2932 List<Type> tvars1 = Type.map(tvars, newInstanceFun); 2933 for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) { 2934 TypeVar tv = (TypeVar) l.head; 2935 tv.bound = subst(tv.bound, tvars, tvars1); 2936 } 2937 return tvars1; 2938 } 2939 private static final Mapping newInstanceFun = new Mapping("newInstanceFun") { 2940 public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); } 2941 }; 2942 // </editor-fold> 2943 2944 public Type createMethodTypeWithParameters(Type original, List<Type> newParams) { 2945 return original.accept(methodWithParameters, newParams); 2946 } 2947 // where 2948 private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() { 2949 public Type visitType(Type t, List<Type> newParams) { 2950 throw new IllegalArgumentException("Not a method type: " + t); 2951 } 2952 public Type visitMethodType(MethodType t, List<Type> newParams) { 2953 return new MethodType(newParams, t.restype, t.thrown, t.tsym); 2954 } 2955 public Type visitForAll(ForAll t, List<Type> newParams) { 2956 return new ForAll(t.tvars, t.qtype.accept(this, newParams)); 2957 } 2958 }; 2959 2960 public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) { 2961 return original.accept(methodWithThrown, newThrown); 2962 } 2963 // where 2964 private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() { 2965 public Type visitType(Type t, List<Type> newThrown) { 2966 throw new IllegalArgumentException("Not a method type: " + t); 2967 } 2968 public Type visitMethodType(MethodType t, List<Type> newThrown) { 2969 return new MethodType(t.argtypes, t.restype, newThrown, t.tsym); 2970 } 2971 public Type visitForAll(ForAll t, List<Type> newThrown) { 2972 return new ForAll(t.tvars, t.qtype.accept(this, newThrown)); 2973 } 2974 }; 2975 2976 public Type createMethodTypeWithReturn(Type original, Type newReturn) { 2977 return original.accept(methodWithReturn, newReturn); 2978 } 2979 // where 2980 private final MapVisitor<Type> methodWithReturn = new MapVisitor<Type>() { 2981 public Type visitType(Type t, Type newReturn) { 2982 throw new IllegalArgumentException("Not a method type: " + t); 2983 } 2984 public Type visitMethodType(MethodType t, Type newReturn) { 2985 return new MethodType(t.argtypes, newReturn, t.thrown, t.tsym); 2986 } 2987 public Type visitForAll(ForAll t, Type newReturn) { 2988 return new ForAll(t.tvars, t.qtype.accept(this, newReturn)); 2989 } 2990 }; 2991 2992 // <editor-fold defaultstate="collapsed" desc="createErrorType"> 2993 public Type createErrorType(Type originalType) { 2994 return new ErrorType(originalType, syms.errSymbol); 2995 } 2996 2997 public Type createErrorType(ClassSymbol c, Type originalType) { 2998 return new ErrorType(c, originalType); 2999 } 3000 3001 public Type createErrorType(Name name, TypeSymbol container, Type originalType) { 3002 return new ErrorType(name, container, originalType); 3003 } 3004 // </editor-fold> 3005 3006 // <editor-fold defaultstate="collapsed" desc="rank"> 3007 /** 3008 * The rank of a class is the length of the longest path between 3009 * the class and java.lang.Object in the class inheritance 3010 * graph. Undefined for all but reference types. 3011 */ 3012 public int rank(Type t) { 3013 t = t.unannotatedType(); 3014 switch(t.tag) { 3015 case CLASS: { 3016 ClassType cls = (ClassType)t; 3017 if (cls.rank_field < 0) { 3018 Name fullname = cls.tsym.getQualifiedName(); 3019 if (fullname == names.java_lang_Object) 3020 cls.rank_field = 0; 3021 else { 3022 int r = rank(supertype(cls)); 3023 for (List<Type> l = interfaces(cls); 3024 l.nonEmpty(); 3025 l = l.tail) { 3026 if (rank(l.head) > r) 3027 r = rank(l.head); 3028 } 3029 cls.rank_field = r + 1; 3030 } 3031 } 3032 return cls.rank_field; 3033 } 3034 case TYPEVAR: { 3035 TypeVar tvar = (TypeVar)t; 3036 if (tvar.rank_field < 0) { 3037 int r = rank(supertype(tvar)); 3038 for (List<Type> l = interfaces(tvar); 3039 l.nonEmpty(); 3040 l = l.tail) { 3041 if (rank(l.head) > r) r = rank(l.head); 3042 } 3043 tvar.rank_field = r + 1; 3044 } 3045 return tvar.rank_field; 3046 } 3047 case ERROR: 3048 return 0; 3049 default: 3050 throw new AssertionError(); 3051 } 3052 } 3053 // </editor-fold> 3054 3055 /** 3056 * Helper method for generating a string representation of a given type 3057 * accordingly to a given locale 3058 */ 3059 public String toString(Type t, Locale locale) { 3060 return Printer.createStandardPrinter(messages).visit(t, locale); 3061 } 3062 3063 /** 3064 * Helper method for generating a string representation of a given type 3065 * accordingly to a given locale 3066 */ 3067 public String toString(Symbol t, Locale locale) { 3068 return Printer.createStandardPrinter(messages).visit(t, locale); 3069 } 3070 3071 // <editor-fold defaultstate="collapsed" desc="toString"> 3072 /** 3073 * This toString is slightly more descriptive than the one on Type. 3074 * 3075 * @deprecated Types.toString(Type t, Locale l) provides better support 3076 * for localization 3077 */ 3078 @Deprecated 3079 public String toString(Type t) { 3080 if (t.tag == FORALL) { 3081 ForAll forAll = (ForAll)t; 3082 return typaramsString(forAll.tvars) + forAll.qtype; 3083 } 3084 return "" + t; 3085 } 3086 // where 3087 private String typaramsString(List<Type> tvars) { 3088 StringBuilder s = new StringBuilder(); 3089 s.append('<'); 3090 boolean first = true; 3091 for (Type t : tvars) { 3092 if (!first) s.append(", "); 3093 first = false; 3094 appendTyparamString(((TypeVar)t), s); 3095 } 3096 s.append('>'); 3097 return s.toString(); 3098 } 3099 private void appendTyparamString(TypeVar t, StringBuilder buf) { 3100 buf.append(t); 3101 if (t.bound == null || 3102 t.bound.tsym.getQualifiedName() == names.java_lang_Object) 3103 return; 3104 buf.append(" extends "); // Java syntax; no need for i18n 3105 Type bound = t.bound; 3106 if (!bound.isCompound()) { 3107 buf.append(bound); 3108 } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) { 3109 buf.append(supertype(t)); 3110 for (Type intf : interfaces(t)) { 3111 buf.append('&'); 3112 buf.append(intf); 3113 } 3114 } else { 3115 // No superclass was given in bounds. 3116 // In this case, supertype is Object, erasure is first interface. 3117 boolean first = true; 3118 for (Type intf : interfaces(t)) { 3119 if (!first) buf.append('&'); 3120 first = false; 3121 buf.append(intf); 3122 } 3123 } 3124 } 3125 // </editor-fold> 3126 3127 // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types"> 3128 /** 3129 * A cache for closures. 3130 * 3131 * <p>A closure is a list of all the supertypes and interfaces of 3132 * a class or interface type, ordered by ClassSymbol.precedes 3133 * (that is, subclasses come first, arbitrary but fixed 3134 * otherwise). 3135 */ 3136 private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>(); 3137 3138 /** 3139 * Returns the closure of a class or interface type. 3140 */ 3141 public List<Type> closure(Type t) { 3142 List<Type> cl = closureCache.get(t); 3143 if (cl == null) { 3144 Type st = supertype(t); 3145 if (!t.isCompound()) { 3146 if (st.tag == CLASS) { 3147 cl = insert(closure(st), t); 3148 } else if (st.tag == TYPEVAR) { 3149 cl = closure(st).prepend(t); 3150 } else { 3151 cl = List.of(t); 3152 } 3153 } else { 3154 cl = closure(supertype(t)); 3155 } 3156 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) 3157 cl = union(cl, closure(l.head)); 3158 closureCache.put(t, cl); 3159 } 3160 return cl; 3161 } 3162 3163 /** 3164 * Insert a type in a closure 3165 */ 3166 public List<Type> insert(List<Type> cl, Type t) { 3167 if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) { 3168 return cl.prepend(t); 3169 } else if (cl.head.tsym.precedes(t.tsym, this)) { 3170 return insert(cl.tail, t).prepend(cl.head); 3171 } else { 3172 return cl; 3173 } 3174 } 3175 3176 /** 3177 * Form the union of two closures 3178 */ 3179 public List<Type> union(List<Type> cl1, List<Type> cl2) { 3180 if (cl1.isEmpty()) { 3181 return cl2; 3182 } else if (cl2.isEmpty()) { 3183 return cl1; 3184 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) { 3185 return union(cl1.tail, cl2).prepend(cl1.head); 3186 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { 3187 return union(cl1, cl2.tail).prepend(cl2.head); 3188 } else { 3189 return union(cl1.tail, cl2.tail).prepend(cl1.head); 3190 } 3191 } 3192 3193 /** 3194 * Intersect two closures 3195 */ 3196 public List<Type> intersect(List<Type> cl1, List<Type> cl2) { 3197 if (cl1 == cl2) 3198 return cl1; 3199 if (cl1.isEmpty() || cl2.isEmpty()) 3200 return List.nil(); 3201 if (cl1.head.tsym.precedes(cl2.head.tsym, this)) 3202 return intersect(cl1.tail, cl2); 3203 if (cl2.head.tsym.precedes(cl1.head.tsym, this)) 3204 return intersect(cl1, cl2.tail); 3205 if (isSameType(cl1.head, cl2.head)) 3206 return intersect(cl1.tail, cl2.tail).prepend(cl1.head); 3207 if (cl1.head.tsym == cl2.head.tsym && 3208 cl1.head.tag == CLASS && cl2.head.tag == CLASS) { 3209 if (cl1.head.isParameterized() && cl2.head.isParameterized()) { 3210 Type merge = merge(cl1.head,cl2.head); 3211 return intersect(cl1.tail, cl2.tail).prepend(merge); 3212 } 3213 if (cl1.head.isRaw() || cl2.head.isRaw()) 3214 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head)); 3215 } 3216 return intersect(cl1.tail, cl2.tail); 3217 } 3218 // where 3219 class TypePair { 3220 final Type t1; 3221 final Type t2; 3222 TypePair(Type t1, Type t2) { 3223 this.t1 = t1; 3224 this.t2 = t2; 3225 } 3226 @Override 3227 public int hashCode() { 3228 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2); 3229 } 3230 @Override 3231 public boolean equals(Object obj) { 3232 if (!(obj instanceof TypePair)) 3233 return false; 3234 TypePair typePair = (TypePair)obj; 3235 return isSameType(t1, typePair.t1) 3236 && isSameType(t2, typePair.t2); 3237 } 3238 } 3239 Set<TypePair> mergeCache = new HashSet<TypePair>(); 3240 private Type merge(Type c1, Type c2) { 3241 ClassType class1 = (ClassType) c1; 3242 List<Type> act1 = class1.getTypeArguments(); 3243 ClassType class2 = (ClassType) c2; 3244 List<Type> act2 = class2.getTypeArguments(); 3245 ListBuffer<Type> merged = new ListBuffer<Type>(); 3246 List<Type> typarams = class1.tsym.type.getTypeArguments(); 3247 3248 while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) { 3249 if (containsType(act1.head, act2.head)) { 3250 merged.append(act1.head); 3251 } else if (containsType(act2.head, act1.head)) { 3252 merged.append(act2.head); 3253 } else { 3254 TypePair pair = new TypePair(c1, c2); 3255 Type m; 3256 if (mergeCache.add(pair)) { 3257 m = new WildcardType(lub(upperBound(act1.head), 3258 upperBound(act2.head)), 3259 BoundKind.EXTENDS, 3260 syms.boundClass); 3261 mergeCache.remove(pair); 3262 } else { 3263 m = new WildcardType(syms.objectType, 3264 BoundKind.UNBOUND, 3265 syms.boundClass); 3266 } 3267 merged.append(m.withTypeVar(typarams.head)); 3268 } 3269 act1 = act1.tail; 3270 act2 = act2.tail; 3271 typarams = typarams.tail; 3272 } 3273 Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty()); 3274 return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym); 3275 } 3276 3277 /** 3278 * Return the minimum type of a closure, a compound type if no 3279 * unique minimum exists. 3280 */ 3281 private Type compoundMin(List<Type> cl) { 3282 if (cl.isEmpty()) return syms.objectType; 3283 List<Type> compound = closureMin(cl); 3284 if (compound.isEmpty()) 3285 return null; 3286 else if (compound.tail.isEmpty()) 3287 return compound.head; 3288 else 3289 return makeCompoundType(compound); 3290 } 3291 3292 /** 3293 * Return the minimum types of a closure, suitable for computing 3294 * compoundMin or glb. 3295 */ 3296 private List<Type> closureMin(List<Type> cl) { 3297 ListBuffer<Type> classes = lb(); 3298 ListBuffer<Type> interfaces = lb(); 3299 while (!cl.isEmpty()) { 3300 Type current = cl.head; 3301 if (current.isInterface()) 3302 interfaces.append(current); 3303 else 3304 classes.append(current); 3305 ListBuffer<Type> candidates = lb(); 3306 for (Type t : cl.tail) { 3307 if (!isSubtypeNoCapture(current, t)) 3308 candidates.append(t); 3309 } 3310 cl = candidates.toList(); 3311 } 3312 return classes.appendList(interfaces).toList(); 3313 } 3314 3315 /** 3316 * Return the least upper bound of pair of types. if the lub does 3317 * not exist return null. 3318 */ 3319 public Type lub(Type t1, Type t2) { 3320 return lub(List.of(t1, t2)); 3321 } 3322 3323 /** 3324 * Return the least upper bound (lub) of set of types. If the lub 3325 * does not exist return the type of null (bottom). 3326 */ 3327 public Type lub(List<Type> ts) { 3328 final int ARRAY_BOUND = 1; 3329 final int CLASS_BOUND = 2; 3330 int boundkind = 0; 3331 for (Type t : ts) { 3332 switch (t.tag) { 3333 case CLASS: 3334 boundkind |= CLASS_BOUND; 3335 break; 3336 case ARRAY: 3337 boundkind |= ARRAY_BOUND; 3338 break; 3339 case TYPEVAR: 3340 do { 3341 t = t.getUpperBound(); 3342 } while (t.tag == TYPEVAR); 3343 if (t.tag == ARRAY) { 3344 boundkind |= ARRAY_BOUND; 3345 } else { 3346 boundkind |= CLASS_BOUND; 3347 } 3348 break; 3349 default: 3350 if (t.isPrimitive()) 3351 return syms.errType; 3352 } 3353 } 3354 switch (boundkind) { 3355 case 0: 3356 return syms.botType; 3357 3358 case ARRAY_BOUND: 3359 // calculate lub(A[], B[]) 3360 List<Type> elements = Type.map(ts, elemTypeFun); 3361 for (Type t : elements) { 3362 if (t.isPrimitive()) { 3363 // if a primitive type is found, then return 3364 // arraySuperType unless all the types are the 3365 // same 3366 Type first = ts.head; 3367 for (Type s : ts.tail) { 3368 if (!isSameType(first, s)) { 3369 // lub(int[], B[]) is Cloneable & Serializable 3370 return arraySuperType(); 3371 } 3372 } 3373 // all the array types are the same, return one 3374 // lub(int[], int[]) is int[] 3375 return first; 3376 } 3377 } 3378 // lub(A[], B[]) is lub(A, B)[] 3379 return new ArrayType(lub(elements), syms.arrayClass); 3380 3381 case CLASS_BOUND: 3382 // calculate lub(A, B) 3383 while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR) 3384 ts = ts.tail; 3385 Assert.check(!ts.isEmpty()); 3386 //step 1 - compute erased candidate set (EC) 3387 List<Type> cl = erasedSupertypes(ts.head); 3388 for (Type t : ts.tail) { 3389 if (t.tag == CLASS || t.tag == TYPEVAR) 3390 cl = intersect(cl, erasedSupertypes(t)); 3391 } 3392 //step 2 - compute minimal erased candidate set (MEC) 3393 List<Type> mec = closureMin(cl); 3394 //step 3 - for each element G in MEC, compute lci(Inv(G)) 3395 List<Type> candidates = List.nil(); 3396 for (Type erasedSupertype : mec) { 3397 List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym)); 3398 for (Type t : ts) { 3399 lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym))); 3400 } 3401 candidates = candidates.appendList(lci); 3402 } 3403 //step 4 - let MEC be { G1, G2 ... Gn }, then we have that 3404 //lub = lci(Inv(G1)) & lci(Inv(G2)) & ... & lci(Inv(Gn)) 3405 return compoundMin(candidates); 3406 3407 default: 3408 // calculate lub(A, B[]) 3409 List<Type> classes = List.of(arraySuperType()); 3410 for (Type t : ts) { 3411 if (t.tag != ARRAY) // Filter out any arrays 3412 classes = classes.prepend(t); 3413 } 3414 // lub(A, B[]) is lub(A, arraySuperType) 3415 return lub(classes); 3416 } 3417 } 3418 // where 3419 List<Type> erasedSupertypes(Type t) { 3420 ListBuffer<Type> buf = lb(); 3421 for (Type sup : closure(t)) { 3422 if (sup.tag == TYPEVAR) { 3423 buf.append(sup); 3424 } else { 3425 buf.append(erasure(sup)); 3426 } 3427 } 3428 return buf.toList(); 3429 } 3430 3431 private Type arraySuperType = null; 3432 private Type arraySuperType() { 3433 // initialized lazily to avoid problems during compiler startup 3434 if (arraySuperType == null) { 3435 synchronized (this) { 3436 if (arraySuperType == null) { 3437 // JLS 10.8: all arrays implement Cloneable and Serializable. 3438 arraySuperType = makeCompoundType(List.of(syms.serializableType, 3439 syms.cloneableType), true); 3440 } 3441 } 3442 } 3443 return arraySuperType; 3444 } 3445 // </editor-fold> 3446 3447 // <editor-fold defaultstate="collapsed" desc="Greatest lower bound"> 3448 public Type glb(List<Type> ts) { 3449 Type t1 = ts.head; 3450 for (Type t2 : ts.tail) { 3451 if (t1.isErroneous()) 3452 return t1; 3453 t1 = glb(t1, t2); 3454 } 3455 return t1; 3456 } 3457 //where 3458 public Type glb(Type t, Type s) { 3459 if (s == null) 3460 return t; 3461 else if (t.isPrimitive() || s.isPrimitive()) 3462 return syms.errType; 3463 else if (isSubtypeNoCapture(t, s)) 3464 return t; 3465 else if (isSubtypeNoCapture(s, t)) 3466 return s; 3467 3468 List<Type> closure = union(closure(t), closure(s)); 3469 List<Type> bounds = closureMin(closure); 3470 3471 if (bounds.isEmpty()) { // length == 0 3472 return syms.objectType; 3473 } else if (bounds.tail.isEmpty()) { // length == 1 3474 return bounds.head; 3475 } else { // length > 1 3476 int classCount = 0; 3477 for (Type bound : bounds) 3478 if (!bound.isInterface()) 3479 classCount++; 3480 if (classCount > 1) 3481 return createErrorType(t); 3482 } 3483 return makeCompoundType(bounds); 3484 } 3485 // </editor-fold> 3486 3487 // <editor-fold defaultstate="collapsed" desc="hashCode"> 3488 /** 3489 * Compute a hash code on a type. 3490 */ 3491 public int hashCode(Type t) { 3492 return hashCode.visit(t); 3493 } 3494 // where 3495 private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() { 3496 3497 public Integer visitType(Type t, Void ignored) { 3498 return t.tag.ordinal(); 3499 } 3500 3501 @Override 3502 public Integer visitClassType(ClassType t, Void ignored) { 3503 int result = visit(t.getEnclosingType()); 3504 result *= 127; 3505 result += t.tsym.flatName().hashCode(); 3506 for (Type s : t.getTypeArguments()) { 3507 result *= 127; 3508 result += visit(s); 3509 } 3510 return result; 3511 } 3512 3513 @Override 3514 public Integer visitMethodType(MethodType t, Void ignored) { 3515 int h = METHOD.ordinal(); 3516 for (List<Type> thisargs = t.argtypes; 3517 thisargs.tail != null; 3518 thisargs = thisargs.tail) 3519 h = (h << 5) + visit(thisargs.head); 3520 return (h << 5) + visit(t.restype); 3521 } 3522 3523 @Override 3524 public Integer visitWildcardType(WildcardType t, Void ignored) { 3525 int result = t.kind.hashCode(); 3526 if (t.type != null) { 3527 result *= 127; 3528 result += visit(t.type); 3529 } 3530 return result; 3531 } 3532 3533 @Override 3534 public Integer visitArrayType(ArrayType t, Void ignored) { 3535 return visit(t.elemtype) + 12; 3536 } 3537 3538 @Override 3539 public Integer visitTypeVar(TypeVar t, Void ignored) { 3540 return System.identityHashCode(t.tsym); 3541 } 3542 3543 @Override 3544 public Integer visitUndetVar(UndetVar t, Void ignored) { 3545 return System.identityHashCode(t); 3546 } 3547 3548 @Override 3549 public Integer visitErrorType(ErrorType t, Void ignored) { 3550 return 0; 3551 } 3552 }; 3553 // </editor-fold> 3554 3555 // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable"> 3556 /** 3557 * Does t have a result that is a subtype of the result type of s, 3558 * suitable for covariant returns? It is assumed that both types 3559 * are (possibly polymorphic) method types. Monomorphic method 3560 * types are handled in the obvious way. Polymorphic method types 3561 * require renaming all type variables of one to corresponding 3562 * type variables in the other, where correspondence is by 3563 * position in the type parameter list. */ 3564 public boolean resultSubtype(Type t, Type s, Warner warner) { 3565 List<Type> tvars = t.getTypeArguments(); 3566 List<Type> svars = s.getTypeArguments(); 3567 Type tres = t.getReturnType(); 3568 Type sres = subst(s.getReturnType(), svars, tvars); 3569 return covariantReturnType(tres, sres, warner); 3570 } 3571 3572 /** 3573 * Return-Type-Substitutable. 3574 * @jls section 8.4.5 3575 */ 3576 public boolean returnTypeSubstitutable(Type r1, Type r2) { 3577 if (hasSameArgs(r1, r2)) 3578 return resultSubtype(r1, r2, noWarnings); 3579 else 3580 return covariantReturnType(r1.getReturnType(), 3581 erasure(r2.getReturnType()), 3582 noWarnings); 3583 } 3584 3585 public boolean returnTypeSubstitutable(Type r1, 3586 Type r2, Type r2res, 3587 Warner warner) { 3588 if (isSameType(r1.getReturnType(), r2res)) 3589 return true; 3590 if (r1.getReturnType().isPrimitive() || r2res.isPrimitive()) 3591 return false; 3592 3593 if (hasSameArgs(r1, r2)) 3594 return covariantReturnType(r1.getReturnType(), r2res, warner); 3595 if (!allowCovariantReturns) 3596 return false; 3597 if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner)) 3598 return true; 3599 if (!isSubtype(r1.getReturnType(), erasure(r2res))) 3600 return false; 3601 warner.warn(LintCategory.UNCHECKED); 3602 return true; 3603 } 3604 3605 /** 3606 * Is t an appropriate return type in an overrider for a 3607 * method that returns s? 3608 */ 3609 public boolean covariantReturnType(Type t, Type s, Warner warner) { 3610 return 3611 isSameType(t, s) || 3612 allowCovariantReturns && 3613 !t.isPrimitive() && 3614 !s.isPrimitive() && 3615 isAssignable(t, s, warner); 3616 } 3617 // </editor-fold> 3618 3619 // <editor-fold defaultstate="collapsed" desc="Box/unbox support"> 3620 /** 3621 * Return the class that boxes the given primitive. 3622 */ 3623 public ClassSymbol boxedClass(Type t) { 3624 return reader.enterClass(syms.boxedName[t.tag.ordinal()]); 3625 } 3626 3627 /** 3628 * Return the boxed type if 't' is primitive, otherwise return 't' itself. 3629 */ 3630 public Type boxedTypeOrType(Type t) { 3631 return t.isPrimitive() ? 3632 boxedClass(t).type : 3633 t; 3634 } 3635 3636 /** 3637 * Return the primitive type corresponding to a boxed type. 3638 */ 3639 public Type unboxedType(Type t) { 3640 if (allowBoxing) { 3641 for (int i=0; i<syms.boxedName.length; i++) { 3642 Name box = syms.boxedName[i]; 3643 if (box != null && 3644 asSuper(t, reader.enterClass(box)) != null) 3645 return syms.typeOfTag[i]; 3646 } 3647 } 3648 return Type.noType; 3649 } 3650 3651 /** 3652 * Return the unboxed type if 't' is a boxed class, otherwise return 't' itself. 3653 */ 3654 public Type unboxedTypeOrType(Type t) { 3655 Type unboxedType = unboxedType(t); 3656 return unboxedType.tag == NONE ? t : unboxedType; 3657 } 3658 // </editor-fold> 3659 3660 // <editor-fold defaultstate="collapsed" desc="Capture conversion"> 3661 /* 3662 * JLS 5.1.10 Capture Conversion: 3663 * 3664 * Let G name a generic type declaration with n formal type 3665 * parameters A1 ... An with corresponding bounds U1 ... Un. There 3666 * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>, 3667 * where, for 1 <= i <= n: 3668 * 3669 * + If Ti is a wildcard type argument (4.5.1) of the form ? then 3670 * Si is a fresh type variable whose upper bound is 3671 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null 3672 * type. 3673 * 3674 * + If Ti is a wildcard type argument of the form ? extends Bi, 3675 * then Si is a fresh type variable whose upper bound is 3676 * glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is 3677 * the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is 3678 * a compile-time error if for any two classes (not interfaces) 3679 * Vi and Vj,Vi is not a subclass of Vj or vice versa. 3680 * 3681 * + If Ti is a wildcard type argument of the form ? super Bi, 3682 * then Si is a fresh type variable whose upper bound is 3683 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi. 3684 * 3685 * + Otherwise, Si = Ti. 3686 * 3687 * Capture conversion on any type other than a parameterized type 3688 * (4.5) acts as an identity conversion (5.1.1). Capture 3689 * conversions never require a special action at run time and 3690 * therefore never throw an exception at run time. 3691 * 3692 * Capture conversion is not applied recursively. 3693 */ 3694 /** 3695 * Capture conversion as specified by the JLS. 3696 */ 3697 3698 public List<Type> capture(List<Type> ts) { 3699 List<Type> buf = List.nil(); 3700 for (Type t : ts) { 3701 buf = buf.prepend(capture(t)); 3702 } 3703 return buf.reverse(); 3704 } 3705 public Type capture(Type t) { 3706 if (t.tag != CLASS) 3707 return t; 3708 if (t.getEnclosingType() != Type.noType) { 3709 Type capturedEncl = capture(t.getEnclosingType()); 3710 if (capturedEncl != t.getEnclosingType()) { 3711 Type type1 = memberType(capturedEncl, t.tsym); 3712 t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments()); 3713 } 3714 } 3715 t = t.unannotatedType(); 3716 ClassType cls = (ClassType)t; 3717 if (cls.isRaw() || !cls.isParameterized()) 3718 return cls; 3719 3720 ClassType G = (ClassType)cls.asElement().asType(); 3721 List<Type> A = G.getTypeArguments(); 3722 List<Type> T = cls.getTypeArguments(); 3723 List<Type> S = freshTypeVariables(T); 3724 3725 List<Type> currentA = A; 3726 List<Type> currentT = T; 3727 List<Type> currentS = S; 3728 boolean captured = false; 3729 while (!currentA.isEmpty() && 3730 !currentT.isEmpty() && 3731 !currentS.isEmpty()) { 3732 if (currentS.head != currentT.head) { 3733 captured = true; 3734 WildcardType Ti = (WildcardType)currentT.head; 3735 Type Ui = currentA.head.getUpperBound(); 3736 CapturedType Si = (CapturedType)currentS.head; 3737 if (Ui == null) 3738 Ui = syms.objectType; 3739 switch (Ti.kind) { 3740 case UNBOUND: 3741 Si.bound = subst(Ui, A, S); 3742 Si.lower = syms.botType; 3743 break; 3744 case EXTENDS: 3745 Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S)); 3746 Si.lower = syms.botType; 3747 break; 3748 case SUPER: 3749 Si.bound = subst(Ui, A, S); 3750 Si.lower = Ti.getSuperBound(); 3751 break; 3752 } 3753 if (Si.bound == Si.lower) 3754 currentS.head = Si.bound; 3755 } 3756 currentA = currentA.tail; 3757 currentT = currentT.tail; 3758 currentS = currentS.tail; 3759 } 3760 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty()) 3761 return erasure(t); // some "rare" type involved 3762 3763 if (captured) 3764 return new ClassType(cls.getEnclosingType(), S, cls.tsym); 3765 else 3766 return t; 3767 } 3768 // where 3769 public List<Type> freshTypeVariables(List<Type> types) { 3770 ListBuffer<Type> result = lb(); 3771 for (Type t : types) { 3772 if (t.tag == WILDCARD) { 3773 Type bound = ((WildcardType)t).getExtendsBound(); 3774 if (bound == null) 3775 bound = syms.objectType; 3776 result.append(new CapturedType(capturedName, 3777 syms.noSymbol, 3778 bound, 3779 syms.botType, 3780 (WildcardType)t)); 3781 } else { 3782 result.append(t); 3783 } 3784 } 3785 return result.toList(); 3786 } 3787 // </editor-fold> 3788 3789 // <editor-fold defaultstate="collapsed" desc="Internal utility methods"> 3790 private List<Type> upperBounds(List<Type> ss) { 3791 if (ss.isEmpty()) return ss; 3792 Type head = upperBound(ss.head); 3793 List<Type> tail = upperBounds(ss.tail); 3794 if (head != ss.head || tail != ss.tail) 3795 return tail.prepend(head); 3796 else 3797 return ss; 3798 } 3799 3800 private boolean sideCast(Type from, Type to, Warner warn) { 3801 // We are casting from type $from$ to type $to$, which are 3802 // non-final unrelated types. This method 3803 // tries to reject a cast by transferring type parameters 3804 // from $to$ to $from$ by common superinterfaces. 3805 boolean reverse = false; 3806 Type target = to; 3807 if ((to.tsym.flags() & INTERFACE) == 0) { 3808 Assert.check((from.tsym.flags() & INTERFACE) != 0); 3809 reverse = true; 3810 to = from; 3811 from = target; 3812 } 3813 List<Type> commonSupers = superClosure(to, erasure(from)); 3814 boolean giveWarning = commonSupers.isEmpty(); 3815 // The arguments to the supers could be unified here to 3816 // get a more accurate analysis 3817 while (commonSupers.nonEmpty()) { 3818 Type t1 = asSuper(from, commonSupers.head.tsym); 3819 Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym); 3820 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) 3821 return false; 3822 giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)); 3823 commonSupers = commonSupers.tail; 3824 } 3825 if (giveWarning && !isReifiable(reverse ? from : to)) 3826 warn.warn(LintCategory.UNCHECKED); 3827 if (!allowCovariantReturns) 3828 // reject if there is a common method signature with 3829 // incompatible return types. 3830 chk.checkCompatibleAbstracts(warn.pos(), from, to); 3831 return true; 3832 } 3833 3834 private boolean sideCastFinal(Type from, Type to, Warner warn) { 3835 // We are casting from type $from$ to type $to$, which are 3836 // unrelated types one of which is final and the other of 3837 // which is an interface. This method 3838 // tries to reject a cast by transferring type parameters 3839 // from the final class to the interface. 3840 boolean reverse = false; 3841 Type target = to; 3842 if ((to.tsym.flags() & INTERFACE) == 0) { 3843 Assert.check((from.tsym.flags() & INTERFACE) != 0); 3844 reverse = true; 3845 to = from; 3846 from = target; 3847 } 3848 Assert.check((from.tsym.flags() & FINAL) != 0); 3849 Type t1 = asSuper(from, to.tsym); 3850 if (t1 == null) return false; 3851 Type t2 = to; 3852 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) 3853 return false; 3854 if (!allowCovariantReturns) 3855 // reject if there is a common method signature with 3856 // incompatible return types. 3857 chk.checkCompatibleAbstracts(warn.pos(), from, to); 3858 if (!isReifiable(target) && 3859 (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2))) 3860 warn.warn(LintCategory.UNCHECKED); 3861 return true; 3862 } 3863 3864 private boolean giveWarning(Type from, Type to) { 3865 List<Type> bounds = to.isCompound() ? 3866 ((IntersectionClassType)to).getComponents() : List.of(to); 3867 for (Type b : bounds) { 3868 Type subFrom = asSub(from, b.tsym); 3869 if (b.isParameterized() && 3870 (!(isUnbounded(b) || 3871 isSubtype(from, b) || 3872 ((subFrom != null) && containsType(b.allparams(), subFrom.allparams()))))) { 3873 return true; 3874 } 3875 } 3876 return false; 3877 } 3878 3879 private List<Type> superClosure(Type t, Type s) { 3880 List<Type> cl = List.nil(); 3881 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) { 3882 if (isSubtype(s, erasure(l.head))) { 3883 cl = insert(cl, l.head); 3884 } else { 3885 cl = union(cl, superClosure(l.head, s)); 3886 } 3887 } 3888 return cl; 3889 } 3890 3891 private boolean containsTypeEquivalent(Type t, Type s) { 3892 return 3893 isSameType(t, s) || // shortcut 3894 containsType(t, s) && containsType(s, t); 3895 } 3896 3897 // <editor-fold defaultstate="collapsed" desc="adapt"> 3898 /** 3899 * Adapt a type by computing a substitution which maps a source 3900 * type to a target type. 3901 * 3902 * @param source the source type 3903 * @param target the target type 3904 * @param from the type variables of the computed substitution 3905 * @param to the types of the computed substitution. 3906 */ 3907 public void adapt(Type source, 3908 Type target, 3909 ListBuffer<Type> from, 3910 ListBuffer<Type> to) throws AdaptFailure { 3911 new Adapter(from, to).adapt(source, target); 3912 } 3913 3914 class Adapter extends SimpleVisitor<Void, Type> { 3915 3916 ListBuffer<Type> from; 3917 ListBuffer<Type> to; 3918 Map<Symbol,Type> mapping; 3919 3920 Adapter(ListBuffer<Type> from, ListBuffer<Type> to) { 3921 this.from = from; 3922 this.to = to; 3923 mapping = new HashMap<Symbol,Type>(); 3924 } 3925 3926 public void adapt(Type source, Type target) throws AdaptFailure { 3927 visit(source, target); 3928 List<Type> fromList = from.toList(); 3929 List<Type> toList = to.toList(); 3930 while (!fromList.isEmpty()) { 3931 Type val = mapping.get(fromList.head.tsym); 3932 if (toList.head != val) 3933 toList.head = val; 3934 fromList = fromList.tail; 3935 toList = toList.tail; 3936 } 3937 } 3938 3939 @Override 3940 public Void visitClassType(ClassType source, Type target) throws AdaptFailure { 3941 if (target.tag == CLASS) 3942 adaptRecursive(source.allparams(), target.allparams()); 3943 return null; 3944 } 3945 3946 @Override 3947 public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure { 3948 if (target.tag == ARRAY) 3949 adaptRecursive(elemtype(source), elemtype(target)); 3950 return null; 3951 } 3952 3953 @Override 3954 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { 3955 if (source.isExtendsBound()) 3956 adaptRecursive(upperBound(source), upperBound(target)); 3957 else if (source.isSuperBound()) 3958 adaptRecursive(lowerBound(source), lowerBound(target)); 3959 return null; 3960 } 3961 3962 @Override 3963 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure { 3964 // Check to see if there is 3965 // already a mapping for $source$, in which case 3966 // the old mapping will be merged with the new 3967 Type val = mapping.get(source.tsym); 3968 if (val != null) { 3969 if (val.isSuperBound() && target.isSuperBound()) { 3970 val = isSubtype(lowerBound(val), lowerBound(target)) 3971 ? target : val; 3972 } else if (val.isExtendsBound() && target.isExtendsBound()) { 3973 val = isSubtype(upperBound(val), upperBound(target)) 3974 ? val : target; 3975 } else if (!isSameType(val, target)) { 3976 throw new AdaptFailure(); 3977 } 3978 } else { 3979 val = target; 3980 from.append(source); 3981 to.append(target); 3982 } 3983 mapping.put(source.tsym, val); 3984 return null; 3985 } 3986 3987 @Override 3988 public Void visitType(Type source, Type target) { 3989 return null; 3990 } 3991 3992 private Set<TypePair> cache = new HashSet<TypePair>(); 3993 3994 private void adaptRecursive(Type source, Type target) { 3995 TypePair pair = new TypePair(source, target); 3996 if (cache.add(pair)) { 3997 try { 3998 visit(source, target); 3999 } finally { 4000 cache.remove(pair); 4001 } 4002 } 4003 } 4004 4005 private void adaptRecursive(List<Type> source, List<Type> target) { 4006 if (source.length() == target.length()) { 4007 while (source.nonEmpty()) { 4008 adaptRecursive(source.head, target.head); 4009 source = source.tail; 4010 target = target.tail; 4011 } 4012 } 4013 } 4014 } 4015 4016 public static class AdaptFailure extends RuntimeException { 4017 static final long serialVersionUID = -7490231548272701566L; 4018 } 4019 4020 private void adaptSelf(Type t, 4021 ListBuffer<Type> from, 4022 ListBuffer<Type> to) { 4023 try { 4024 //if (t.tsym.type != t) 4025 adapt(t.tsym.type, t, from, to); 4026 } catch (AdaptFailure ex) { 4027 // Adapt should never fail calculating a mapping from 4028 // t.tsym.type to t as there can be no merge problem. 4029 throw new AssertionError(ex); 4030 } 4031 } 4032 // </editor-fold> 4033 4034 /** 4035 * Rewrite all type variables (universal quantifiers) in the given 4036 * type to wildcards (existential quantifiers). This is used to 4037 * determine if a cast is allowed. For example, if high is true 4038 * and {@code T <: Number}, then {@code List<T>} is rewritten to 4039 * {@code List<? extends Number>}. Since {@code List<Integer> <: 4040 * List<? extends Number>} a {@code List<T>} can be cast to {@code 4041 * List<Integer>} with a warning. 4042 * @param t a type 4043 * @param high if true return an upper bound; otherwise a lower 4044 * bound 4045 * @param rewriteTypeVars only rewrite captured wildcards if false; 4046 * otherwise rewrite all type variables 4047 * @return the type rewritten with wildcards (existential 4048 * quantifiers) only 4049 */ 4050 private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) { 4051 return new Rewriter(high, rewriteTypeVars).visit(t); 4052 } 4053 4054 class Rewriter extends UnaryVisitor<Type> { 4055 4056 boolean high; 4057 boolean rewriteTypeVars; 4058 4059 Rewriter(boolean high, boolean rewriteTypeVars) { 4060 this.high = high; 4061 this.rewriteTypeVars = rewriteTypeVars; 4062 } 4063 4064 @Override 4065 public Type visitClassType(ClassType t, Void s) { 4066 ListBuffer<Type> rewritten = new ListBuffer<Type>(); 4067 boolean changed = false; 4068 for (Type arg : t.allparams()) { 4069 Type bound = visit(arg); 4070 if (arg != bound) { 4071 changed = true; 4072 } 4073 rewritten.append(bound); 4074 } 4075 if (changed) 4076 return subst(t.tsym.type, 4077 t.tsym.type.allparams(), 4078 rewritten.toList()); 4079 else 4080 return t; 4081 } 4082 4083 public Type visitType(Type t, Void s) { 4084 return high ? upperBound(t) : lowerBound(t); 4085 } 4086 4087 @Override 4088 public Type visitCapturedType(CapturedType t, Void s) { 4089 Type w_bound = t.wildcard.type; 4090 Type bound = w_bound.contains(t) ? 4091 erasure(w_bound) : 4092 visit(w_bound); 4093 return rewriteAsWildcardType(visit(bound), t.wildcard.bound, t.wildcard.kind); 4094 } 4095 4096 @Override 4097 public Type visitTypeVar(TypeVar t, Void s) { 4098 if (rewriteTypeVars) { 4099 Type bound = t.bound.contains(t) ? 4100 erasure(t.bound) : 4101 visit(t.bound); 4102 return rewriteAsWildcardType(bound, t, EXTENDS); 4103 } else { 4104 return t; 4105 } 4106 } 4107 4108 @Override 4109 public Type visitWildcardType(WildcardType t, Void s) { 4110 Type bound2 = visit(t.type); 4111 return t.type == bound2 ? t : rewriteAsWildcardType(bound2, t.bound, t.kind); 4112 } 4113 4114 private Type rewriteAsWildcardType(Type bound, TypeVar formal, BoundKind bk) { 4115 switch (bk) { 4116 case EXTENDS: return high ? 4117 makeExtendsWildcard(B(bound), formal) : 4118 makeExtendsWildcard(syms.objectType, formal); 4119 case SUPER: return high ? 4120 makeSuperWildcard(syms.botType, formal) : 4121 makeSuperWildcard(B(bound), formal); 4122 case UNBOUND: return makeExtendsWildcard(syms.objectType, formal); 4123 default: 4124 Assert.error("Invalid bound kind " + bk); 4125 return null; 4126 } 4127 } 4128 4129 Type B(Type t) { 4130 while (t.tag == WILDCARD) { 4131 WildcardType w = (WildcardType)t; 4132 t = high ? 4133 w.getExtendsBound() : 4134 w.getSuperBound(); 4135 if (t == null) { 4136 t = high ? syms.objectType : syms.botType; 4137 } 4138 } 4139 return t; 4140 } 4141 } 4142 4143 4144 /** 4145 * Create a wildcard with the given upper (extends) bound; create 4146 * an unbounded wildcard if bound is Object. 4147 * 4148 * @param bound the upper bound 4149 * @param formal the formal type parameter that will be 4150 * substituted by the wildcard 4151 */ 4152 private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) { 4153 if (bound == syms.objectType) { 4154 return new WildcardType(syms.objectType, 4155 BoundKind.UNBOUND, 4156 syms.boundClass, 4157 formal); 4158 } else { 4159 return new WildcardType(bound, 4160 BoundKind.EXTENDS, 4161 syms.boundClass, 4162 formal); 4163 } 4164 } 4165 4166 /** 4167 * Create a wildcard with the given lower (super) bound; create an 4168 * unbounded wildcard if bound is bottom (type of {@code null}). 4169 * 4170 * @param bound the lower bound 4171 * @param formal the formal type parameter that will be 4172 * substituted by the wildcard 4173 */ 4174 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) { 4175 if (bound.tag == BOT) { 4176 return new WildcardType(syms.objectType, 4177 BoundKind.UNBOUND, 4178 syms.boundClass, 4179 formal); 4180 } else { 4181 return new WildcardType(bound, 4182 BoundKind.SUPER, 4183 syms.boundClass, 4184 formal); 4185 } 4186 } 4187 4188 /** 4189 * A wrapper for a type that allows use in sets. 4190 */ 4191 public static class UniqueType { 4192 public final Type type; 4193 final Types types; 4194 4195 public UniqueType(Type type, Types types) { 4196 this.type = type; 4197 this.types = types; 4198 } 4199 4200 public int hashCode() { 4201 return types.hashCode(type); 4202 } 4203 4204 public boolean equals(Object obj) { 4205 return (obj instanceof UniqueType) && 4206 types.isSameType(type, ((UniqueType)obj).type); 4207 } 4208 4209 public String toString() { 4210 return type.toString(); 4211 } 4212 4213 } 4214 // </editor-fold> 4215 4216 // <editor-fold defaultstate="collapsed" desc="Visitors"> 4217 /** 4218 * A default visitor for types. All visitor methods except 4219 * visitType are implemented by delegating to visitType. Concrete 4220 * subclasses must provide an implementation of visitType and can 4221 * override other methods as needed. 4222 * 4223 * @param <R> the return type of the operation implemented by this 4224 * visitor; use Void if no return type is needed. 4225 * @param <S> the type of the second argument (the first being the 4226 * type itself) of the operation implemented by this visitor; use 4227 * Void if a second argument is not needed. 4228 */ 4229 public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> { 4230 final public R visit(Type t, S s) { return t.accept(this, s); } 4231 public R visitClassType(ClassType t, S s) { return visitType(t, s); } 4232 public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); } 4233 public R visitArrayType(ArrayType t, S s) { return visitType(t, s); } 4234 public R visitMethodType(MethodType t, S s) { return visitType(t, s); } 4235 public R visitPackageType(PackageType t, S s) { return visitType(t, s); } 4236 public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); } 4237 public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); } 4238 public R visitForAll(ForAll t, S s) { return visitType(t, s); } 4239 public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); } 4240 public R visitErrorType(ErrorType t, S s) { return visitType(t, s); } 4241 // Pretend annotations don't exist 4242 public R visitAnnotatedType(AnnotatedType t, S s) { return visit(t.underlyingType, s); } 4243 } 4244 4245 /** 4246 * A default visitor for symbols. All visitor methods except 4247 * visitSymbol are implemented by delegating to visitSymbol. Concrete 4248 * subclasses must provide an implementation of visitSymbol and can 4249 * override other methods as needed. 4250 * 4251 * @param <R> the return type of the operation implemented by this 4252 * visitor; use Void if no return type is needed. 4253 * @param <S> the type of the second argument (the first being the 4254 * symbol itself) of the operation implemented by this visitor; use 4255 * Void if a second argument is not needed. 4256 */ 4257 public static abstract class DefaultSymbolVisitor<R,S> implements Symbol.Visitor<R,S> { 4258 final public R visit(Symbol s, S arg) { return s.accept(this, arg); } 4259 public R visitClassSymbol(ClassSymbol s, S arg) { return visitSymbol(s, arg); } 4260 public R visitMethodSymbol(MethodSymbol s, S arg) { return visitSymbol(s, arg); } 4261 public R visitOperatorSymbol(OperatorSymbol s, S arg) { return visitSymbol(s, arg); } 4262 public R visitPackageSymbol(PackageSymbol s, S arg) { return visitSymbol(s, arg); } 4263 public R visitTypeSymbol(TypeSymbol s, S arg) { return visitSymbol(s, arg); } 4264 public R visitVarSymbol(VarSymbol s, S arg) { return visitSymbol(s, arg); } 4265 } 4266 4267 /** 4268 * A <em>simple</em> visitor for types. This visitor is simple as 4269 * captured wildcards, for-all types (generic methods), and 4270 * undetermined type variables (part of inference) are hidden. 4271 * Captured wildcards are hidden by treating them as type 4272 * variables and the rest are hidden by visiting their qtypes. 4273 * 4274 * @param <R> the return type of the operation implemented by this 4275 * visitor; use Void if no return type is needed. 4276 * @param <S> the type of the second argument (the first being the 4277 * type itself) of the operation implemented by this visitor; use 4278 * Void if a second argument is not needed. 4279 */ 4280 public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> { 4281 @Override 4282 public R visitCapturedType(CapturedType t, S s) { 4283 return visitTypeVar(t, s); 4284 } 4285 @Override 4286 public R visitForAll(ForAll t, S s) { 4287 return visit(t.qtype, s); 4288 } 4289 @Override 4290 public R visitUndetVar(UndetVar t, S s) { 4291 return visit(t.qtype, s); 4292 } 4293 } 4294 4295 /** 4296 * A plain relation on types. That is a 2-ary function on the 4297 * form Type × Type → Boolean. 4298 * <!-- In plain text: Type x Type -> Boolean --> 4299 */ 4300 public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {} 4301 4302 /** 4303 * A convenience visitor for implementing operations that only 4304 * require one argument (the type itself), that is, unary 4305 * operations. 4306 * 4307 * @param <R> the return type of the operation implemented by this 4308 * visitor; use Void if no return type is needed. 4309 */ 4310 public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> { 4311 final public R visit(Type t) { return t.accept(this, null); } 4312 } 4313 4314 /** 4315 * A visitor for implementing a mapping from types to types. The 4316 * default behavior of this class is to implement the identity 4317 * mapping (mapping a type to itself). This can be overridden in 4318 * subclasses. 4319 * 4320 * @param <S> the type of the second argument (the first being the 4321 * type itself) of this mapping; use Void if a second argument is 4322 * not needed. 4323 */ 4324 public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> { 4325 final public Type visit(Type t) { return t.accept(this, null); } 4326 public Type visitType(Type t, S s) { return t; } 4327 } 4328 // </editor-fold> 4329 4330 4331 // <editor-fold defaultstate="collapsed" desc="Annotation support"> 4332 4333 public RetentionPolicy getRetention(Attribute.Compound a) { 4334 return getRetention(a.type.tsym); 4335 } 4336 4337 public RetentionPolicy getRetention(Symbol sym) { 4338 RetentionPolicy vis = RetentionPolicy.CLASS; // the default 4339 Attribute.Compound c = sym.attribute(syms.retentionType.tsym); 4340 if (c != null) { 4341 Attribute value = c.member(names.value); 4342 if (value != null && value instanceof Attribute.Enum) { 4343 Name levelName = ((Attribute.Enum)value).value.name; 4344 if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE; 4345 else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS; 4346 else if (levelName == names.RUNTIME) vis = RetentionPolicy.RUNTIME; 4347 else ;// /* fail soft */ throw new AssertionError(levelName); 4348 } 4349 } 4350 return vis; 4351 } 4352 // </editor-fold> 4353 4354 // <editor-fold defaultstate="collapsed" desc="Signature Generation"> 4355 4356 public static abstract class SignatureGenerator { 4357 4358 private final Types types; 4359 4360 protected abstract void append(char ch); 4361 protected abstract void append(byte[] ba); 4362 protected abstract void append(Name name); 4363 protected void classReference(ClassSymbol c) { /* by default: no-op */ } 4364 4365 protected SignatureGenerator(Types types) { 4366 this.types = types; 4367 } 4368 4369 /** 4370 * Assemble signature of given type in string buffer. 4371 */ 4372 public void assembleSig(Type type) { 4373 type = type.unannotatedType(); 4374 switch (type.getTag()) { 4375 case BYTE: 4376 append('B'); 4377 break; 4378 case SHORT: 4379 append('S'); 4380 break; 4381 case CHAR: 4382 append('C'); 4383 break; 4384 case INT: 4385 append('I'); 4386 break; 4387 case LONG: 4388 append('J'); 4389 break; 4390 case FLOAT: 4391 append('F'); 4392 break; 4393 case DOUBLE: 4394 append('D'); 4395 break; 4396 case BOOLEAN: 4397 append('Z'); 4398 break; 4399 case VOID: 4400 append('V'); 4401 break; 4402 case CLASS: 4403 append('L'); 4404 assembleClassSig(type); 4405 append(';'); 4406 break; 4407 case ARRAY: 4408 ArrayType at = (ArrayType) type; 4409 append('['); 4410 assembleSig(at.elemtype); 4411 break; 4412 case METHOD: 4413 MethodType mt = (MethodType) type; 4414 append('('); 4415 assembleSig(mt.argtypes); 4416 append(')'); 4417 assembleSig(mt.restype); 4418 if (hasTypeVar(mt.thrown)) { 4419 for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) { 4420 append('^'); 4421 assembleSig(l.head); 4422 } 4423 } 4424 break; 4425 case WILDCARD: { 4426 Type.WildcardType ta = (Type.WildcardType) type; 4427 switch (ta.kind) { 4428 case SUPER: 4429 append('-'); 4430 assembleSig(ta.type); 4431 break; 4432 case EXTENDS: 4433 append('+'); 4434 assembleSig(ta.type); 4435 break; 4436 case UNBOUND: 4437 append('*'); 4438 break; 4439 default: 4440 throw new AssertionError(ta.kind); 4441 } 4442 break; 4443 } 4444 case TYPEVAR: 4445 append('T'); 4446 append(type.tsym.name); 4447 append(';'); 4448 break; 4449 case FORALL: 4450 Type.ForAll ft = (Type.ForAll) type; 4451 assembleParamsSig(ft.tvars); 4452 assembleSig(ft.qtype); 4453 break; 4454 default: 4455 throw new AssertionError("typeSig " + type.getTag()); 4456 } 4457 } 4458 4459 public boolean hasTypeVar(List<Type> l) { 4460 while (l.nonEmpty()) { 4461 if (l.head.hasTag(TypeTag.TYPEVAR)) { 4462 return true; 4463 } 4464 l = l.tail; 4465 } 4466 return false; 4467 } 4468 4469 public void assembleClassSig(Type type) { 4470 type = type.unannotatedType(); 4471 ClassType ct = (ClassType) type; 4472 ClassSymbol c = (ClassSymbol) ct.tsym; 4473 classReference(c); 4474 Type outer = ct.getEnclosingType(); 4475 if (outer.allparams().nonEmpty()) { 4476 boolean rawOuter = 4477 c.owner.kind == Kinds.MTH || // either a local class 4478 c.name == types.names.empty; // or anonymous 4479 assembleClassSig(rawOuter 4480 ? types.erasure(outer) 4481 : outer); 4482 append('.'); 4483 Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname)); 4484 append(rawOuter 4485 ? c.flatname.subName(c.owner.enclClass().flatname.getByteLength() + 1, c.flatname.getByteLength()) 4486 : c.name); 4487 } else { 4488 append(externalize(c.flatname)); 4489 } 4490 if (ct.getTypeArguments().nonEmpty()) { 4491 append('<'); 4492 assembleSig(ct.getTypeArguments()); 4493 append('>'); 4494 } 4495 } 4496 4497 public void assembleParamsSig(List<Type> typarams) { 4498 append('<'); 4499 for (List<Type> ts = typarams; ts.nonEmpty(); ts = ts.tail) { 4500 Type.TypeVar tvar = (Type.TypeVar) ts.head; 4501 append(tvar.tsym.name); 4502 List<Type> bounds = types.getBounds(tvar); 4503 if ((bounds.head.tsym.flags() & INTERFACE) != 0) { 4504 append(':'); 4505 } 4506 for (List<Type> l = bounds; l.nonEmpty(); l = l.tail) { 4507 append(':'); 4508 assembleSig(l.head); 4509 } 4510 } 4511 append('>'); 4512 } 4513 4514 private void assembleSig(List<Type> types) { 4515 for (List<Type> ts = types; ts.nonEmpty(); ts = ts.tail) { 4516 assembleSig(ts.head); 4517 } 4518 } 4519 } 4520 // </editor-fold> 4521 }