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