1 /* 2 * Copyright (c) 2003, 2023, 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.Annotations; 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 Check chk; 96 final Enter enter; 97 JCDiagnostic.Factory diags; 98 List<Warner> warnStack = List.nil(); 99 final Name capturedName; 100 101 public final Warner noWarnings; 102 103 // <editor-fold defaultstate="collapsed" desc="Instantiating"> 104 public static Types instance(Context context) { 105 Types instance = context.get(typesKey); 106 if (instance == null) 107 instance = new Types(context); 108 return instance; 109 } 110 111 @SuppressWarnings("this-escape") 112 protected Types(Context context) { 113 context.put(typesKey, this); 114 syms = Symtab.instance(context); 115 names = Names.instance(context); 116 Source source = Source.instance(context); 117 chk = Check.instance(context); 118 enter = Enter.instance(context); 119 capturedName = names.fromString("<captured wildcard>"); 120 messages = JavacMessages.instance(context); 121 diags = JCDiagnostic.Factory.instance(context); 122 noWarnings = new Warner(null); 123 } 124 // </editor-fold> 125 126 // <editor-fold defaultstate="collapsed" desc="bounds"> 127 /** 128 * Get a wildcard's upper bound, returning non-wildcards unchanged. 129 * @param t a type argument, either a wildcard or a type 130 */ 131 public Type wildUpperBound(Type t) { 132 if (t.hasTag(WILDCARD)) { 133 WildcardType w = (WildcardType) t; 134 if (w.isSuperBound()) 135 return w.bound == null ? syms.objectType : w.bound.getUpperBound(); 136 else 137 return wildUpperBound(w.type); 138 } 139 else return t; 140 } 141 142 /** 143 * Get a capture variable's upper bound, returning other types unchanged. 144 * @param t a type 145 */ 146 public Type cvarUpperBound(Type t) { 147 if (t.hasTag(TYPEVAR)) { 148 TypeVar v = (TypeVar) t; 149 return v.isCaptured() ? cvarUpperBound(v.getUpperBound()) : v; 150 } 151 else return t; 152 } 153 154 /** 155 * Get a wildcard's lower bound, returning non-wildcards unchanged. 156 * @param t a type argument, either a wildcard or a type 157 */ 158 public Type wildLowerBound(Type t) { 159 if (t.hasTag(WILDCARD)) { 160 WildcardType w = (WildcardType) t; 161 return w.isExtendsBound() ? syms.botType : wildLowerBound(w.type); 162 } 163 else return t; 164 } 165 166 /** 167 * Get a capture variable's lower bound, returning other types unchanged. 168 * @param t a type 169 */ 170 public Type cvarLowerBound(Type t) { 171 if (t.hasTag(TYPEVAR) && ((TypeVar) t).isCaptured()) { 172 return cvarLowerBound(t.getLowerBound()); 173 } 174 else return t; 175 } 176 177 /** 178 * Recursively skip type-variables until a class/array type is found; capture conversion is then 179 * (optionally) applied to the resulting type. This is useful for i.e. computing a site that is 180 * suitable for a method lookup. 181 */ 182 public Type skipTypeVars(Type site, boolean capture) { 183 while (site.hasTag(TYPEVAR)) { 184 site = site.getUpperBound(); 185 } 186 return capture ? capture(site) : site; 187 } 188 // </editor-fold> 189 190 // <editor-fold defaultstate="collapsed" desc="projections"> 191 192 /** 193 * A projection kind. See {@link TypeProjection} 194 */ 195 enum ProjectionKind { 196 UPWARDS() { 197 @Override 198 ProjectionKind complement() { 199 return DOWNWARDS; 200 } 201 }, 202 DOWNWARDS() { 203 @Override 204 ProjectionKind complement() { 205 return UPWARDS; 206 } 207 }; 208 209 abstract ProjectionKind complement(); 210 } 211 212 /** 213 * This visitor performs upwards and downwards projections on types. 214 * 215 * A projection is defined as a function that takes a type T, a set of type variables V and that 216 * produces another type S. 217 * 218 * An upwards projection maps a type T into a type S such that (i) T has no variables in V, 219 * and (ii) S is an upper bound of T. 220 * 221 * A downwards projection maps a type T into a type S such that (i) T has no variables in V, 222 * and (ii) S is a lower bound of T. 223 * 224 * Note that projections are only allowed to touch variables in V. Therefore, it is possible for 225 * a projection to leave its input type unchanged if it does not contain any variables in V. 226 * 227 * Moreover, note that while an upwards projection is always defined (every type as an upper bound), 228 * a downwards projection is not always defined. 229 * 230 * Examples: 231 * 232 * {@code upwards(List<#CAP1>, [#CAP1]) = List<? extends String>, where #CAP1 <: String } 233 * {@code downwards(List<#CAP2>, [#CAP2]) = List<? super String>, where #CAP2 :> String } 234 * {@code upwards(List<#CAP1>, [#CAP2]) = List<#CAP1> } 235 * {@code downwards(List<#CAP1>, [#CAP1]) = not defined } 236 */ 237 class TypeProjection extends TypeMapping<ProjectionKind> { 238 239 List<Type> vars; 240 Set<Type> seen = new HashSet<>(); 241 242 public TypeProjection(List<Type> vars) { 243 this.vars = vars; 244 } 245 246 @Override 247 public Type visitClassType(ClassType t, ProjectionKind pkind) { 248 if (t.isCompound()) { 249 List<Type> components = directSupertypes(t); 250 List<Type> components1 = components.map(c -> c.map(this, pkind)); 251 if (components == components1) return t; 252 else return makeIntersectionType(components1); 253 } else { 254 Type outer = t.getEnclosingType(); 255 Type outer1 = visit(outer, pkind); 256 List<Type> typarams = t.getTypeArguments(); 257 List<Type> formals = t.tsym.type.getTypeArguments(); 258 ListBuffer<Type> typarams1 = new ListBuffer<>(); 259 boolean changed = false; 260 for (Type actual : typarams) { 261 Type t2 = mapTypeArgument(t, formals.head.getUpperBound(), actual, pkind); 262 if (t2.hasTag(BOT)) { 263 //not defined 264 return syms.botType; 265 } 266 typarams1.add(t2); 267 changed |= actual != t2; 268 formals = formals.tail; 269 } 270 if (outer1 == outer && !changed) return t; 271 else return new ClassType(outer1, typarams1.toList(), t.tsym, t.getMetadata()) { 272 @Override 273 protected boolean needsStripping() { 274 return true; 275 } 276 }; 277 } 278 } 279 280 @Override 281 public Type visitArrayType(ArrayType t, ProjectionKind s) { 282 Type elemtype = t.elemtype; 283 Type elemtype1 = visit(elemtype, s); 284 if (elemtype1 == elemtype) { 285 return t; 286 } else if (elemtype1.hasTag(BOT)) { 287 //undefined 288 return syms.botType; 289 } else { 290 return new ArrayType(elemtype1, t.tsym, t.metadata) { 291 @Override 292 protected boolean needsStripping() { 293 return true; 294 } 295 }; 296 } 297 } 298 299 @Override 300 public Type visitTypeVar(TypeVar t, ProjectionKind pkind) { 301 if (vars.contains(t)) { 302 if (seen.add(t)) { 303 try { 304 final Type bound; 305 switch (pkind) { 306 case UPWARDS: 307 bound = t.getUpperBound(); 308 break; 309 case DOWNWARDS: 310 bound = (t.getLowerBound() == null) ? 311 syms.botType : 312 t.getLowerBound(); 313 break; 314 default: 315 Assert.error(); 316 return null; 317 } 318 return bound.map(this, pkind); 319 } finally { 320 seen.remove(t); 321 } 322 } else { 323 //cycle 324 return pkind == ProjectionKind.UPWARDS ? 325 syms.objectType : syms.botType; 326 } 327 } else { 328 return t; 329 } 330 } 331 332 private Type mapTypeArgument(Type site, Type declaredBound, Type t, ProjectionKind pkind) { 333 return t.containsAny(vars) ? 334 t.map(new TypeArgumentProjection(site, declaredBound), pkind) : 335 t; 336 } 337 338 class TypeArgumentProjection extends TypeMapping<ProjectionKind> { 339 340 Type site; 341 Type declaredBound; 342 343 TypeArgumentProjection(Type site, Type declaredBound) { 344 this.site = site; 345 this.declaredBound = declaredBound; 346 } 347 348 @Override 349 public Type visitType(Type t, ProjectionKind pkind) { 350 //type argument is some type containing restricted vars 351 if (pkind == ProjectionKind.DOWNWARDS) { 352 //not defined 353 return syms.botType; 354 } 355 Type upper = t.map(TypeProjection.this, ProjectionKind.UPWARDS); 356 Type lower = t.map(TypeProjection.this, ProjectionKind.DOWNWARDS); 357 List<Type> formals = site.tsym.type.getTypeArguments(); 358 BoundKind bk; 359 Type bound; 360 if (!isSameType(upper, syms.objectType) && 361 (declaredBound.containsAny(formals) || 362 !isSubtype(declaredBound, upper))) { 363 bound = upper; 364 bk = EXTENDS; 365 } else if (!lower.hasTag(BOT)) { 366 bound = lower; 367 bk = SUPER; 368 } else { 369 bound = syms.objectType; 370 bk = UNBOUND; 371 } 372 return makeWildcard(bound, bk); 373 } 374 375 @Override 376 public Type visitWildcardType(WildcardType wt, ProjectionKind pkind) { 377 //type argument is some wildcard whose bound contains restricted vars 378 Type bound = syms.botType; 379 BoundKind bk = wt.kind; 380 switch (wt.kind) { 381 case EXTENDS: 382 bound = wt.type.map(TypeProjection.this, pkind); 383 if (bound.hasTag(BOT)) { 384 return syms.botType; 385 } 386 break; 387 case SUPER: 388 bound = wt.type.map(TypeProjection.this, pkind.complement()); 389 if (bound.hasTag(BOT)) { 390 bound = syms.objectType; 391 bk = UNBOUND; 392 } 393 break; 394 } 395 return makeWildcard(bound, bk); 396 } 397 398 private Type makeWildcard(Type bound, BoundKind bk) { 399 return new WildcardType(bound, bk, syms.boundClass) { 400 @Override 401 protected boolean needsStripping() { 402 return true; 403 } 404 }; 405 } 406 } 407 } 408 409 /** 410 * Computes an upward projection of given type, and vars. See {@link TypeProjection}. 411 * 412 * @param t the type to be projected 413 * @param vars the set of type variables to be mapped 414 * @return the type obtained as result of the projection 415 */ 416 public Type upward(Type t, List<Type> vars) { 417 return t.map(new TypeProjection(vars), ProjectionKind.UPWARDS); 418 } 419 420 /** 421 * Computes the set of captured variables mentioned in a given type. See {@link CaptureScanner}. 422 * This routine is typically used to computed the input set of variables to be used during 423 * an upwards projection (see {@link Types#upward(Type, List)}). 424 * 425 * @param t the type where occurrences of captured variables have to be found 426 * @return the set of captured variables found in t 427 */ 428 public List<Type> captures(Type t) { 429 CaptureScanner cs = new CaptureScanner(); 430 Set<Type> captures = new HashSet<>(); 431 cs.visit(t, captures); 432 return List.from(captures); 433 } 434 435 /** 436 * This visitor scans a type recursively looking for occurrences of captured type variables. 437 */ 438 class CaptureScanner extends SimpleVisitor<Void, Set<Type>> { 439 440 @Override 441 public Void visitType(Type t, Set<Type> types) { 442 return null; 443 } 444 445 @Override 446 public Void visitClassType(ClassType t, Set<Type> seen) { 447 if (t.isCompound()) { 448 directSupertypes(t).forEach(s -> visit(s, seen)); 449 } else { 450 t.allparams().forEach(ta -> visit(ta, seen)); 451 } 452 return null; 453 } 454 455 @Override 456 public Void visitArrayType(ArrayType t, Set<Type> seen) { 457 return visit(t.elemtype, seen); 458 } 459 460 @Override 461 public Void visitWildcardType(WildcardType t, Set<Type> seen) { 462 visit(t.type, seen); 463 return null; 464 } 465 466 @Override 467 public Void visitTypeVar(TypeVar t, Set<Type> seen) { 468 if ((t.tsym.flags() & Flags.SYNTHETIC) != 0 && seen.add(t)) { 469 visit(t.getUpperBound(), seen); 470 } 471 return null; 472 } 473 474 @Override 475 public Void visitCapturedType(CapturedType t, Set<Type> seen) { 476 if (seen.add(t)) { 477 visit(t.getUpperBound(), seen); 478 visit(t.getLowerBound(), seen); 479 } 480 return null; 481 } 482 } 483 484 // </editor-fold> 485 486 // <editor-fold defaultstate="collapsed" desc="isUnbounded"> 487 /** 488 * Checks that all the arguments to a class are unbounded 489 * wildcards or something else that doesn't make any restrictions 490 * on the arguments. If a class isUnbounded, a raw super- or 491 * subclass can be cast to it without a warning. 492 * @param t a type 493 * @return true iff the given type is unbounded or raw 494 */ 495 public boolean isUnbounded(Type t) { 496 return isUnbounded.visit(t); 497 } 498 // where 499 private final UnaryVisitor<Boolean> isUnbounded = new UnaryVisitor<Boolean>() { 500 501 public Boolean visitType(Type t, Void ignored) { 502 return true; 503 } 504 505 @Override 506 public Boolean visitClassType(ClassType t, Void ignored) { 507 List<Type> parms = t.tsym.type.allparams(); 508 List<Type> args = t.allparams(); 509 while (parms.nonEmpty()) { 510 WildcardType unb = new WildcardType(syms.objectType, 511 BoundKind.UNBOUND, 512 syms.boundClass, 513 (TypeVar)parms.head); 514 if (!containsType(args.head, unb)) 515 return false; 516 parms = parms.tail; 517 args = args.tail; 518 } 519 return true; 520 } 521 }; 522 // </editor-fold> 523 524 // <editor-fold defaultstate="collapsed" desc="asSub"> 525 /** 526 * Return the least specific subtype of t that starts with symbol 527 * sym. If none exists, return null. The least specific subtype 528 * is determined as follows: 529 * 530 * <p>If there is exactly one parameterized instance of sym that is a 531 * subtype of t, that parameterized instance is returned.<br> 532 * Otherwise, if the plain type or raw type `sym' is a subtype of 533 * type t, the type `sym' itself is returned. Otherwise, null is 534 * returned. 535 */ 536 public Type asSub(Type t, Symbol sym) { 537 return asSub.visit(t, sym); 538 } 539 // where 540 private final SimpleVisitor<Type,Symbol> asSub = new SimpleVisitor<Type,Symbol>() { 541 542 public Type visitType(Type t, Symbol sym) { 543 return null; 544 } 545 546 @Override 547 public Type visitClassType(ClassType t, Symbol sym) { 548 if (t.tsym == sym) 549 return t; 550 Type base = asSuper(sym.type, t.tsym); 551 if (base == null) 552 return null; 553 ListBuffer<Type> from = new ListBuffer<>(); 554 ListBuffer<Type> to = new ListBuffer<>(); 555 try { 556 adapt(base, t, from, to); 557 } catch (AdaptFailure ex) { 558 return null; 559 } 560 Type res = subst(sym.type, from.toList(), to.toList()); 561 if (!isSubtype(res, t)) 562 return null; 563 ListBuffer<Type> openVars = new ListBuffer<>(); 564 for (List<Type> l = sym.type.allparams(); 565 l.nonEmpty(); l = l.tail) 566 if (res.contains(l.head) && !t.contains(l.head)) 567 openVars.append(l.head); 568 if (openVars.nonEmpty()) { 569 if (t.isRaw()) { 570 // The subtype of a raw type is raw 571 res = erasure(res); 572 } else { 573 // Unbound type arguments default to ? 574 List<Type> opens = openVars.toList(); 575 ListBuffer<Type> qs = new ListBuffer<>(); 576 for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) { 577 qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, 578 syms.boundClass, (TypeVar) iter.head)); 579 } 580 res = subst(res, opens, qs.toList()); 581 } 582 } 583 return res; 584 } 585 586 @Override 587 public Type visitErrorType(ErrorType t, Symbol sym) { 588 return t; 589 } 590 }; 591 // </editor-fold> 592 593 // <editor-fold defaultstate="collapsed" desc="isConvertible"> 594 /** 595 * Is t a subtype of or convertible via boxing/unboxing 596 * conversion to s? 597 */ 598 public boolean isConvertible(Type t, Type s, Warner warn) { 599 if (t.hasTag(ERROR)) { 600 return true; 601 } 602 boolean tPrimitive = t.isPrimitive(); 603 boolean sPrimitive = s.isPrimitive(); 604 if (tPrimitive == sPrimitive) { 605 return isSubtypeUnchecked(t, s, warn); 606 } 607 boolean tUndet = t.hasTag(UNDETVAR); 608 boolean sUndet = s.hasTag(UNDETVAR); 609 610 if (tUndet || sUndet) { 611 return tUndet ? 612 isSubtype(t, boxedTypeOrType(s)) : 613 isSubtype(boxedTypeOrType(t), s); 614 } 615 616 return tPrimitive 617 ? isSubtype(boxedClass(t).type, s) 618 : isSubtype(unboxedType(t), s); 619 } 620 621 /** 622 * Is t a subtype of or convertible via boxing/unboxing 623 * conversions to s? 624 */ 625 public boolean isConvertible(Type t, Type s) { 626 return isConvertible(t, s, noWarnings); 627 } 628 // </editor-fold> 629 630 // <editor-fold defaultstate="collapsed" desc="findSam"> 631 632 /** 633 * Exception used to report a function descriptor lookup failure. The exception 634 * wraps a diagnostic that can be used to generate more details error 635 * messages. 636 */ 637 public static class FunctionDescriptorLookupError extends RuntimeException { 638 private static final long serialVersionUID = 0; 639 640 transient JCDiagnostic diagnostic; 641 642 FunctionDescriptorLookupError() { 643 this.diagnostic = null; 644 } 645 646 FunctionDescriptorLookupError setMessage(JCDiagnostic diag) { 647 this.diagnostic = diag; 648 return this; 649 } 650 651 public JCDiagnostic getDiagnostic() { 652 return diagnostic; 653 } 654 655 @Override 656 public Throwable fillInStackTrace() { 657 // This is an internal exception; the stack trace is irrelevant. 658 return this; 659 } 660 } 661 662 /** 663 * A cache that keeps track of function descriptors associated with given 664 * functional interfaces. 665 */ 666 class DescriptorCache { 667 668 private WeakHashMap<TypeSymbol, Entry> _map = new WeakHashMap<>(); 669 670 class FunctionDescriptor { 671 Symbol descSym; 672 673 FunctionDescriptor(Symbol descSym) { 674 this.descSym = descSym; 675 } 676 677 public Symbol getSymbol() { 678 return descSym; 679 } 680 681 public Type getType(Type site) { 682 site = removeWildcards(site); 683 if (site.isIntersection()) { 684 IntersectionClassType ict = (IntersectionClassType)site; 685 for (Type component : ict.getExplicitComponents()) { 686 if (!chk.checkValidGenericType(component)) { 687 //if the inferred functional interface type is not well-formed, 688 //or if it's not a subtype of the original target, issue an error 689 throw failure(diags.fragment(Fragments.NoSuitableFunctionalIntfInst(site))); 690 } 691 } 692 } else { 693 if (!chk.checkValidGenericType(site)) { 694 //if the inferred functional interface type is not well-formed, 695 //or if it's not a subtype of the original target, issue an error 696 throw failure(diags.fragment(Fragments.NoSuitableFunctionalIntfInst(site))); 697 } 698 } 699 return memberType(site, descSym); 700 } 701 } 702 703 class Entry { 704 final FunctionDescriptor cachedDescRes; 705 final int prevMark; 706 707 public Entry(FunctionDescriptor cachedDescRes, 708 int prevMark) { 709 this.cachedDescRes = cachedDescRes; 710 this.prevMark = prevMark; 711 } 712 713 boolean matches(int mark) { 714 return this.prevMark == mark; 715 } 716 } 717 718 FunctionDescriptor get(TypeSymbol origin) throws FunctionDescriptorLookupError { 719 Entry e = _map.get(origin); 720 CompoundScope members = membersClosure(origin.type, false); 721 if (e == null || 722 !e.matches(members.getMark())) { 723 FunctionDescriptor descRes = findDescriptorInternal(origin, members); 724 _map.put(origin, new Entry(descRes, members.getMark())); 725 return descRes; 726 } 727 else { 728 return e.cachedDescRes; 729 } 730 } 731 732 /** 733 * Compute the function descriptor associated with a given functional interface 734 */ 735 public FunctionDescriptor findDescriptorInternal(TypeSymbol origin, 736 CompoundScope membersCache) throws FunctionDescriptorLookupError { 737 if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0 || origin.isSealed()) { 738 //t must be an interface 739 throw failure("not.a.functional.intf", origin); 740 } 741 742 final ListBuffer<Symbol> abstracts = new ListBuffer<>(); 743 for (Symbol sym : membersCache.getSymbols(new DescriptorFilter(origin))) { 744 Type mtype = memberType(origin.type, sym); 745 if (abstracts.isEmpty()) { 746 abstracts.append(sym); 747 } else if ((sym.name == abstracts.first().name && 748 overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) { 749 if (!abstracts.stream().filter(msym -> msym.owner.isSubClass(sym.enclClass(), Types.this)) 750 .map(msym -> memberType(origin.type, msym)) 751 .anyMatch(abstractMType -> isSubSignature(abstractMType, mtype))) { 752 abstracts.append(sym); 753 } 754 } else { 755 //the target method(s) should be the only abstract members of t 756 throw failure("not.a.functional.intf.1", origin, 757 diags.fragment(Fragments.IncompatibleAbstracts(Kinds.kindName(origin), origin))); 758 } 759 } 760 if (abstracts.isEmpty()) { 761 //t must define a suitable non-generic method 762 throw failure("not.a.functional.intf.1", origin, 763 diags.fragment(Fragments.NoAbstracts(Kinds.kindName(origin), origin))); 764 } else if (abstracts.size() == 1) { 765 return new FunctionDescriptor(abstracts.first()); 766 } else { // size > 1 767 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList()); 768 if (descRes == null) { 769 //we can get here if the functional interface is ill-formed 770 ListBuffer<JCDiagnostic> descriptors = new ListBuffer<>(); 771 for (Symbol desc : abstracts) { 772 String key = desc.type.getThrownTypes().nonEmpty() ? 773 "descriptor.throws" : "descriptor"; 774 descriptors.append(diags.fragment(key, desc.name, 775 desc.type.getParameterTypes(), 776 desc.type.getReturnType(), 777 desc.type.getThrownTypes())); 778 } 779 JCDiagnostic msg = 780 diags.fragment(Fragments.IncompatibleDescsInFunctionalIntf(Kinds.kindName(origin), 781 origin)); 782 JCDiagnostic.MultilineDiagnostic incompatibleDescriptors = 783 new JCDiagnostic.MultilineDiagnostic(msg, descriptors.toList()); 784 throw failure(incompatibleDescriptors); 785 } 786 return descRes; 787 } 788 } 789 790 /** 791 * Compute a synthetic type for the target descriptor given a list 792 * of override-equivalent methods in the functional interface type. 793 * The resulting method type is a method type that is override-equivalent 794 * and return-type substitutable with each method in the original list. 795 */ 796 private FunctionDescriptor mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) { 797 return mergeAbstracts(methodSyms, origin.type, false) 798 .map(bestSoFar -> new FunctionDescriptor(bestSoFar.baseSymbol()) { 799 @Override 800 public Type getType(Type origin) { 801 Type mt = memberType(origin, getSymbol()); 802 return createMethodTypeWithThrown(mt, bestSoFar.type.getThrownTypes()); 803 } 804 }).orElse(null); 805 } 806 807 FunctionDescriptorLookupError failure(String msg, Object... args) { 808 return failure(diags.fragment(msg, args)); 809 } 810 811 FunctionDescriptorLookupError failure(JCDiagnostic diag) { 812 return new FunctionDescriptorLookupError().setMessage(diag); 813 } 814 } 815 816 private DescriptorCache descCache = new DescriptorCache(); 817 818 /** 819 * Find the method descriptor associated to this class symbol - if the 820 * symbol 'origin' is not a functional interface, an exception is thrown. 821 */ 822 public Symbol findDescriptorSymbol(TypeSymbol origin) throws FunctionDescriptorLookupError { 823 return descCache.get(origin).getSymbol(); 824 } 825 826 /** 827 * Find the type of the method descriptor associated to this class symbol - 828 * if the symbol 'origin' is not a functional interface, an exception is thrown. 829 */ 830 public Type findDescriptorType(Type origin) throws FunctionDescriptorLookupError { 831 return descCache.get(origin.tsym).getType(origin); 832 } 833 834 /** 835 * Is given type a functional interface? 836 */ 837 public boolean isFunctionalInterface(TypeSymbol tsym) { 838 try { 839 findDescriptorSymbol(tsym); 840 return true; 841 } catch (FunctionDescriptorLookupError ex) { 842 return false; 843 } 844 } 845 846 public boolean isFunctionalInterface(Type site) { 847 try { 848 findDescriptorType(site); 849 return true; 850 } catch (FunctionDescriptorLookupError ex) { 851 return false; 852 } 853 } 854 855 public Type removeWildcards(Type site) { 856 if (site.getTypeArguments().stream().anyMatch(t -> t.hasTag(WILDCARD))) { 857 //compute non-wildcard parameterization - JLS 9.9 858 List<Type> actuals = site.getTypeArguments(); 859 List<Type> formals = site.tsym.type.getTypeArguments(); 860 ListBuffer<Type> targs = new ListBuffer<>(); 861 for (Type formal : formals) { 862 Type actual = actuals.head; 863 Type bound = formal.getUpperBound(); 864 if (actuals.head.hasTag(WILDCARD)) { 865 WildcardType wt = (WildcardType)actual; 866 //check that bound does not contain other formals 867 if (bound.containsAny(formals)) { 868 targs.add(wt.type); 869 } else { 870 //compute new type-argument based on declared bound and wildcard bound 871 switch (wt.kind) { 872 case UNBOUND: 873 targs.add(bound); 874 break; 875 case EXTENDS: 876 targs.add(glb(bound, wt.type)); 877 break; 878 case SUPER: 879 targs.add(wt.type); 880 break; 881 default: 882 Assert.error("Cannot get here!"); 883 } 884 } 885 } else { 886 //not a wildcard - the new type argument remains unchanged 887 targs.add(actual); 888 } 889 actuals = actuals.tail; 890 } 891 return subst(site.tsym.type, formals, targs.toList()); 892 } else { 893 return site; 894 } 895 } 896 897 /** 898 * Create a symbol for a class that implements a given functional interface 899 * and overrides its functional descriptor. This routine is used for two 900 * main purposes: (i) checking well-formedness of a functional interface; 901 * (ii) perform functional interface bridge calculation. 902 */ 903 public ClassSymbol makeFunctionalInterfaceClass(Env<AttrContext> env, Name name, Type target, long cflags) { 904 if (target == null || target == syms.unknownType) { 905 return null; 906 } 907 Symbol descSym = findDescriptorSymbol(target.tsym); 908 Type descType = findDescriptorType(target); 909 ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass()); 910 csym.completer = Completer.NULL_COMPLETER; 911 csym.members_field = WriteableScope.create(csym); 912 MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym); 913 csym.members_field.enter(instDescSym); 914 Type.ClassType ctype = new Type.ClassType(Type.noType, List.nil(), csym); 915 ctype.supertype_field = syms.objectType; 916 ctype.interfaces_field = target.isIntersection() ? 917 directSupertypes(target) : 918 List.of(target); 919 csym.type = ctype; 920 csym.sourcefile = ((ClassSymbol)csym.owner).sourcefile; 921 return csym; 922 } 923 924 /** 925 * Find the minimal set of methods that are overridden by the functional 926 * descriptor in 'origin'. All returned methods are assumed to have different 927 * erased signatures. 928 */ 929 public List<Symbol> functionalInterfaceBridges(TypeSymbol origin) { 930 Assert.check(isFunctionalInterface(origin)); 931 Symbol descSym = findDescriptorSymbol(origin); 932 CompoundScope members = membersClosure(origin.type, false); 933 ListBuffer<Symbol> overridden = new ListBuffer<>(); 934 outer: for (Symbol m2 : members.getSymbolsByName(descSym.name, bridgeFilter)) { 935 if (m2 == descSym) continue; 936 else if (descSym.overrides(m2, origin, Types.this, false)) { 937 for (Symbol m3 : overridden) { 938 if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) || 939 (m3.overrides(m2, origin, Types.this, false) && 940 (pendingBridges((ClassSymbol)origin, m3.enclClass()) || 941 (((MethodSymbol)m2).binaryImplementation((ClassSymbol)m3.owner, Types.this) != null)))) { 942 continue outer; 943 } 944 } 945 overridden.add(m2); 946 } 947 } 948 return overridden.toList(); 949 } 950 //where 951 // Use anonymous class instead of lambda expression intentionally, 952 // because the variable `names` has modifier: final. 953 private Predicate<Symbol> bridgeFilter = new Predicate<Symbol>() { 954 public boolean test(Symbol t) { 955 return t.kind == MTH && 956 t.name != names.init && 957 t.name != names.clinit && 958 (t.flags() & SYNTHETIC) == 0; 959 } 960 }; 961 962 private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) { 963 //a symbol will be completed from a classfile if (a) symbol has 964 //an associated file object with CLASS kind and (b) the symbol has 965 //not been entered 966 if (origin.classfile != null && 967 origin.classfile.getKind() == JavaFileObject.Kind.CLASS && 968 enter.getEnv(origin) == null) { 969 return false; 970 } 971 if (origin == s) { 972 return true; 973 } 974 for (Type t : interfaces(origin.type)) { 975 if (pendingBridges((ClassSymbol)t.tsym, s)) { 976 return true; 977 } 978 } 979 return false; 980 } 981 // </editor-fold> 982 983 /** 984 * Scope filter used to skip methods that should be ignored (such as methods 985 * overridden by j.l.Object) during function interface conversion interface check 986 */ 987 class DescriptorFilter implements Predicate<Symbol> { 988 989 TypeSymbol origin; 990 991 DescriptorFilter(TypeSymbol origin) { 992 this.origin = origin; 993 } 994 995 @Override 996 public boolean test(Symbol sym) { 997 return sym.kind == MTH && 998 (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT && 999 !overridesObjectMethod(origin, sym) && 1000 (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0; 1001 } 1002 } 1003 1004 // <editor-fold defaultstate="collapsed" desc="isSubtype"> 1005 /** 1006 * Is t an unchecked subtype of s? 1007 */ 1008 public boolean isSubtypeUnchecked(Type t, Type s) { 1009 return isSubtypeUnchecked(t, s, noWarnings); 1010 } 1011 /** 1012 * Is t an unchecked subtype of s? 1013 */ 1014 public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) { 1015 boolean result = isSubtypeUncheckedInternal(t, s, true, warn); 1016 if (result) { 1017 checkUnsafeVarargsConversion(t, s, warn); 1018 } 1019 return result; 1020 } 1021 //where 1022 private boolean isSubtypeUncheckedInternal(Type t, Type s, boolean capture, Warner warn) { 1023 if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) { 1024 if (((ArrayType)t).elemtype.isPrimitive()) { 1025 return isSameType(elemtype(t), elemtype(s)); 1026 } else { 1027 return isSubtypeUncheckedInternal(elemtype(t), elemtype(s), false, warn); 1028 } 1029 } else if (isSubtype(t, s, capture)) { 1030 return true; 1031 } else if (t.hasTag(TYPEVAR)) { 1032 return isSubtypeUncheckedInternal(t.getUpperBound(), s, false, warn); 1033 } else if (!s.isRaw()) { 1034 Type t2 = asSuper(t, s.tsym); 1035 if (t2 != null && t2.isRaw()) { 1036 if (isReifiable(s)) { 1037 warn.silentWarn(LintCategory.UNCHECKED); 1038 } else { 1039 warn.warn(LintCategory.UNCHECKED); 1040 } 1041 return true; 1042 } 1043 } 1044 return false; 1045 } 1046 1047 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) { 1048 if (!t.hasTag(ARRAY) || isReifiable(t)) { 1049 return; 1050 } 1051 ArrayType from = (ArrayType)t; 1052 boolean shouldWarn = false; 1053 switch (s.getTag()) { 1054 case ARRAY: 1055 ArrayType to = (ArrayType)s; 1056 shouldWarn = from.isVarargs() && 1057 !to.isVarargs() && 1058 !isReifiable(from); 1059 break; 1060 case CLASS: 1061 shouldWarn = from.isVarargs(); 1062 break; 1063 } 1064 if (shouldWarn) { 1065 warn.warn(LintCategory.VARARGS); 1066 } 1067 } 1068 1069 /** 1070 * Is t a subtype of s?<br> 1071 * (not defined for Method and ForAll types) 1072 */ 1073 public final boolean isSubtype(Type t, Type s) { 1074 return isSubtype(t, s, true); 1075 } 1076 public final boolean isSubtypeNoCapture(Type t, Type s) { 1077 return isSubtype(t, s, false); 1078 } 1079 public boolean isSubtype(Type t, Type s, boolean capture) { 1080 if (t.equalsIgnoreMetadata(s)) 1081 return true; 1082 if (s.isPartial()) 1083 return isSuperType(s, t); 1084 1085 if (s.isCompound()) { 1086 for (Type s2 : interfaces(s).prepend(supertype(s))) { 1087 if (!isSubtype(t, s2, capture)) 1088 return false; 1089 } 1090 return true; 1091 } 1092 1093 // Generally, if 's' is a lower-bounded type variable, recur on lower bound; but 1094 // for inference variables and intersections, we need to keep 's' 1095 // (see JLS 4.10.2 for intersections and 18.2.3 for inference vars) 1096 if (!t.hasTag(UNDETVAR) && !t.isCompound()) { 1097 // TODO: JDK-8039198, bounds checking sometimes passes in a wildcard as s 1098 Type lower = cvarLowerBound(wildLowerBound(s)); 1099 if (s != lower && !lower.hasTag(BOT)) 1100 return isSubtype(capture ? capture(t) : t, lower, false); 1101 } 1102 1103 return isSubtype.visit(capture ? capture(t) : t, s); 1104 } 1105 // where 1106 private TypeRelation isSubtype = new TypeRelation() 1107 { 1108 @Override 1109 public Boolean visitType(Type t, Type s) { 1110 switch (t.getTag()) { 1111 case BYTE: 1112 return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag())); 1113 case CHAR: 1114 return (!s.hasTag(SHORT) && t.getTag().isSubRangeOf(s.getTag())); 1115 case SHORT: case INT: case LONG: 1116 case FLOAT: case DOUBLE: 1117 return t.getTag().isSubRangeOf(s.getTag()); 1118 case BOOLEAN: case VOID: 1119 return t.hasTag(s.getTag()); 1120 case TYPEVAR: 1121 return isSubtypeNoCapture(t.getUpperBound(), s); 1122 case BOT: 1123 return 1124 s.hasTag(BOT) || s.hasTag(CLASS) || 1125 s.hasTag(ARRAY) || s.hasTag(TYPEVAR); 1126 case WILDCARD: //we shouldn't be here - avoids crash (see 7034495) 1127 case NONE: 1128 return false; 1129 default: 1130 throw new AssertionError("isSubtype " + t.getTag()); 1131 } 1132 } 1133 1134 private Set<TypePair> cache = new HashSet<>(); 1135 1136 private boolean containsTypeRecursive(Type t, Type s) { 1137 TypePair pair = new TypePair(t, s); 1138 if (cache.add(pair)) { 1139 try { 1140 return containsType(t.getTypeArguments(), 1141 s.getTypeArguments()); 1142 } finally { 1143 cache.remove(pair); 1144 } 1145 } else { 1146 return containsType(t.getTypeArguments(), 1147 rewriteSupers(s).getTypeArguments()); 1148 } 1149 } 1150 1151 private Type rewriteSupers(Type t) { 1152 if (!t.isParameterized()) 1153 return t; 1154 ListBuffer<Type> from = new ListBuffer<>(); 1155 ListBuffer<Type> to = new ListBuffer<>(); 1156 adaptSelf(t, from, to); 1157 if (from.isEmpty()) 1158 return t; 1159 ListBuffer<Type> rewrite = new ListBuffer<>(); 1160 boolean changed = false; 1161 for (Type orig : to.toList()) { 1162 Type s = rewriteSupers(orig); 1163 if (s.isSuperBound() && !s.isExtendsBound()) { 1164 s = new WildcardType(syms.objectType, 1165 BoundKind.UNBOUND, 1166 syms.boundClass, 1167 s.getMetadata()); 1168 changed = true; 1169 } else if (s != orig) { 1170 s = new WildcardType(wildUpperBound(s), 1171 BoundKind.EXTENDS, 1172 syms.boundClass, 1173 s.getMetadata()); 1174 changed = true; 1175 } 1176 rewrite.append(s); 1177 } 1178 if (changed) 1179 return subst(t.tsym.type, from.toList(), rewrite.toList()); 1180 else 1181 return t; 1182 } 1183 1184 @Override 1185 public Boolean visitClassType(ClassType t, Type s) { 1186 Type sup = asSuper(t, s.tsym); 1187 if (sup == null) return false; 1188 // If t is an intersection, sup might not be a class type 1189 if (!sup.hasTag(CLASS)) return isSubtypeNoCapture(sup, s); 1190 return sup.tsym == s.tsym 1191 // Check type variable containment 1192 && (!s.isParameterized() || containsTypeRecursive(s, sup)) 1193 && isSubtypeNoCapture(sup.getEnclosingType(), 1194 s.getEnclosingType()); 1195 } 1196 1197 @Override 1198 public Boolean visitArrayType(ArrayType t, Type s) { 1199 if (s.hasTag(ARRAY)) { 1200 if (t.elemtype.isPrimitive()) 1201 return isSameType(t.elemtype, elemtype(s)); 1202 else 1203 return isSubtypeNoCapture(t.elemtype, elemtype(s)); 1204 } 1205 1206 if (s.hasTag(CLASS)) { 1207 Name sname = s.tsym.getQualifiedName(); 1208 return sname == names.java_lang_Object 1209 || sname == names.java_lang_Cloneable 1210 || sname == names.java_io_Serializable; 1211 } 1212 1213 return false; 1214 } 1215 1216 @Override 1217 public Boolean visitUndetVar(UndetVar t, Type s) { 1218 //todo: test against origin needed? or replace with substitution? 1219 if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) { 1220 return true; 1221 } else if (s.hasTag(BOT)) { 1222 //if 's' is 'null' there's no instantiated type U for which 1223 //U <: s (but 'null' itself, which is not a valid type) 1224 return false; 1225 } 1226 1227 t.addBound(InferenceBound.UPPER, s, Types.this); 1228 return true; 1229 } 1230 1231 @Override 1232 public Boolean visitErrorType(ErrorType t, Type s) { 1233 return true; 1234 } 1235 }; 1236 1237 /** 1238 * Is t a subtype of every type in given list `ts'?<br> 1239 * (not defined for Method and ForAll types)<br> 1240 * Allows unchecked conversions. 1241 */ 1242 public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) { 1243 for (List<Type> l = ts; l.nonEmpty(); l = l.tail) 1244 if (!isSubtypeUnchecked(t, l.head, warn)) 1245 return false; 1246 return true; 1247 } 1248 1249 /** 1250 * Are corresponding elements of ts subtypes of ss? If lists are 1251 * of different length, return false. 1252 */ 1253 public boolean isSubtypes(List<Type> ts, List<Type> ss) { 1254 while (ts.tail != null && ss.tail != null 1255 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && 1256 isSubtype(ts.head, ss.head)) { 1257 ts = ts.tail; 1258 ss = ss.tail; 1259 } 1260 return ts.tail == null && ss.tail == null; 1261 /*inlined: ts.isEmpty() && ss.isEmpty();*/ 1262 } 1263 1264 /** 1265 * Are corresponding elements of ts subtypes of ss, allowing 1266 * unchecked conversions? If lists are of different length, 1267 * return false. 1268 **/ 1269 public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) { 1270 while (ts.tail != null && ss.tail != null 1271 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && 1272 isSubtypeUnchecked(ts.head, ss.head, warn)) { 1273 ts = ts.tail; 1274 ss = ss.tail; 1275 } 1276 return ts.tail == null && ss.tail == null; 1277 /*inlined: ts.isEmpty() && ss.isEmpty();*/ 1278 } 1279 // </editor-fold> 1280 1281 // <editor-fold defaultstate="collapsed" desc="isSuperType"> 1282 /** 1283 * Is t a supertype of s? 1284 */ 1285 public boolean isSuperType(Type t, Type s) { 1286 switch (t.getTag()) { 1287 case ERROR: 1288 return true; 1289 case UNDETVAR: { 1290 UndetVar undet = (UndetVar)t; 1291 if (t == s || 1292 undet.qtype == s || 1293 s.hasTag(ERROR) || 1294 s.hasTag(BOT)) { 1295 return true; 1296 } 1297 undet.addBound(InferenceBound.LOWER, s, this); 1298 return true; 1299 } 1300 default: 1301 return isSubtype(s, t); 1302 } 1303 } 1304 // </editor-fold> 1305 1306 // <editor-fold defaultstate="collapsed" desc="isSameType"> 1307 /** 1308 * Are corresponding elements of the lists the same type? If 1309 * lists are of different length, return false. 1310 */ 1311 public boolean isSameTypes(List<Type> ts, List<Type> ss) { 1312 while (ts.tail != null && ss.tail != null 1313 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ && 1314 isSameType(ts.head, ss.head)) { 1315 ts = ts.tail; 1316 ss = ss.tail; 1317 } 1318 return ts.tail == null && ss.tail == null; 1319 /*inlined: ts.isEmpty() && ss.isEmpty();*/ 1320 } 1321 1322 /** 1323 * A polymorphic signature method (JLS 15.12.3) is a method that 1324 * (i) is declared in the java.lang.invoke.MethodHandle/VarHandle classes; 1325 * (ii) takes a single variable arity parameter; 1326 * (iii) whose declared type is Object[]; 1327 * (iv) has any return type, Object signifying a polymorphic return type; and 1328 * (v) is native. 1329 */ 1330 public boolean isSignaturePolymorphic(MethodSymbol msym) { 1331 List<Type> argtypes = msym.type.getParameterTypes(); 1332 return (msym.flags_field & NATIVE) != 0 && 1333 (msym.owner == syms.methodHandleType.tsym || msym.owner == syms.varHandleType.tsym) && 1334 argtypes.length() == 1 && 1335 argtypes.head.hasTag(TypeTag.ARRAY) && 1336 ((ArrayType)argtypes.head).elemtype.tsym == syms.objectType.tsym; 1337 } 1338 1339 /** 1340 * Is t the same type as s? 1341 */ 1342 public boolean isSameType(Type t, Type s) { 1343 return isSameTypeVisitor.visit(t, s); 1344 } 1345 // where 1346 1347 /** 1348 * Type-equality relation - type variables are considered 1349 * equals if they share the same object identity. 1350 */ 1351 TypeRelation isSameTypeVisitor = new TypeRelation() { 1352 1353 public Boolean visitType(Type t, Type s) { 1354 if (t.equalsIgnoreMetadata(s)) 1355 return true; 1356 1357 if (s.isPartial()) 1358 return visit(s, t); 1359 1360 switch (t.getTag()) { 1361 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: 1362 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE: 1363 return t.hasTag(s.getTag()); 1364 case TYPEVAR: { 1365 if (s.hasTag(TYPEVAR)) { 1366 //type-substitution does not preserve type-var types 1367 //check that type var symbols and bounds are indeed the same 1368 return t == s; 1369 } 1370 else { 1371 //special case for s == ? super X, where upper(s) = u 1372 //check that u == t, where u has been set by Type.withTypeVar 1373 return s.isSuperBound() && 1374 !s.isExtendsBound() && 1375 visit(t, wildUpperBound(s)); 1376 } 1377 } 1378 default: 1379 throw new AssertionError("isSameType " + t.getTag()); 1380 } 1381 } 1382 1383 @Override 1384 public Boolean visitWildcardType(WildcardType t, Type s) { 1385 if (!s.hasTag(WILDCARD)) { 1386 return false; 1387 } else { 1388 WildcardType t2 = (WildcardType)s; 1389 return (t.kind == t2.kind || (t.isExtendsBound() && s.isExtendsBound())) && 1390 isSameType(t.type, t2.type); 1391 } 1392 } 1393 1394 @Override 1395 public Boolean visitClassType(ClassType t, Type s) { 1396 if (t == s) 1397 return true; 1398 1399 if (s.isPartial()) 1400 return visit(s, t); 1401 1402 if (s.isSuperBound() && !s.isExtendsBound()) 1403 return visit(t, wildUpperBound(s)) && visit(t, wildLowerBound(s)); 1404 1405 if (t.isCompound() && s.isCompound()) { 1406 if (!visit(supertype(t), supertype(s))) 1407 return false; 1408 1409 Map<Symbol,Type> tMap = new HashMap<>(); 1410 for (Type ti : interfaces(t)) { 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 isCastable(elemtype(t), elemtype(s), warnStack.head); 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().nonEmpty()) { 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.dropMetadata(Annotations.class); 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.dropMetadata(Annotations.class).getMetadata()); 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 lower-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="subsignature / override equivalence"> 2784 /** 2785 * Returns true iff the first signature is a <em>subsignature</em> 2786 * 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 subsignature of s. 2794 */ 2795 public boolean isSubSignature(Type t, Type s) { 2796 return hasSameArgs(t, s, true) || hasSameArgs(t, erasure(s), true); 2797 } 2798 2799 /** 2800 * Returns true iff these signatures are related by <em>override 2801 * equivalence</em>. This is the natural extension of 2802 * isSubSignature to an equivalence relation. 2803 * 2804 * @jls 8.4.2 Method Signature 2805 * @see #isSubSignature(Type t, Type s) 2806 * @param t a signature (possible raw, could be subjected to 2807 * erasure). 2808 * @param s a signature (possible raw, could be subjected to 2809 * erasure). 2810 * @return true if either argument is a subsignature of the other. 2811 */ 2812 public boolean overrideEquivalent(Type t, Type s) { 2813 return hasSameArgs(t, s) || 2814 hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s); 2815 } 2816 2817 public boolean overridesObjectMethod(TypeSymbol origin, Symbol msym) { 2818 for (Symbol sym : syms.objectType.tsym.members().getSymbolsByName(msym.name)) { 2819 if (msym.overrides(sym, origin, Types.this, true)) { 2820 return true; 2821 } 2822 } 2823 return false; 2824 } 2825 2826 /** 2827 * This enum defines the strategy for implementing most specific return type check 2828 * during the most specific and functional interface checks. 2829 */ 2830 public enum MostSpecificReturnCheck { 2831 /** 2832 * Return r1 is more specific than r2 if {@code r1 <: r2}. Extra care required for (i) handling 2833 * method type variables (if either method is generic) and (ii) subtyping should be replaced 2834 * by type-equivalence for primitives. This is essentially an inlined version of 2835 * {@link Types#resultSubtype(Type, Type, Warner)}, where the assignability check has been 2836 * replaced with a strict subtyping check. 2837 */ 2838 BASIC() { 2839 @Override 2840 public boolean test(Type mt1, Type mt2, Types types) { 2841 List<Type> tvars = mt1.getTypeArguments(); 2842 List<Type> svars = mt2.getTypeArguments(); 2843 Type t = mt1.getReturnType(); 2844 Type s = types.subst(mt2.getReturnType(), svars, tvars); 2845 return types.isSameType(t, s) || 2846 !t.isPrimitive() && 2847 !s.isPrimitive() && 2848 types.isSubtype(t, s); 2849 } 2850 }, 2851 /** 2852 * Return r1 is more specific than r2 if r1 is return-type-substitutable for r2. 2853 */ 2854 RTS() { 2855 @Override 2856 public boolean test(Type mt1, Type mt2, Types types) { 2857 return types.returnTypeSubstitutable(mt1, mt2); 2858 } 2859 }; 2860 2861 public abstract boolean test(Type mt1, Type mt2, Types types); 2862 } 2863 2864 /** 2865 * Merge multiple abstract methods. The preferred method is a method that is a subsignature 2866 * of all the other signatures and whose return type is more specific {@link MostSpecificReturnCheck}. 2867 * The resulting preferred method has a throws clause that is the intersection of the merged 2868 * methods' clauses. 2869 */ 2870 public Optional<Symbol> mergeAbstracts(List<Symbol> ambiguousInOrder, Type site, boolean sigCheck) { 2871 //first check for preconditions 2872 boolean shouldErase = false; 2873 List<Type> erasedParams = ambiguousInOrder.head.erasure(this).getParameterTypes(); 2874 for (Symbol s : ambiguousInOrder) { 2875 if ((s.flags() & ABSTRACT) == 0 || 2876 (sigCheck && !isSameTypes(erasedParams, s.erasure(this).getParameterTypes()))) { 2877 return Optional.empty(); 2878 } else if (s.type.hasTag(FORALL)) { 2879 shouldErase = true; 2880 } 2881 } 2882 //then merge abstracts 2883 for (MostSpecificReturnCheck mostSpecificReturnCheck : MostSpecificReturnCheck.values()) { 2884 outer: for (Symbol s : ambiguousInOrder) { 2885 Type mt = memberType(site, s); 2886 List<Type> allThrown = mt.getThrownTypes(); 2887 for (Symbol s2 : ambiguousInOrder) { 2888 if (s != s2) { 2889 Type mt2 = memberType(site, s2); 2890 if (!isSubSignature(mt, mt2) || 2891 !mostSpecificReturnCheck.test(mt, mt2, this)) { 2892 //ambiguity cannot be resolved 2893 continue outer; 2894 } else { 2895 List<Type> thrownTypes2 = mt2.getThrownTypes(); 2896 if (!mt.hasTag(FORALL) && shouldErase) { 2897 thrownTypes2 = erasure(thrownTypes2); 2898 } else if (mt.hasTag(FORALL)) { 2899 //subsignature implies that if most specific is generic, then all other 2900 //methods are too 2901 Assert.check(mt2.hasTag(FORALL)); 2902 // if both are generic methods, adjust thrown types ahead of intersection computation 2903 thrownTypes2 = subst(thrownTypes2, mt2.getTypeArguments(), mt.getTypeArguments()); 2904 } 2905 allThrown = chk.intersect(allThrown, thrownTypes2); 2906 } 2907 } 2908 } 2909 return (allThrown == mt.getThrownTypes()) ? 2910 Optional.of(s) : 2911 Optional.of(new MethodSymbol( 2912 s.flags(), 2913 s.name, 2914 createMethodTypeWithThrown(s.type, allThrown), 2915 s.owner) { 2916 @Override 2917 public Symbol baseSymbol() { 2918 return s; 2919 } 2920 }); 2921 } 2922 } 2923 return Optional.empty(); 2924 } 2925 2926 // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site"> 2927 class ImplementationCache { 2928 2929 private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>> _map = new WeakHashMap<>(); 2930 2931 class Entry { 2932 final MethodSymbol cachedImpl; 2933 final Predicate<Symbol> implFilter; 2934 final boolean checkResult; 2935 final int prevMark; 2936 2937 public Entry(MethodSymbol cachedImpl, 2938 Predicate<Symbol> scopeFilter, 2939 boolean checkResult, 2940 int prevMark) { 2941 this.cachedImpl = cachedImpl; 2942 this.implFilter = scopeFilter; 2943 this.checkResult = checkResult; 2944 this.prevMark = prevMark; 2945 } 2946 2947 boolean matches(Predicate<Symbol> scopeFilter, boolean checkResult, int mark) { 2948 return this.implFilter == scopeFilter && 2949 this.checkResult == checkResult && 2950 this.prevMark == mark; 2951 } 2952 } 2953 2954 MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Predicate<Symbol> implFilter) { 2955 SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms); 2956 Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null; 2957 if (cache == null) { 2958 cache = new HashMap<>(); 2959 _map.put(ms, new SoftReference<>(cache)); 2960 } 2961 Entry e = cache.get(origin); 2962 CompoundScope members = membersClosure(origin.type, true); 2963 if (e == null || 2964 !e.matches(implFilter, checkResult, members.getMark())) { 2965 MethodSymbol impl = implementationInternal(ms, origin, checkResult, implFilter); 2966 cache.put(origin, new Entry(impl, implFilter, checkResult, members.getMark())); 2967 return impl; 2968 } 2969 else { 2970 return e.cachedImpl; 2971 } 2972 } 2973 2974 private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Predicate<Symbol> implFilter) { 2975 for (Type t = origin.type; t.hasTag(CLASS) || t.hasTag(TYPEVAR); t = supertype(t)) { 2976 t = skipTypeVars(t, false); 2977 TypeSymbol c = t.tsym; 2978 Symbol bestSoFar = null; 2979 for (Symbol sym : c.members().getSymbolsByName(ms.name, implFilter)) { 2980 if (sym != null && sym.overrides(ms, origin, Types.this, checkResult)) { 2981 bestSoFar = sym; 2982 if ((sym.flags() & ABSTRACT) == 0) { 2983 //if concrete impl is found, exit immediately 2984 break; 2985 } 2986 } 2987 } 2988 if (bestSoFar != null) { 2989 //return either the (only) concrete implementation or the first abstract one 2990 return (MethodSymbol)bestSoFar; 2991 } 2992 } 2993 return null; 2994 } 2995 } 2996 2997 private ImplementationCache implCache = new ImplementationCache(); 2998 2999 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Predicate<Symbol> implFilter) { 3000 return implCache.get(ms, origin, checkResult, implFilter); 3001 } 3002 // </editor-fold> 3003 3004 // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site"> 3005 class MembersClosureCache extends SimpleVisitor<Scope.CompoundScope, Void> { 3006 3007 private Map<TypeSymbol, CompoundScope> _map = new HashMap<>(); 3008 3009 Set<TypeSymbol> seenTypes = new HashSet<>(); 3010 3011 class MembersScope extends CompoundScope { 3012 3013 CompoundScope scope; 3014 3015 public MembersScope(CompoundScope scope) { 3016 super(scope.owner); 3017 this.scope = scope; 3018 } 3019 3020 Predicate<Symbol> combine(Predicate<Symbol> sf) { 3021 return s -> !s.owner.isInterface() && (sf == null || sf.test(s)); 3022 } 3023 3024 @Override 3025 public Iterable<Symbol> getSymbols(Predicate<Symbol> sf, LookupKind lookupKind) { 3026 return scope.getSymbols(combine(sf), lookupKind); 3027 } 3028 3029 @Override 3030 public Iterable<Symbol> getSymbolsByName(Name name, Predicate<Symbol> sf, LookupKind lookupKind) { 3031 return scope.getSymbolsByName(name, combine(sf), lookupKind); 3032 } 3033 3034 @Override 3035 public int getMark() { 3036 return scope.getMark(); 3037 } 3038 } 3039 3040 CompoundScope nilScope; 3041 3042 /** members closure visitor methods **/ 3043 3044 public CompoundScope visitType(Type t, Void _unused) { 3045 if (nilScope == null) { 3046 nilScope = new CompoundScope(syms.noSymbol); 3047 } 3048 return nilScope; 3049 } 3050 3051 @Override 3052 public CompoundScope visitClassType(ClassType t, Void _unused) { 3053 if (!seenTypes.add(t.tsym)) { 3054 //this is possible when an interface is implemented in multiple 3055 //superclasses, or when a class hierarchy is circular - in such 3056 //cases we don't need to recurse (empty scope is returned) 3057 return new CompoundScope(t.tsym); 3058 } 3059 try { 3060 seenTypes.add(t.tsym); 3061 ClassSymbol csym = (ClassSymbol)t.tsym; 3062 CompoundScope membersClosure = _map.get(csym); 3063 if (membersClosure == null) { 3064 membersClosure = new CompoundScope(csym); 3065 for (Type i : interfaces(t)) { 3066 membersClosure.prependSubScope(visit(i, null)); 3067 } 3068 membersClosure.prependSubScope(visit(supertype(t), null)); 3069 membersClosure.prependSubScope(csym.members()); 3070 _map.put(csym, membersClosure); 3071 } 3072 return membersClosure; 3073 } 3074 finally { 3075 seenTypes.remove(t.tsym); 3076 } 3077 } 3078 3079 @Override 3080 public CompoundScope visitTypeVar(TypeVar t, Void _unused) { 3081 return visit(t.getUpperBound(), null); 3082 } 3083 } 3084 3085 private MembersClosureCache membersCache = new MembersClosureCache(); 3086 3087 public CompoundScope membersClosure(Type site, boolean skipInterface) { 3088 CompoundScope cs = membersCache.visit(site, null); 3089 Assert.checkNonNull(cs, () -> "type " + site); 3090 return skipInterface ? membersCache.new MembersScope(cs) : cs; 3091 } 3092 // </editor-fold> 3093 3094 3095 /** Return first abstract member of class `sym'. 3096 */ 3097 public MethodSymbol firstUnimplementedAbstract(ClassSymbol sym) { 3098 try { 3099 return firstUnimplementedAbstractImpl(sym, sym); 3100 } catch (CompletionFailure ex) { 3101 chk.completionError(enter.getEnv(sym).tree.pos(), ex); 3102 return null; 3103 } 3104 } 3105 //where: 3106 private MethodSymbol firstUnimplementedAbstractImpl(ClassSymbol impl, ClassSymbol c) { 3107 MethodSymbol undef = null; 3108 // Do not bother to search in classes that are not abstract, 3109 // since they cannot have abstract members. 3110 if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) { 3111 Scope s = c.members(); 3112 for (Symbol sym : s.getSymbols(NON_RECURSIVE)) { 3113 if (sym.kind == MTH && 3114 (sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) { 3115 MethodSymbol absmeth = (MethodSymbol)sym; 3116 MethodSymbol implmeth = absmeth.implementation(impl, this, true); 3117 if (implmeth == null || implmeth == absmeth) { 3118 //look for default implementations 3119 MethodSymbol prov = interfaceCandidates(impl.type, absmeth).head; 3120 if (prov != null && prov.overrides(absmeth, impl, this, true)) { 3121 implmeth = prov; 3122 } 3123 } 3124 if (implmeth == null || implmeth == absmeth) { 3125 undef = absmeth; 3126 break; 3127 } 3128 } 3129 } 3130 if (undef == null) { 3131 Type st = supertype(c.type); 3132 if (st.hasTag(CLASS)) 3133 undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)st.tsym); 3134 } 3135 for (List<Type> l = interfaces(c.type); 3136 undef == null && l.nonEmpty(); 3137 l = l.tail) { 3138 undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)l.head.tsym); 3139 } 3140 } 3141 return undef; 3142 } 3143 3144 public class CandidatesCache { 3145 public Map<Entry, List<MethodSymbol>> cache = new WeakHashMap<>(); 3146 3147 class Entry { 3148 Type site; 3149 MethodSymbol msym; 3150 3151 Entry(Type site, MethodSymbol msym) { 3152 this.site = site; 3153 this.msym = msym; 3154 } 3155 3156 @Override 3157 public boolean equals(Object obj) { 3158 return (obj instanceof Entry entry) 3159 && entry.msym == msym 3160 && isSameType(site, entry.site); 3161 } 3162 3163 @Override 3164 public int hashCode() { 3165 return Types.this.hashCode(site) & ~msym.hashCode(); 3166 } 3167 } 3168 3169 public List<MethodSymbol> get(Entry e) { 3170 return cache.get(e); 3171 } 3172 3173 public void put(Entry e, List<MethodSymbol> msymbols) { 3174 cache.put(e, msymbols); 3175 } 3176 } 3177 3178 public CandidatesCache candidatesCache = new CandidatesCache(); 3179 3180 //where 3181 public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) { 3182 CandidatesCache.Entry e = candidatesCache.new Entry(site, ms); 3183 List<MethodSymbol> candidates = candidatesCache.get(e); 3184 if (candidates == null) { 3185 Predicate<Symbol> filter = new MethodFilter(ms, site); 3186 List<MethodSymbol> candidates2 = List.nil(); 3187 for (Symbol s : membersClosure(site, false).getSymbols(filter)) { 3188 if (!site.tsym.isInterface() && !s.owner.isInterface()) { 3189 return List.of((MethodSymbol)s); 3190 } else if (!candidates2.contains(s)) { 3191 candidates2 = candidates2.prepend((MethodSymbol)s); 3192 } 3193 } 3194 candidates = prune(candidates2); 3195 candidatesCache.put(e, candidates); 3196 } 3197 return candidates; 3198 } 3199 3200 public List<MethodSymbol> prune(List<MethodSymbol> methods) { 3201 ListBuffer<MethodSymbol> methodsMin = new ListBuffer<>(); 3202 for (MethodSymbol m1 : methods) { 3203 boolean isMin_m1 = true; 3204 for (MethodSymbol m2 : methods) { 3205 if (m1 == m2) continue; 3206 if (m2.owner != m1.owner && 3207 asSuper(m2.owner.type, m1.owner) != null) { 3208 isMin_m1 = false; 3209 break; 3210 } 3211 } 3212 if (isMin_m1) 3213 methodsMin.append(m1); 3214 } 3215 return methodsMin.toList(); 3216 } 3217 // where 3218 private class MethodFilter implements Predicate<Symbol> { 3219 3220 Symbol msym; 3221 Type site; 3222 3223 MethodFilter(Symbol msym, Type site) { 3224 this.msym = msym; 3225 this.site = site; 3226 } 3227 3228 @Override 3229 public boolean test(Symbol s) { 3230 return s.kind == MTH && 3231 s.name == msym.name && 3232 (s.flags() & SYNTHETIC) == 0 && 3233 s.isInheritedIn(site.tsym, Types.this) && 3234 overrideEquivalent(memberType(site, s), memberType(site, msym)); 3235 } 3236 } 3237 // </editor-fold> 3238 3239 /** 3240 * Does t have the same arguments as s? It is assumed that both 3241 * types are (possibly polymorphic) method types. Monomorphic 3242 * method types "have the same arguments", if their argument lists 3243 * are equal. Polymorphic method types "have the same arguments", 3244 * if they have the same arguments after renaming all type 3245 * variables of one to corresponding type variables in the other, 3246 * where correspondence is by position in the type parameter list. 3247 */ 3248 public boolean hasSameArgs(Type t, Type s) { 3249 return hasSameArgs(t, s, true); 3250 } 3251 3252 public boolean hasSameArgs(Type t, Type s, boolean strict) { 3253 return hasSameArgs(t, s, strict ? hasSameArgs_strict : hasSameArgs_nonstrict); 3254 } 3255 3256 private boolean hasSameArgs(Type t, Type s, TypeRelation hasSameArgs) { 3257 return hasSameArgs.visit(t, s); 3258 } 3259 // where 3260 private class HasSameArgs extends TypeRelation { 3261 3262 boolean strict; 3263 3264 public HasSameArgs(boolean strict) { 3265 this.strict = strict; 3266 } 3267 3268 public Boolean visitType(Type t, Type s) { 3269 throw new AssertionError(); 3270 } 3271 3272 @Override 3273 public Boolean visitMethodType(MethodType t, Type s) { 3274 return s.hasTag(METHOD) 3275 && containsTypeEquivalent(t.argtypes, s.getParameterTypes()); 3276 } 3277 3278 @Override 3279 public Boolean visitForAll(ForAll t, Type s) { 3280 if (!s.hasTag(FORALL)) 3281 return strict ? false : visitMethodType(t.asMethodType(), s); 3282 3283 ForAll forAll = (ForAll)s; 3284 return hasSameBounds(t, forAll) 3285 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars)); 3286 } 3287 3288 @Override 3289 public Boolean visitErrorType(ErrorType t, Type s) { 3290 return false; 3291 } 3292 } 3293 3294 TypeRelation hasSameArgs_strict = new HasSameArgs(true); 3295 TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false); 3296 3297 // </editor-fold> 3298 3299 // <editor-fold defaultstate="collapsed" desc="subst"> 3300 public List<Type> subst(List<Type> ts, 3301 List<Type> from, 3302 List<Type> to) { 3303 return ts.map(new Subst(from, to)); 3304 } 3305 3306 /** 3307 * Substitute all occurrences of a type in `from' with the 3308 * corresponding type in `to' in 't'. Match lists `from' and `to' 3309 * from the right: If lists have different length, discard leading 3310 * elements of the longer list. 3311 */ 3312 public Type subst(Type t, List<Type> from, List<Type> to) { 3313 return t.map(new Subst(from, to)); 3314 } 3315 3316 private class Subst extends StructuralTypeMapping<Void> { 3317 List<Type> from; 3318 List<Type> to; 3319 3320 public Subst(List<Type> from, List<Type> to) { 3321 int fromLength = from.length(); 3322 int toLength = to.length(); 3323 while (fromLength > toLength) { 3324 fromLength--; 3325 from = from.tail; 3326 } 3327 while (fromLength < toLength) { 3328 toLength--; 3329 to = to.tail; 3330 } 3331 this.from = from; 3332 this.to = to; 3333 } 3334 3335 @Override 3336 public Type visitTypeVar(TypeVar t, Void ignored) { 3337 for (List<Type> from = this.from, to = this.to; 3338 from.nonEmpty(); 3339 from = from.tail, to = to.tail) { 3340 if (t.equalsIgnoreMetadata(from.head)) { 3341 return to.head.withTypeVar(t); 3342 } 3343 } 3344 return t; 3345 } 3346 3347 @Override 3348 public Type visitClassType(ClassType t, Void ignored) { 3349 if (!t.isCompound()) { 3350 return super.visitClassType(t, ignored); 3351 } else { 3352 Type st = visit(supertype(t)); 3353 List<Type> is = visit(interfaces(t), ignored); 3354 if (st == supertype(t) && is == interfaces(t)) 3355 return t; 3356 else 3357 return makeIntersectionType(is.prepend(st)); 3358 } 3359 } 3360 3361 @Override 3362 public Type visitWildcardType(WildcardType t, Void ignored) { 3363 WildcardType t2 = (WildcardType)super.visitWildcardType(t, ignored); 3364 if (t2 != t && t.isExtendsBound() && t2.type.isExtendsBound()) { 3365 t2.type = wildUpperBound(t2.type); 3366 } 3367 return t2; 3368 } 3369 3370 @Override 3371 public Type visitForAll(ForAll t, Void ignored) { 3372 if (Type.containsAny(to, t.tvars)) { 3373 //perform alpha-renaming of free-variables in 't' 3374 //if 'to' types contain variables that are free in 't' 3375 List<Type> freevars = newInstances(t.tvars); 3376 t = new ForAll(freevars, 3377 Types.this.subst(t.qtype, t.tvars, freevars)); 3378 } 3379 List<Type> tvars1 = substBounds(t.tvars, from, to); 3380 Type qtype1 = visit(t.qtype); 3381 if (tvars1 == t.tvars && qtype1 == t.qtype) { 3382 return t; 3383 } else if (tvars1 == t.tvars) { 3384 return new ForAll(tvars1, qtype1) { 3385 @Override 3386 public boolean needsStripping() { 3387 return true; 3388 } 3389 }; 3390 } else { 3391 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1)) { 3392 @Override 3393 public boolean needsStripping() { 3394 return true; 3395 } 3396 }; 3397 } 3398 } 3399 } 3400 3401 public List<Type> substBounds(List<Type> tvars, 3402 List<Type> from, 3403 List<Type> to) { 3404 if (tvars.isEmpty()) 3405 return tvars; 3406 ListBuffer<Type> newBoundsBuf = new ListBuffer<>(); 3407 boolean changed = false; 3408 // calculate new bounds 3409 for (Type t : tvars) { 3410 TypeVar tv = (TypeVar) t; 3411 Type bound = subst(tv.getUpperBound(), from, to); 3412 if (bound != tv.getUpperBound()) 3413 changed = true; 3414 newBoundsBuf.append(bound); 3415 } 3416 if (!changed) 3417 return tvars; 3418 ListBuffer<Type> newTvars = new ListBuffer<>(); 3419 // create new type variables without bounds 3420 for (Type t : tvars) { 3421 newTvars.append(new TypeVar(t.tsym, null, syms.botType, 3422 t.getMetadata())); 3423 } 3424 // the new bounds should use the new type variables in place 3425 // of the old 3426 List<Type> newBounds = newBoundsBuf.toList(); 3427 from = tvars; 3428 to = newTvars.toList(); 3429 for (; !newBounds.isEmpty(); newBounds = newBounds.tail) { 3430 newBounds.head = subst(newBounds.head, from, to); 3431 } 3432 newBounds = newBoundsBuf.toList(); 3433 // set the bounds of new type variables to the new bounds 3434 for (Type t : newTvars.toList()) { 3435 TypeVar tv = (TypeVar) t; 3436 tv.setUpperBound( newBounds.head ); 3437 newBounds = newBounds.tail; 3438 } 3439 return newTvars.toList(); 3440 } 3441 3442 public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) { 3443 Type bound1 = subst(t.getUpperBound(), from, to); 3444 if (bound1 == t.getUpperBound()) 3445 return t; 3446 else { 3447 // create new type variable without bounds 3448 TypeVar tv = new TypeVar(t.tsym, null, syms.botType, 3449 t.getMetadata()); 3450 // the new bound should use the new type variable in place 3451 // of the old 3452 tv.setUpperBound( subst(bound1, List.of(t), List.of(tv)) ); 3453 return tv; 3454 } 3455 } 3456 // </editor-fold> 3457 3458 // <editor-fold defaultstate="collapsed" desc="hasSameBounds"> 3459 /** 3460 * Does t have the same bounds for quantified variables as s? 3461 */ 3462 public boolean hasSameBounds(ForAll t, ForAll s) { 3463 List<Type> l1 = t.tvars; 3464 List<Type> l2 = s.tvars; 3465 while (l1.nonEmpty() && l2.nonEmpty() && 3466 isSameType(l1.head.getUpperBound(), 3467 subst(l2.head.getUpperBound(), 3468 s.tvars, 3469 t.tvars))) { 3470 l1 = l1.tail; 3471 l2 = l2.tail; 3472 } 3473 return l1.isEmpty() && l2.isEmpty(); 3474 } 3475 // </editor-fold> 3476 3477 // <editor-fold defaultstate="collapsed" desc="newInstances"> 3478 /** Create new vector of type variables from list of variables 3479 * changing all recursive bounds from old to new list. 3480 */ 3481 public List<Type> newInstances(List<Type> tvars) { 3482 List<Type> tvars1 = tvars.map(newInstanceFun); 3483 for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) { 3484 TypeVar tv = (TypeVar) l.head; 3485 tv.setUpperBound( subst(tv.getUpperBound(), tvars, tvars1) ); 3486 } 3487 return tvars1; 3488 } 3489 private static final TypeMapping<Void> newInstanceFun = new TypeMapping<Void>() { 3490 @Override 3491 public TypeVar visitTypeVar(TypeVar t, Void _unused) { 3492 return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getMetadata()); 3493 } 3494 }; 3495 // </editor-fold> 3496 3497 public Type createMethodTypeWithParameters(Type original, List<Type> newParams) { 3498 return original.accept(methodWithParameters, newParams); 3499 } 3500 // where 3501 private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() { 3502 public Type visitType(Type t, List<Type> newParams) { 3503 throw new IllegalArgumentException("Not a method type: " + t); 3504 } 3505 public Type visitMethodType(MethodType t, List<Type> newParams) { 3506 return new MethodType(newParams, t.restype, t.thrown, t.tsym); 3507 } 3508 public Type visitForAll(ForAll t, List<Type> newParams) { 3509 return new ForAll(t.tvars, t.qtype.accept(this, newParams)); 3510 } 3511 }; 3512 3513 public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) { 3514 return original.accept(methodWithThrown, newThrown); 3515 } 3516 // where 3517 private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() { 3518 public Type visitType(Type t, List<Type> newThrown) { 3519 throw new IllegalArgumentException("Not a method type: " + t); 3520 } 3521 public Type visitMethodType(MethodType t, List<Type> newThrown) { 3522 return new MethodType(t.argtypes, t.restype, newThrown, t.tsym); 3523 } 3524 public Type visitForAll(ForAll t, List<Type> newThrown) { 3525 return new ForAll(t.tvars, t.qtype.accept(this, newThrown)); 3526 } 3527 }; 3528 3529 public Type createMethodTypeWithReturn(Type original, Type newReturn) { 3530 return original.accept(methodWithReturn, newReturn); 3531 } 3532 // where 3533 private final MapVisitor<Type> methodWithReturn = new MapVisitor<Type>() { 3534 public Type visitType(Type t, Type newReturn) { 3535 throw new IllegalArgumentException("Not a method type: " + t); 3536 } 3537 public Type visitMethodType(MethodType t, Type newReturn) { 3538 return new MethodType(t.argtypes, newReturn, t.thrown, t.tsym) { 3539 @Override 3540 public Type baseType() { 3541 return t; 3542 } 3543 }; 3544 } 3545 public Type visitForAll(ForAll t, Type newReturn) { 3546 return new ForAll(t.tvars, t.qtype.accept(this, newReturn)) { 3547 @Override 3548 public Type baseType() { 3549 return t; 3550 } 3551 }; 3552 } 3553 }; 3554 3555 // <editor-fold defaultstate="collapsed" desc="createErrorType"> 3556 public Type createErrorType(Type originalType) { 3557 return new ErrorType(originalType, syms.errSymbol); 3558 } 3559 3560 public Type createErrorType(ClassSymbol c, Type originalType) { 3561 return new ErrorType(c, originalType); 3562 } 3563 3564 public Type createErrorType(Name name, TypeSymbol container, Type originalType) { 3565 return new ErrorType(name, container, originalType); 3566 } 3567 // </editor-fold> 3568 3569 // <editor-fold defaultstate="collapsed" desc="rank"> 3570 /** 3571 * The rank of a class is the length of the longest path between 3572 * the class and java.lang.Object in the class inheritance 3573 * graph. Undefined for all but reference types. 3574 */ 3575 public int rank(Type t) { 3576 switch(t.getTag()) { 3577 case CLASS: { 3578 ClassType cls = (ClassType)t; 3579 if (cls.rank_field < 0) { 3580 Name fullname = cls.tsym.getQualifiedName(); 3581 if (fullname == names.java_lang_Object) 3582 cls.rank_field = 0; 3583 else { 3584 int r = rank(supertype(cls)); 3585 for (List<Type> l = interfaces(cls); 3586 l.nonEmpty(); 3587 l = l.tail) { 3588 if (rank(l.head) > r) 3589 r = rank(l.head); 3590 } 3591 cls.rank_field = r + 1; 3592 } 3593 } 3594 return cls.rank_field; 3595 } 3596 case TYPEVAR: { 3597 TypeVar tvar = (TypeVar)t; 3598 if (tvar.rank_field < 0) { 3599 int r = rank(supertype(tvar)); 3600 for (List<Type> l = interfaces(tvar); 3601 l.nonEmpty(); 3602 l = l.tail) { 3603 if (rank(l.head) > r) r = rank(l.head); 3604 } 3605 tvar.rank_field = r + 1; 3606 } 3607 return tvar.rank_field; 3608 } 3609 case ERROR: 3610 case NONE: 3611 return 0; 3612 default: 3613 throw new AssertionError(); 3614 } 3615 } 3616 // </editor-fold> 3617 3618 /** 3619 * Helper method for generating a string representation of a given type 3620 * accordingly to a given locale 3621 */ 3622 public String toString(Type t, Locale locale) { 3623 return Printer.createStandardPrinter(messages).visit(t, locale); 3624 } 3625 3626 /** 3627 * Helper method for generating a string representation of a given type 3628 * accordingly to a given locale 3629 */ 3630 public String toString(Symbol t, Locale locale) { 3631 return Printer.createStandardPrinter(messages).visit(t, locale); 3632 } 3633 3634 // <editor-fold defaultstate="collapsed" desc="toString"> 3635 /** 3636 * This toString is slightly more descriptive than the one on Type. 3637 * 3638 * @deprecated Types.toString(Type t, Locale l) provides better support 3639 * for localization 3640 */ 3641 @Deprecated 3642 public String toString(Type t) { 3643 if (t.hasTag(FORALL)) { 3644 ForAll forAll = (ForAll)t; 3645 return typaramsString(forAll.tvars) + forAll.qtype; 3646 } 3647 return "" + t; 3648 } 3649 // where 3650 private String typaramsString(List<Type> tvars) { 3651 StringBuilder s = new StringBuilder(); 3652 s.append('<'); 3653 boolean first = true; 3654 for (Type t : tvars) { 3655 if (!first) s.append(", "); 3656 first = false; 3657 appendTyparamString(((TypeVar)t), s); 3658 } 3659 s.append('>'); 3660 return s.toString(); 3661 } 3662 private void appendTyparamString(TypeVar t, StringBuilder buf) { 3663 buf.append(t); 3664 if (t.getUpperBound() == null || 3665 t.getUpperBound().tsym.getQualifiedName() == names.java_lang_Object) 3666 return; 3667 buf.append(" extends "); // Java syntax; no need for i18n 3668 Type bound = t.getUpperBound(); 3669 if (!bound.isCompound()) { 3670 buf.append(bound); 3671 } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) { 3672 buf.append(supertype(t)); 3673 for (Type intf : interfaces(t)) { 3674 buf.append('&'); 3675 buf.append(intf); 3676 } 3677 } else { 3678 // No superclass was given in bounds. 3679 // In this case, supertype is Object, erasure is first interface. 3680 boolean first = true; 3681 for (Type intf : interfaces(t)) { 3682 if (!first) buf.append('&'); 3683 first = false; 3684 buf.append(intf); 3685 } 3686 } 3687 } 3688 // </editor-fold> 3689 3690 // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types"> 3691 /** 3692 * A cache for closures. 3693 * 3694 * <p>A closure is a list of all the supertypes and interfaces of 3695 * a class or interface type, ordered by ClassSymbol.precedes 3696 * (that is, subclasses come first, arbitrarily but fixed 3697 * otherwise). 3698 */ 3699 private Map<Type,List<Type>> closureCache = new HashMap<>(); 3700 3701 /** 3702 * Returns the closure of a class or interface type. 3703 */ 3704 public List<Type> closure(Type t) { 3705 List<Type> cl = closureCache.get(t); 3706 if (cl == null) { 3707 Type st = supertype(t); 3708 if (!t.isCompound()) { 3709 if (st.hasTag(CLASS)) { 3710 cl = insert(closure(st), t); 3711 } else if (st.hasTag(TYPEVAR)) { 3712 cl = closure(st).prepend(t); 3713 } else { 3714 cl = List.of(t); 3715 } 3716 } else { 3717 cl = closure(supertype(t)); 3718 } 3719 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) 3720 cl = union(cl, closure(l.head)); 3721 closureCache.put(t, cl); 3722 } 3723 return cl; 3724 } 3725 3726 /** 3727 * Collect types into a new closure (using a {@code ClosureHolder}) 3728 */ 3729 public Collector<Type, ClosureHolder, List<Type>> closureCollector(boolean minClosure, BiPredicate<Type, Type> shouldSkip) { 3730 return Collector.of(() -> new ClosureHolder(minClosure, shouldSkip), 3731 ClosureHolder::add, 3732 ClosureHolder::merge, 3733 ClosureHolder::closure); 3734 } 3735 //where 3736 class ClosureHolder { 3737 List<Type> closure; 3738 final boolean minClosure; 3739 final BiPredicate<Type, Type> shouldSkip; 3740 3741 ClosureHolder(boolean minClosure, BiPredicate<Type, Type> shouldSkip) { 3742 this.closure = List.nil(); 3743 this.minClosure = minClosure; 3744 this.shouldSkip = shouldSkip; 3745 } 3746 3747 void add(Type type) { 3748 closure = insert(closure, type, shouldSkip); 3749 } 3750 3751 ClosureHolder merge(ClosureHolder other) { 3752 closure = union(closure, other.closure, shouldSkip); 3753 return this; 3754 } 3755 3756 List<Type> closure() { 3757 return minClosure ? closureMin(closure) : closure; 3758 } 3759 } 3760 3761 BiPredicate<Type, Type> basicClosureSkip = (t1, t2) -> t1.tsym == t2.tsym; 3762 3763 /** 3764 * Insert a type in a closure 3765 */ 3766 public List<Type> insert(List<Type> cl, Type t, BiPredicate<Type, Type> shouldSkip) { 3767 if (cl.isEmpty()) { 3768 return cl.prepend(t); 3769 } else if (shouldSkip.test(t, cl.head)) { 3770 return cl; 3771 } else if (t.tsym.precedes(cl.head.tsym, this)) { 3772 return cl.prepend(t); 3773 } else { 3774 // t comes after head, or the two are unrelated 3775 return insert(cl.tail, t, shouldSkip).prepend(cl.head); 3776 } 3777 } 3778 3779 public List<Type> insert(List<Type> cl, Type t) { 3780 return insert(cl, t, basicClosureSkip); 3781 } 3782 3783 /** 3784 * Form the union of two closures 3785 */ 3786 public List<Type> union(List<Type> cl1, List<Type> cl2, BiPredicate<Type, Type> shouldSkip) { 3787 if (cl1.isEmpty()) { 3788 return cl2; 3789 } else if (cl2.isEmpty()) { 3790 return cl1; 3791 } else if (shouldSkip.test(cl1.head, cl2.head)) { 3792 return union(cl1.tail, cl2.tail, shouldSkip).prepend(cl1.head); 3793 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { 3794 return union(cl1, cl2.tail, shouldSkip).prepend(cl2.head); 3795 } else { 3796 return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head); 3797 } 3798 } 3799 3800 public List<Type> union(List<Type> cl1, List<Type> cl2) { 3801 return union(cl1, cl2, basicClosureSkip); 3802 } 3803 3804 /** 3805 * Intersect two closures 3806 */ 3807 public List<Type> intersect(List<Type> cl1, List<Type> cl2) { 3808 if (cl1 == cl2) 3809 return cl1; 3810 if (cl1.isEmpty() || cl2.isEmpty()) 3811 return List.nil(); 3812 if (cl1.head.tsym.precedes(cl2.head.tsym, this)) 3813 return intersect(cl1.tail, cl2); 3814 if (cl2.head.tsym.precedes(cl1.head.tsym, this)) 3815 return intersect(cl1, cl2.tail); 3816 if (isSameType(cl1.head, cl2.head)) 3817 return intersect(cl1.tail, cl2.tail).prepend(cl1.head); 3818 if (cl1.head.tsym == cl2.head.tsym && 3819 cl1.head.hasTag(CLASS) && cl2.head.hasTag(CLASS)) { 3820 if (cl1.head.isParameterized() && cl2.head.isParameterized()) { 3821 Type merge = merge(cl1.head,cl2.head); 3822 return intersect(cl1.tail, cl2.tail).prepend(merge); 3823 } 3824 if (cl1.head.isRaw() || cl2.head.isRaw()) 3825 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head)); 3826 } 3827 return intersect(cl1.tail, cl2.tail); 3828 } 3829 // where 3830 class TypePair { 3831 final Type t1; 3832 final Type t2;; 3833 3834 TypePair(Type t1, Type t2) { 3835 this.t1 = t1; 3836 this.t2 = t2; 3837 } 3838 @Override 3839 public int hashCode() { 3840 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2); 3841 } 3842 @Override 3843 public boolean equals(Object obj) { 3844 return (obj instanceof TypePair typePair) 3845 && isSameType(t1, typePair.t1) 3846 && isSameType(t2, typePair.t2); 3847 } 3848 } 3849 Set<TypePair> mergeCache = new HashSet<>(); 3850 private Type merge(Type c1, Type c2) { 3851 ClassType class1 = (ClassType) c1; 3852 List<Type> act1 = class1.getTypeArguments(); 3853 ClassType class2 = (ClassType) c2; 3854 List<Type> act2 = class2.getTypeArguments(); 3855 ListBuffer<Type> merged = new ListBuffer<>(); 3856 List<Type> typarams = class1.tsym.type.getTypeArguments(); 3857 3858 while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) { 3859 if (containsType(act1.head, act2.head)) { 3860 merged.append(act1.head); 3861 } else if (containsType(act2.head, act1.head)) { 3862 merged.append(act2.head); 3863 } else { 3864 TypePair pair = new TypePair(c1, c2); 3865 Type m; 3866 if (mergeCache.add(pair)) { 3867 m = new WildcardType(lub(wildUpperBound(act1.head), 3868 wildUpperBound(act2.head)), 3869 BoundKind.EXTENDS, 3870 syms.boundClass); 3871 mergeCache.remove(pair); 3872 } else { 3873 m = new WildcardType(syms.objectType, 3874 BoundKind.UNBOUND, 3875 syms.boundClass); 3876 } 3877 merged.append(m.withTypeVar(typarams.head)); 3878 } 3879 act1 = act1.tail; 3880 act2 = act2.tail; 3881 typarams = typarams.tail; 3882 } 3883 Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty()); 3884 // There is no spec detailing how type annotations are to 3885 // be inherited. So set it to noAnnotations for now 3886 return new ClassType(class1.getEnclosingType(), merged.toList(), 3887 class1.tsym); 3888 } 3889 3890 /** 3891 * Return the minimum type of a closure, a compound type if no 3892 * unique minimum exists. 3893 */ 3894 private Type compoundMin(List<Type> cl) { 3895 if (cl.isEmpty()) return syms.objectType; 3896 List<Type> compound = closureMin(cl); 3897 if (compound.isEmpty()) 3898 return null; 3899 else if (compound.tail.isEmpty()) 3900 return compound.head; 3901 else 3902 return makeIntersectionType(compound); 3903 } 3904 3905 /** 3906 * Return the minimum types of a closure, suitable for computing 3907 * compoundMin or glb. 3908 */ 3909 private List<Type> closureMin(List<Type> cl) { 3910 ListBuffer<Type> classes = new ListBuffer<>(); 3911 ListBuffer<Type> interfaces = new ListBuffer<>(); 3912 Set<Type> toSkip = new HashSet<>(); 3913 while (!cl.isEmpty()) { 3914 Type current = cl.head; 3915 boolean keep = !toSkip.contains(current); 3916 if (keep && current.hasTag(TYPEVAR)) { 3917 // skip lower-bounded variables with a subtype in cl.tail 3918 for (Type t : cl.tail) { 3919 if (isSubtypeNoCapture(t, current)) { 3920 keep = false; 3921 break; 3922 } 3923 } 3924 } 3925 if (keep) { 3926 if (current.isInterface()) 3927 interfaces.append(current); 3928 else 3929 classes.append(current); 3930 for (Type t : cl.tail) { 3931 // skip supertypes of 'current' in cl.tail 3932 if (isSubtypeNoCapture(current, t)) 3933 toSkip.add(t); 3934 } 3935 } 3936 cl = cl.tail; 3937 } 3938 return classes.appendList(interfaces).toList(); 3939 } 3940 3941 /** 3942 * Return the least upper bound of list of types. if the lub does 3943 * not exist return null. 3944 */ 3945 public Type lub(List<Type> ts) { 3946 return lub(ts.toArray(new Type[ts.length()])); 3947 } 3948 3949 /** 3950 * Return the least upper bound (lub) of set of types. If the lub 3951 * does not exist return the type of null (bottom). 3952 */ 3953 public Type lub(Type... ts) { 3954 final int UNKNOWN_BOUND = 0; 3955 final int ARRAY_BOUND = 1; 3956 final int CLASS_BOUND = 2; 3957 3958 int[] kinds = new int[ts.length]; 3959 3960 int boundkind = UNKNOWN_BOUND; 3961 for (int i = 0 ; i < ts.length ; i++) { 3962 Type t = ts[i]; 3963 switch (t.getTag()) { 3964 case CLASS: 3965 boundkind |= kinds[i] = CLASS_BOUND; 3966 break; 3967 case ARRAY: 3968 boundkind |= kinds[i] = ARRAY_BOUND; 3969 break; 3970 case TYPEVAR: 3971 do { 3972 t = t.getUpperBound(); 3973 } while (t.hasTag(TYPEVAR)); 3974 if (t.hasTag(ARRAY)) { 3975 boundkind |= kinds[i] = ARRAY_BOUND; 3976 } else { 3977 boundkind |= kinds[i] = CLASS_BOUND; 3978 } 3979 break; 3980 default: 3981 kinds[i] = UNKNOWN_BOUND; 3982 if (t.isPrimitive()) 3983 return syms.errType; 3984 } 3985 } 3986 switch (boundkind) { 3987 case 0: 3988 return syms.botType; 3989 3990 case ARRAY_BOUND: 3991 // calculate lub(A[], B[]) 3992 Type[] elements = new Type[ts.length]; 3993 for (int i = 0 ; i < ts.length ; i++) { 3994 Type elem = elements[i] = elemTypeFun.apply(ts[i]); 3995 if (elem.isPrimitive()) { 3996 // if a primitive type is found, then return 3997 // arraySuperType unless all the types are the 3998 // same 3999 Type first = ts[0]; 4000 for (int j = 1 ; j < ts.length ; j++) { 4001 if (!isSameType(first, ts[j])) { 4002 // lub(int[], B[]) is Cloneable & Serializable 4003 return arraySuperType(); 4004 } 4005 } 4006 // all the array types are the same, return one 4007 // lub(int[], int[]) is int[] 4008 return first; 4009 } 4010 } 4011 // lub(A[], B[]) is lub(A, B)[] 4012 return new ArrayType(lub(elements), syms.arrayClass); 4013 4014 case CLASS_BOUND: 4015 // calculate lub(A, B) 4016 int startIdx = 0; 4017 for (int i = 0; i < ts.length ; i++) { 4018 Type t = ts[i]; 4019 if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) { 4020 break; 4021 } else { 4022 startIdx++; 4023 } 4024 } 4025 Assert.check(startIdx < ts.length); 4026 //step 1 - compute erased candidate set (EC) 4027 List<Type> cl = erasedSupertypes(ts[startIdx]); 4028 for (int i = startIdx + 1 ; i < ts.length ; i++) { 4029 Type t = ts[i]; 4030 if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) 4031 cl = intersect(cl, erasedSupertypes(t)); 4032 } 4033 //step 2 - compute minimal erased candidate set (MEC) 4034 List<Type> mec = closureMin(cl); 4035 //step 3 - for each element G in MEC, compute lci(Inv(G)) 4036 List<Type> candidates = List.nil(); 4037 for (Type erasedSupertype : mec) { 4038 List<Type> lci = List.of(asSuper(ts[startIdx], erasedSupertype.tsym)); 4039 for (int i = startIdx + 1 ; i < ts.length ; i++) { 4040 Type superType = asSuper(ts[i], erasedSupertype.tsym); 4041 lci = intersect(lci, superType != null ? List.of(superType) : List.nil()); 4042 } 4043 candidates = candidates.appendList(lci); 4044 } 4045 //step 4 - let MEC be { G1, G2 ... Gn }, then we have that 4046 //lub = lci(Inv(G1)) & lci(Inv(G2)) & ... & lci(Inv(Gn)) 4047 return compoundMin(candidates); 4048 4049 default: 4050 // calculate lub(A, B[]) 4051 List<Type> classes = List.of(arraySuperType()); 4052 for (int i = 0 ; i < ts.length ; i++) { 4053 if (kinds[i] != ARRAY_BOUND) // Filter out any arrays 4054 classes = classes.prepend(ts[i]); 4055 } 4056 // lub(A, B[]) is lub(A, arraySuperType) 4057 return lub(classes); 4058 } 4059 } 4060 // where 4061 List<Type> erasedSupertypes(Type t) { 4062 ListBuffer<Type> buf = new ListBuffer<>(); 4063 for (Type sup : closure(t)) { 4064 if (sup.hasTag(TYPEVAR)) { 4065 buf.append(sup); 4066 } else { 4067 buf.append(erasure(sup)); 4068 } 4069 } 4070 return buf.toList(); 4071 } 4072 4073 private Type arraySuperType; 4074 private Type arraySuperType() { 4075 // initialized lazily to avoid problems during compiler startup 4076 if (arraySuperType == null) { 4077 // JLS 10.8: all arrays implement Cloneable and Serializable. 4078 arraySuperType = makeIntersectionType(List.of(syms.serializableType, 4079 syms.cloneableType), true); 4080 } 4081 return arraySuperType; 4082 } 4083 // </editor-fold> 4084 4085 // <editor-fold defaultstate="collapsed" desc="Greatest lower bound"> 4086 public Type glb(List<Type> ts) { 4087 Type t1 = ts.head; 4088 for (Type t2 : ts.tail) { 4089 if (t1.isErroneous()) 4090 return t1; 4091 t1 = glb(t1, t2); 4092 } 4093 return t1; 4094 } 4095 //where 4096 public Type glb(Type t, Type s) { 4097 if (s == null) 4098 return t; 4099 else if (t.isPrimitive() || s.isPrimitive()) 4100 return syms.errType; 4101 else if (isSubtypeNoCapture(t, s)) 4102 return t; 4103 else if (isSubtypeNoCapture(s, t)) 4104 return s; 4105 4106 List<Type> closure = union(closure(t), closure(s)); 4107 return glbFlattened(closure, t); 4108 } 4109 //where 4110 /** 4111 * Perform glb for a list of non-primitive, non-error, non-compound types; 4112 * redundant elements are removed. Bounds should be ordered according to 4113 * {@link Symbol#precedes(TypeSymbol,Types)}. 4114 * 4115 * @param flatBounds List of type to glb 4116 * @param errT Original type to use if the result is an error type 4117 */ 4118 private Type glbFlattened(List<Type> flatBounds, Type errT) { 4119 List<Type> bounds = closureMin(flatBounds); 4120 4121 if (bounds.isEmpty()) { // length == 0 4122 return syms.objectType; 4123 } else if (bounds.tail.isEmpty()) { // length == 1 4124 return bounds.head; 4125 } else { // length > 1 4126 int classCount = 0; 4127 List<Type> cvars = List.nil(); 4128 List<Type> lowers = List.nil(); 4129 for (Type bound : bounds) { 4130 if (!bound.isInterface()) { 4131 classCount++; 4132 Type lower = cvarLowerBound(bound); 4133 if (bound != lower && !lower.hasTag(BOT)) { 4134 cvars = cvars.append(bound); 4135 lowers = lowers.append(lower); 4136 } 4137 } 4138 } 4139 if (classCount > 1) { 4140 if (lowers.isEmpty()) { 4141 return createErrorType(errT); 4142 } else { 4143 // try again with lower bounds included instead of capture variables 4144 List<Type> newBounds = bounds.diff(cvars).appendList(lowers); 4145 return glb(newBounds); 4146 } 4147 } 4148 } 4149 return makeIntersectionType(bounds); 4150 } 4151 // </editor-fold> 4152 4153 // <editor-fold defaultstate="collapsed" desc="hashCode"> 4154 /** 4155 * Compute a hash code on a type. 4156 */ 4157 public int hashCode(Type t) { 4158 return hashCode(t, false); 4159 } 4160 4161 public int hashCode(Type t, boolean strict) { 4162 return strict ? 4163 hashCodeStrictVisitor.visit(t) : 4164 hashCodeVisitor.visit(t); 4165 } 4166 // where 4167 private static final HashCodeVisitor hashCodeVisitor = new HashCodeVisitor(); 4168 private static final HashCodeVisitor hashCodeStrictVisitor = new HashCodeVisitor() { 4169 @Override 4170 public Integer visitTypeVar(TypeVar t, Void ignored) { 4171 return System.identityHashCode(t); 4172 } 4173 }; 4174 4175 private static class HashCodeVisitor extends UnaryVisitor<Integer> { 4176 public Integer visitType(Type t, Void ignored) { 4177 return t.getTag().ordinal(); 4178 } 4179 4180 @Override 4181 public Integer visitClassType(ClassType t, Void ignored) { 4182 int result = visit(t.getEnclosingType()); 4183 result *= 127; 4184 result += t.tsym.flatName().hashCode(); 4185 for (Type s : t.getTypeArguments()) { 4186 result *= 127; 4187 result += visit(s); 4188 } 4189 return result; 4190 } 4191 4192 @Override 4193 public Integer visitMethodType(MethodType t, Void ignored) { 4194 int h = METHOD.ordinal(); 4195 for (List<Type> thisargs = t.argtypes; 4196 thisargs.tail != null; 4197 thisargs = thisargs.tail) 4198 h = (h << 5) + visit(thisargs.head); 4199 return (h << 5) + visit(t.restype); 4200 } 4201 4202 @Override 4203 public Integer visitWildcardType(WildcardType t, Void ignored) { 4204 int result = t.kind.hashCode(); 4205 if (t.type != null) { 4206 result *= 127; 4207 result += visit(t.type); 4208 } 4209 return result; 4210 } 4211 4212 @Override 4213 public Integer visitArrayType(ArrayType t, Void ignored) { 4214 return visit(t.elemtype) + 12; 4215 } 4216 4217 @Override 4218 public Integer visitTypeVar(TypeVar t, Void ignored) { 4219 return System.identityHashCode(t); 4220 } 4221 4222 @Override 4223 public Integer visitUndetVar(UndetVar t, Void ignored) { 4224 return System.identityHashCode(t); 4225 } 4226 4227 @Override 4228 public Integer visitErrorType(ErrorType t, Void ignored) { 4229 return 0; 4230 } 4231 } 4232 // </editor-fold> 4233 4234 // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable"> 4235 /** 4236 * Does t have a result that is a subtype of the result type of s, 4237 * suitable for covariant returns? It is assumed that both types 4238 * are (possibly polymorphic) method types. Monomorphic method 4239 * types are handled in the obvious way. Polymorphic method types 4240 * require renaming all type variables of one to corresponding 4241 * type variables in the other, where correspondence is by 4242 * position in the type parameter list. */ 4243 public boolean resultSubtype(Type t, Type s, Warner warner) { 4244 List<Type> tvars = t.getTypeArguments(); 4245 List<Type> svars = s.getTypeArguments(); 4246 Type tres = t.getReturnType(); 4247 Type sres = subst(s.getReturnType(), svars, tvars); 4248 return covariantReturnType(tres, sres, warner); 4249 } 4250 4251 /** 4252 * Return-Type-Substitutable. 4253 * @jls 8.4.5 Method Result 4254 */ 4255 public boolean returnTypeSubstitutable(Type r1, Type r2) { 4256 if (hasSameArgs(r1, r2)) 4257 return resultSubtype(r1, r2, noWarnings); 4258 else 4259 return covariantReturnType(r1.getReturnType(), 4260 erasure(r2.getReturnType()), 4261 noWarnings); 4262 } 4263 4264 public boolean returnTypeSubstitutable(Type r1, 4265 Type r2, Type r2res, 4266 Warner warner) { 4267 if (isSameType(r1.getReturnType(), r2res)) 4268 return true; 4269 if (r1.getReturnType().isPrimitive() || r2res.isPrimitive()) 4270 return false; 4271 4272 if (hasSameArgs(r1, r2)) 4273 return covariantReturnType(r1.getReturnType(), r2res, warner); 4274 if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner)) 4275 return true; 4276 if (!isSubtype(r1.getReturnType(), erasure(r2res))) 4277 return false; 4278 warner.warn(LintCategory.UNCHECKED); 4279 return true; 4280 } 4281 4282 /** 4283 * Is t an appropriate return type in an overrider for a 4284 * method that returns s? 4285 */ 4286 public boolean covariantReturnType(Type t, Type s, Warner warner) { 4287 return 4288 isSameType(t, s) || 4289 !t.isPrimitive() && 4290 !s.isPrimitive() && 4291 isAssignable(t, s, warner); 4292 } 4293 // </editor-fold> 4294 4295 // <editor-fold defaultstate="collapsed" desc="Box/unbox support"> 4296 /** 4297 * Return the class that boxes the given primitive. 4298 */ 4299 public ClassSymbol boxedClass(Type t) { 4300 return syms.enterClass(syms.java_base, syms.boxedName[t.getTag().ordinal()]); 4301 } 4302 4303 /** 4304 * Return the boxed type if 't' is primitive, otherwise return 't' itself. 4305 */ 4306 public Type boxedTypeOrType(Type t) { 4307 return t.isPrimitive() ? 4308 boxedClass(t).type : 4309 t; 4310 } 4311 4312 /** 4313 * Return the primitive type corresponding to a boxed type. 4314 */ 4315 public Type unboxedType(Type t) { 4316 if (t.hasTag(ERROR)) 4317 return Type.noType; 4318 for (int i=0; i<syms.boxedName.length; i++) { 4319 Name box = syms.boxedName[i]; 4320 if (box != null && 4321 asSuper(t, syms.enterClass(syms.java_base, box)) != null) 4322 return syms.typeOfTag[i]; 4323 } 4324 return Type.noType; 4325 } 4326 4327 /** 4328 * Return the unboxed type if 't' is a boxed class, otherwise return 't' itself. 4329 */ 4330 public Type unboxedTypeOrType(Type t) { 4331 Type unboxedType = unboxedType(t); 4332 return unboxedType.hasTag(NONE) ? t : unboxedType; 4333 } 4334 // </editor-fold> 4335 4336 // <editor-fold defaultstate="collapsed" desc="Capture conversion"> 4337 /* 4338 * JLS 5.1.10 Capture Conversion: 4339 * 4340 * Let G name a generic type declaration with n formal type 4341 * parameters A1 ... An with corresponding bounds U1 ... Un. There 4342 * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>, 4343 * where, for 1 <= i <= n: 4344 * 4345 * + If Ti is a wildcard type argument (4.5.1) of the form ? then 4346 * Si is a fresh type variable whose upper bound is 4347 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null 4348 * type. 4349 * 4350 * + If Ti is a wildcard type argument of the form ? extends Bi, 4351 * then Si is a fresh type variable whose upper bound is 4352 * glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is 4353 * the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is 4354 * a compile-time error if for any two classes (not interfaces) 4355 * Vi and Vj,Vi is not a subclass of Vj or vice versa. 4356 * 4357 * + If Ti is a wildcard type argument of the form ? super Bi, 4358 * then Si is a fresh type variable whose upper bound is 4359 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi. 4360 * 4361 * + Otherwise, Si = Ti. 4362 * 4363 * Capture conversion on any type other than a parameterized type 4364 * (4.5) acts as an identity conversion (5.1.1). Capture 4365 * conversions never require a special action at run time and 4366 * therefore never throw an exception at run time. 4367 * 4368 * Capture conversion is not applied recursively. 4369 */ 4370 /** 4371 * Capture conversion as specified by the JLS. 4372 */ 4373 4374 public List<Type> capture(List<Type> ts) { 4375 List<Type> buf = List.nil(); 4376 for (Type t : ts) { 4377 buf = buf.prepend(capture(t)); 4378 } 4379 return buf.reverse(); 4380 } 4381 4382 public Type capture(Type t) { 4383 if (!t.hasTag(CLASS)) { 4384 return t; 4385 } 4386 if (t.getEnclosingType() != Type.noType) { 4387 Type capturedEncl = capture(t.getEnclosingType()); 4388 if (capturedEncl != t.getEnclosingType()) { 4389 Type type1 = memberType(capturedEncl, t.tsym); 4390 t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments()); 4391 } 4392 } 4393 ClassType cls = (ClassType)t; 4394 if (cls.isRaw() || !cls.isParameterized()) 4395 return cls; 4396 4397 ClassType G = (ClassType)cls.asElement().asType(); 4398 List<Type> A = G.getTypeArguments(); 4399 List<Type> T = cls.getTypeArguments(); 4400 List<Type> S = freshTypeVariables(T); 4401 4402 List<Type> currentA = A; 4403 List<Type> currentT = T; 4404 List<Type> currentS = S; 4405 boolean captured = false; 4406 while (!currentA.isEmpty() && 4407 !currentT.isEmpty() && 4408 !currentS.isEmpty()) { 4409 if (currentS.head != currentT.head) { 4410 captured = true; 4411 WildcardType Ti = (WildcardType)currentT.head; 4412 Type Ui = currentA.head.getUpperBound(); 4413 CapturedType Si = (CapturedType)currentS.head; 4414 if (Ui == null) 4415 Ui = syms.objectType; 4416 switch (Ti.kind) { 4417 case UNBOUND: 4418 Si.setUpperBound( subst(Ui, A, S) ); 4419 Si.lower = syms.botType; 4420 break; 4421 case EXTENDS: 4422 Si.setUpperBound( glb(Ti.getExtendsBound(), subst(Ui, A, S)) ); 4423 Si.lower = syms.botType; 4424 break; 4425 case SUPER: 4426 Si.setUpperBound( subst(Ui, A, S) ); 4427 Si.lower = Ti.getSuperBound(); 4428 break; 4429 } 4430 Type tmpBound = Si.getUpperBound().hasTag(UNDETVAR) ? ((UndetVar)Si.getUpperBound()).qtype : Si.getUpperBound(); 4431 Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar)Si.lower).qtype : Si.lower; 4432 if (!Si.getUpperBound().hasTag(ERROR) && 4433 !Si.lower.hasTag(ERROR) && 4434 isSameType(tmpBound, tmpLower)) { 4435 currentS.head = Si.getUpperBound(); 4436 } 4437 } 4438 currentA = currentA.tail; 4439 currentT = currentT.tail; 4440 currentS = currentS.tail; 4441 } 4442 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty()) 4443 return erasure(t); // some "rare" type involved 4444 4445 if (captured) 4446 return new ClassType(cls.getEnclosingType(), S, cls.tsym, 4447 cls.getMetadata()); 4448 else 4449 return t; 4450 } 4451 // where 4452 public List<Type> freshTypeVariables(List<Type> types) { 4453 ListBuffer<Type> result = new ListBuffer<>(); 4454 for (Type t : types) { 4455 if (t.hasTag(WILDCARD)) { 4456 Type bound = ((WildcardType)t).getExtendsBound(); 4457 if (bound == null) 4458 bound = syms.objectType; 4459 result.append(new CapturedType(capturedName, 4460 syms.noSymbol, 4461 bound, 4462 syms.botType, 4463 (WildcardType)t)); 4464 } else { 4465 result.append(t); 4466 } 4467 } 4468 return result.toList(); 4469 } 4470 // </editor-fold> 4471 4472 // <editor-fold defaultstate="collapsed" desc="Internal utility methods"> 4473 private boolean sideCast(Type from, Type to, Warner warn) { 4474 // We are casting from type $from$ to type $to$, which are 4475 // non-final unrelated types. This method 4476 // tries to reject a cast by transferring type parameters 4477 // from $to$ to $from$ by common superinterfaces. 4478 boolean reverse = false; 4479 Type target = to; 4480 if ((to.tsym.flags() & INTERFACE) == 0) { 4481 Assert.check((from.tsym.flags() & INTERFACE) != 0); 4482 reverse = true; 4483 to = from; 4484 from = target; 4485 } 4486 List<Type> commonSupers = superClosure(to, erasure(from)); 4487 boolean giveWarning = commonSupers.isEmpty(); 4488 // The arguments to the supers could be unified here to 4489 // get a more accurate analysis 4490 while (commonSupers.nonEmpty()) { 4491 Type t1 = asSuper(from, commonSupers.head.tsym); 4492 Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym); 4493 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) 4494 return false; 4495 giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)); 4496 commonSupers = commonSupers.tail; 4497 } 4498 if (giveWarning && !isReifiable(reverse ? from : to)) 4499 warn.warn(LintCategory.UNCHECKED); 4500 return true; 4501 } 4502 4503 private boolean sideCastFinal(Type from, Type to, Warner warn) { 4504 // We are casting from type $from$ to type $to$, which are 4505 // unrelated types one of which is final and the other of 4506 // which is an interface. This method 4507 // tries to reject a cast by transferring type parameters 4508 // from the final class to the interface. 4509 boolean reverse = false; 4510 Type target = to; 4511 if ((to.tsym.flags() & INTERFACE) == 0) { 4512 Assert.check((from.tsym.flags() & INTERFACE) != 0); 4513 reverse = true; 4514 to = from; 4515 from = target; 4516 } 4517 Assert.check((from.tsym.flags() & FINAL) != 0); 4518 Type t1 = asSuper(from, to.tsym); 4519 if (t1 == null) return false; 4520 Type t2 = to; 4521 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) 4522 return false; 4523 if (!isReifiable(target) && 4524 (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2))) 4525 warn.warn(LintCategory.UNCHECKED); 4526 return true; 4527 } 4528 4529 private boolean giveWarning(Type from, Type to) { 4530 List<Type> bounds = to.isCompound() ? 4531 directSupertypes(to) : List.of(to); 4532 for (Type b : bounds) { 4533 Type subFrom = asSub(from, b.tsym); 4534 if (b.isParameterized() && 4535 (!(isUnbounded(b) || 4536 isSubtype(from, b) || 4537 ((subFrom != null) && containsType(b.allparams(), subFrom.allparams()))))) { 4538 return true; 4539 } 4540 } 4541 return false; 4542 } 4543 4544 private List<Type> superClosure(Type t, Type s) { 4545 List<Type> cl = List.nil(); 4546 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) { 4547 if (isSubtype(s, erasure(l.head))) { 4548 cl = insert(cl, l.head); 4549 } else { 4550 cl = union(cl, superClosure(l.head, s)); 4551 } 4552 } 4553 return cl; 4554 } 4555 4556 private boolean containsTypeEquivalent(Type t, Type s) { 4557 return isSameType(t, s) || // shortcut 4558 containsType(t, s) && containsType(s, t); 4559 } 4560 4561 // <editor-fold defaultstate="collapsed" desc="adapt"> 4562 /** 4563 * Adapt a type by computing a substitution which maps a source 4564 * type to a target type. 4565 * 4566 * @param source the source type 4567 * @param target the target type 4568 * @param from the type variables of the computed substitution 4569 * @param to the types of the computed substitution. 4570 */ 4571 public void adapt(Type source, 4572 Type target, 4573 ListBuffer<Type> from, 4574 ListBuffer<Type> to) throws AdaptFailure { 4575 new Adapter(from, to).adapt(source, target); 4576 } 4577 4578 class Adapter extends SimpleVisitor<Void, Type> { 4579 4580 ListBuffer<Type> from; 4581 ListBuffer<Type> to; 4582 Map<Symbol,Type> mapping; 4583 4584 Adapter(ListBuffer<Type> from, ListBuffer<Type> to) { 4585 this.from = from; 4586 this.to = to; 4587 mapping = new HashMap<>(); 4588 } 4589 4590 public void adapt(Type source, Type target) throws AdaptFailure { 4591 visit(source, target); 4592 List<Type> fromList = from.toList(); 4593 List<Type> toList = to.toList(); 4594 while (!fromList.isEmpty()) { 4595 Type val = mapping.get(fromList.head.tsym); 4596 if (toList.head != val) 4597 toList.head = val; 4598 fromList = fromList.tail; 4599 toList = toList.tail; 4600 } 4601 } 4602 4603 @Override 4604 public Void visitClassType(ClassType source, Type target) throws AdaptFailure { 4605 if (target.hasTag(CLASS)) 4606 adaptRecursive(source.allparams(), target.allparams()); 4607 return null; 4608 } 4609 4610 @Override 4611 public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure { 4612 if (target.hasTag(ARRAY)) 4613 adaptRecursive(elemtype(source), elemtype(target)); 4614 return null; 4615 } 4616 4617 @Override 4618 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { 4619 if (source.isExtendsBound()) 4620 adaptRecursive(wildUpperBound(source), wildUpperBound(target)); 4621 else if (source.isSuperBound()) 4622 adaptRecursive(wildLowerBound(source), wildLowerBound(target)); 4623 return null; 4624 } 4625 4626 @Override 4627 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure { 4628 // Check to see if there is 4629 // already a mapping for $source$, in which case 4630 // the old mapping will be merged with the new 4631 Type val = mapping.get(source.tsym); 4632 if (val != null) { 4633 if (val.isSuperBound() && target.isSuperBound()) { 4634 val = isSubtype(wildLowerBound(val), wildLowerBound(target)) 4635 ? target : val; 4636 } else if (val.isExtendsBound() && target.isExtendsBound()) { 4637 val = isSubtype(wildUpperBound(val), wildUpperBound(target)) 4638 ? val : target; 4639 } else if (!isSameType(val, target)) { 4640 throw new AdaptFailure(); 4641 } 4642 } else { 4643 val = target; 4644 from.append(source); 4645 to.append(target); 4646 } 4647 mapping.put(source.tsym, val); 4648 return null; 4649 } 4650 4651 @Override 4652 public Void visitType(Type source, Type target) { 4653 return null; 4654 } 4655 4656 private Set<TypePair> cache = new HashSet<>(); 4657 4658 private void adaptRecursive(Type source, Type target) { 4659 TypePair pair = new TypePair(source, target); 4660 if (cache.add(pair)) { 4661 try { 4662 visit(source, target); 4663 } finally { 4664 cache.remove(pair); 4665 } 4666 } 4667 } 4668 4669 private void adaptRecursive(List<Type> source, List<Type> target) { 4670 if (source.length() == target.length()) { 4671 while (source.nonEmpty()) { 4672 adaptRecursive(source.head, target.head); 4673 source = source.tail; 4674 target = target.tail; 4675 } 4676 } 4677 } 4678 } 4679 4680 public static class AdaptFailure extends RuntimeException { 4681 static final long serialVersionUID = -7490231548272701566L; 4682 } 4683 4684 private void adaptSelf(Type t, 4685 ListBuffer<Type> from, 4686 ListBuffer<Type> to) { 4687 try { 4688 //if (t.tsym.type != t) 4689 adapt(t.tsym.type, t, from, to); 4690 } catch (AdaptFailure ex) { 4691 // Adapt should never fail calculating a mapping from 4692 // t.tsym.type to t as there can be no merge problem. 4693 throw new AssertionError(ex); 4694 } 4695 } 4696 // </editor-fold> 4697 4698 /** 4699 * Rewrite all type variables (universal quantifiers) in the given 4700 * type to wildcards (existential quantifiers). This is used to 4701 * determine if a cast is allowed. For example, if high is true 4702 * and {@code T <: Number}, then {@code List<T>} is rewritten to 4703 * {@code List<? extends Number>}. Since {@code List<Integer> <: 4704 * List<? extends Number>} a {@code List<T>} can be cast to {@code 4705 * List<Integer>} with a warning. 4706 * @param t a type 4707 * @param high if true return an upper bound; otherwise a lower 4708 * bound 4709 * @param rewriteTypeVars only rewrite captured wildcards if false; 4710 * otherwise rewrite all type variables 4711 * @return the type rewritten with wildcards (existential 4712 * quantifiers) only 4713 */ 4714 private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) { 4715 return new Rewriter(high, rewriteTypeVars).visit(t); 4716 } 4717 4718 class Rewriter extends UnaryVisitor<Type> { 4719 4720 boolean high; 4721 boolean rewriteTypeVars; 4722 4723 Rewriter(boolean high, boolean rewriteTypeVars) { 4724 this.high = high; 4725 this.rewriteTypeVars = rewriteTypeVars; 4726 } 4727 4728 @Override 4729 public Type visitClassType(ClassType t, Void s) { 4730 ListBuffer<Type> rewritten = new ListBuffer<>(); 4731 boolean changed = false; 4732 for (Type arg : t.allparams()) { 4733 Type bound = visit(arg); 4734 if (arg != bound) { 4735 changed = true; 4736 } 4737 rewritten.append(bound); 4738 } 4739 if (changed) 4740 return subst(t.tsym.type, 4741 t.tsym.type.allparams(), 4742 rewritten.toList()); 4743 else 4744 return t; 4745 } 4746 4747 public Type visitType(Type t, Void s) { 4748 return t; 4749 } 4750 4751 @Override 4752 public Type visitCapturedType(CapturedType t, Void s) { 4753 Type w_bound = t.wildcard.type; 4754 Type bound = w_bound.contains(t) ? 4755 erasure(w_bound) : 4756 visit(w_bound); 4757 return rewriteAsWildcardType(visit(bound), t.wildcard.bound, t.wildcard.kind); 4758 } 4759 4760 @Override 4761 public Type visitTypeVar(TypeVar t, Void s) { 4762 if (rewriteTypeVars) { 4763 Type bound = t.getUpperBound().contains(t) ? 4764 erasure(t.getUpperBound()) : 4765 visit(t.getUpperBound()); 4766 return rewriteAsWildcardType(bound, t, EXTENDS); 4767 } else { 4768 return t; 4769 } 4770 } 4771 4772 @Override 4773 public Type visitWildcardType(WildcardType t, Void s) { 4774 Type bound2 = visit(t.type); 4775 return t.type == bound2 ? t : rewriteAsWildcardType(bound2, t.bound, t.kind); 4776 } 4777 4778 private Type rewriteAsWildcardType(Type bound, TypeVar formal, BoundKind bk) { 4779 switch (bk) { 4780 case EXTENDS: return high ? 4781 makeExtendsWildcard(B(bound), formal) : 4782 makeExtendsWildcard(syms.objectType, formal); 4783 case SUPER: return high ? 4784 makeSuperWildcard(syms.botType, formal) : 4785 makeSuperWildcard(B(bound), formal); 4786 case UNBOUND: return makeExtendsWildcard(syms.objectType, formal); 4787 default: 4788 Assert.error("Invalid bound kind " + bk); 4789 return null; 4790 } 4791 } 4792 4793 Type B(Type t) { 4794 while (t.hasTag(WILDCARD)) { 4795 WildcardType w = (WildcardType)t; 4796 t = high ? 4797 w.getExtendsBound() : 4798 w.getSuperBound(); 4799 if (t == null) { 4800 t = high ? syms.objectType : syms.botType; 4801 } 4802 } 4803 return t; 4804 } 4805 } 4806 4807 4808 /** 4809 * Create a wildcard with the given upper (extends) bound; create 4810 * an unbounded wildcard if bound is Object. 4811 * 4812 * @param bound the upper bound 4813 * @param formal the formal type parameter that will be 4814 * substituted by the wildcard 4815 */ 4816 private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) { 4817 if (bound == syms.objectType) { 4818 return new WildcardType(syms.objectType, 4819 BoundKind.UNBOUND, 4820 syms.boundClass, 4821 formal); 4822 } else { 4823 return new WildcardType(bound, 4824 BoundKind.EXTENDS, 4825 syms.boundClass, 4826 formal); 4827 } 4828 } 4829 4830 /** 4831 * Create a wildcard with the given lower (super) bound; create an 4832 * unbounded wildcard if bound is bottom (type of {@code null}). 4833 * 4834 * @param bound the lower bound 4835 * @param formal the formal type parameter that will be 4836 * substituted by the wildcard 4837 */ 4838 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) { 4839 if (bound.hasTag(BOT)) { 4840 return new WildcardType(syms.objectType, 4841 BoundKind.UNBOUND, 4842 syms.boundClass, 4843 formal); 4844 } else { 4845 return new WildcardType(bound, 4846 BoundKind.SUPER, 4847 syms.boundClass, 4848 formal); 4849 } 4850 } 4851 4852 /** 4853 * A wrapper for a type that allows use in sets. 4854 */ 4855 public static class UniqueType { 4856 public final Type type; 4857 final Types types; 4858 4859 public UniqueType(Type type, Types types) { 4860 this.type = type; 4861 this.types = types; 4862 } 4863 4864 public int hashCode() { 4865 return types.hashCode(type); 4866 } 4867 4868 public boolean equals(Object obj) { 4869 return (obj instanceof UniqueType uniqueType) && 4870 types.isSameType(type, uniqueType.type); 4871 } 4872 4873 public String toString() { 4874 return type.toString(); 4875 } 4876 4877 } 4878 // </editor-fold> 4879 4880 // <editor-fold defaultstate="collapsed" desc="Visitors"> 4881 /** 4882 * A default visitor for types. All visitor methods except 4883 * visitType are implemented by delegating to visitType. Concrete 4884 * subclasses must provide an implementation of visitType and can 4885 * override other methods as needed. 4886 * 4887 * @param <R> the return type of the operation implemented by this 4888 * visitor; use Void if no return type is needed. 4889 * @param <S> the type of the second argument (the first being the 4890 * type itself) of the operation implemented by this visitor; use 4891 * Void if a second argument is not needed. 4892 */ 4893 public abstract static class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> { 4894 public final R visit(Type t, S s) { return t.accept(this, s); } 4895 public R visitClassType(ClassType t, S s) { return visitType(t, s); } 4896 public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); } 4897 public R visitArrayType(ArrayType t, S s) { return visitType(t, s); } 4898 public R visitMethodType(MethodType t, S s) { return visitType(t, s); } 4899 public R visitPackageType(PackageType t, S s) { return visitType(t, s); } 4900 public R visitModuleType(ModuleType t, S s) { return visitType(t, s); } 4901 public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); } 4902 public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); } 4903 public R visitForAll(ForAll t, S s) { return visitType(t, s); } 4904 public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); } 4905 public R visitErrorType(ErrorType t, S s) { return visitType(t, s); } 4906 } 4907 4908 /** 4909 * A default visitor for symbols. All visitor methods except 4910 * visitSymbol are implemented by delegating to visitSymbol. Concrete 4911 * subclasses must provide an implementation of visitSymbol and can 4912 * override other methods as needed. 4913 * 4914 * @param <R> the return type of the operation implemented by this 4915 * visitor; use Void if no return type is needed. 4916 * @param <S> the type of the second argument (the first being the 4917 * symbol itself) of the operation implemented by this visitor; use 4918 * Void if a second argument is not needed. 4919 */ 4920 public abstract static class DefaultSymbolVisitor<R,S> implements Symbol.Visitor<R,S> { 4921 public final R visit(Symbol s, S arg) { return s.accept(this, arg); } 4922 public R visitClassSymbol(ClassSymbol s, S arg) { return visitSymbol(s, arg); } 4923 public R visitMethodSymbol(MethodSymbol s, S arg) { return visitSymbol(s, arg); } 4924 public R visitOperatorSymbol(OperatorSymbol s, S arg) { return visitSymbol(s, arg); } 4925 public R visitPackageSymbol(PackageSymbol s, S arg) { return visitSymbol(s, arg); } 4926 public R visitTypeSymbol(TypeSymbol s, S arg) { return visitSymbol(s, arg); } 4927 public R visitVarSymbol(VarSymbol s, S arg) { return visitSymbol(s, arg); } 4928 } 4929 4930 /** 4931 * A <em>simple</em> visitor for types. This visitor is simple as 4932 * captured wildcards, for-all types (generic methods), and 4933 * undetermined type variables (part of inference) are hidden. 4934 * Captured wildcards are hidden by treating them as type 4935 * variables and the rest are hidden by visiting their qtypes. 4936 * 4937 * @param <R> the return type of the operation implemented by this 4938 * visitor; use Void if no return type is needed. 4939 * @param <S> the type of the second argument (the first being the 4940 * type itself) of the operation implemented by this visitor; use 4941 * Void if a second argument is not needed. 4942 */ 4943 public abstract static class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> { 4944 @Override 4945 public R visitCapturedType(CapturedType t, S s) { 4946 return visitTypeVar(t, s); 4947 } 4948 @Override 4949 public R visitForAll(ForAll t, S s) { 4950 return visit(t.qtype, s); 4951 } 4952 @Override 4953 public R visitUndetVar(UndetVar t, S s) { 4954 return visit(t.qtype, s); 4955 } 4956 } 4957 4958 /** 4959 * A plain relation on types. That is a 2-ary function on the 4960 * form Type × Type → Boolean. 4961 * <!-- In plain text: Type x Type -> Boolean --> 4962 */ 4963 public abstract static class TypeRelation extends SimpleVisitor<Boolean,Type> {} 4964 4965 /** 4966 * A convenience visitor for implementing operations that only 4967 * require one argument (the type itself), that is, unary 4968 * operations. 4969 * 4970 * @param <R> the return type of the operation implemented by this 4971 * visitor; use Void if no return type is needed. 4972 */ 4973 public abstract static class UnaryVisitor<R> extends SimpleVisitor<R,Void> { 4974 public final R visit(Type t) { return t.accept(this, null); } 4975 } 4976 4977 /** 4978 * A visitor for implementing a mapping from types to types. The 4979 * default behavior of this class is to implement the identity 4980 * mapping (mapping a type to itself). This can be overridden in 4981 * subclasses. 4982 * 4983 * @param <S> the type of the second argument (the first being the 4984 * type itself) of this mapping; use Void if a second argument is 4985 * not needed. 4986 */ 4987 public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> { 4988 public final Type visit(Type t) { return t.accept(this, null); } 4989 public Type visitType(Type t, S s) { return t; } 4990 } 4991 4992 /** 4993 * An abstract class for mappings from types to types (see {@link Type#map(TypeMapping)}. 4994 * This class implements the functional interface {@code Function}, that allows it to be used 4995 * fluently in stream-like processing. 4996 */ 4997 public static class TypeMapping<S> extends MapVisitor<S> implements Function<Type, Type> { 4998 @Override 4999 public Type apply(Type type) { return visit(type); } 5000 5001 List<Type> visit(List<Type> ts, S s) { 5002 return ts.map(t -> visit(t, s)); 5003 } 5004 5005 @Override 5006 public Type visitCapturedType(CapturedType t, S s) { 5007 return visitTypeVar(t, s); 5008 } 5009 } 5010 // </editor-fold> 5011 5012 5013 // <editor-fold defaultstate="collapsed" desc="Annotation support"> 5014 5015 public RetentionPolicy getRetention(Attribute.Compound a) { 5016 return getRetention(a.type.tsym); 5017 } 5018 5019 public RetentionPolicy getRetention(TypeSymbol sym) { 5020 RetentionPolicy vis = RetentionPolicy.CLASS; // the default 5021 Attribute.Compound c = sym.attribute(syms.retentionType.tsym); 5022 if (c != null) { 5023 Attribute value = c.member(names.value); 5024 if (value != null && value instanceof Attribute.Enum attributeEnum) { 5025 Name levelName = attributeEnum.value.name; 5026 if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE; 5027 else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS; 5028 else if (levelName == names.RUNTIME) vis = RetentionPolicy.RUNTIME; 5029 else ;// /* fail soft */ throw new AssertionError(levelName); 5030 } 5031 } 5032 return vis; 5033 } 5034 // </editor-fold> 5035 5036 // <editor-fold defaultstate="collapsed" desc="Signature Generation"> 5037 5038 public abstract static class SignatureGenerator { 5039 5040 public static class InvalidSignatureException extends RuntimeException { 5041 private static final long serialVersionUID = 0; 5042 5043 private final transient Type type; 5044 5045 InvalidSignatureException(Type type) { 5046 this.type = type; 5047 } 5048 5049 public Type type() { 5050 return type; 5051 } 5052 5053 @Override 5054 public Throwable fillInStackTrace() { 5055 // This is an internal exception; the stack trace is irrelevant. 5056 return this; 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.length() + 1) 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 } --- EOF ---