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