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