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