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