Types.java revision 3853:9d2379f8dd41
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 case CHAR: 2054 case SHORT: 2055 case INT: 2056 if (s.getTag().checkRange(value)) 2057 return true; 2058 break; 2059 case CLASS: 2060 switch (unboxedType(s).getTag()) { 2061 case BYTE: 2062 case CHAR: 2063 case SHORT: 2064 return isAssignable(t, unboxedType(s), warn); 2065 } 2066 break; 2067 } 2068 } 2069 return isConvertible(t, s, warn); 2070 } 2071 // </editor-fold> 2072 2073 // <editor-fold defaultstate="collapsed" desc="erasure"> 2074 /** 2075 * The erasure of t {@code |t|} -- the type that results when all 2076 * type parameters in t are deleted. 2077 */ 2078 public Type erasure(Type t) { 2079 return eraseNotNeeded(t) ? t : erasure(t, false); 2080 } 2081 //where 2082 private boolean eraseNotNeeded(Type t) { 2083 // We don't want to erase primitive types and String type as that 2084 // operation is idempotent. Also, erasing these could result in loss 2085 // of information such as constant values attached to such types. 2086 return (t.isPrimitive()) || (syms.stringType.tsym == t.tsym); 2087 } 2088 2089 private Type erasure(Type t, boolean recurse) { 2090 if (t.isPrimitive()) { 2091 return t; /* fast special case */ 2092 } else { 2093 Type out = erasure.visit(t, recurse); 2094 return out; 2095 } 2096 } 2097 // where 2098 private TypeMapping<Boolean> erasure = new TypeMapping<Boolean>() { 2099 private Type combineMetadata(final Type s, 2100 final Type t) { 2101 if (t.getMetadata() != TypeMetadata.EMPTY) { 2102 switch (s.getKind()) { 2103 case OTHER: 2104 case UNION: 2105 case INTERSECTION: 2106 case PACKAGE: 2107 case EXECUTABLE: 2108 case NONE: 2109 case VOID: 2110 case ERROR: 2111 return s; 2112 default: return s.cloneWithMetadata(s.getMetadata().without(Kind.ANNOTATIONS)); 2113 } 2114 } else { 2115 return s; 2116 } 2117 } 2118 2119 public Type visitType(Type t, Boolean recurse) { 2120 if (t.isPrimitive()) 2121 return t; /*fast special case*/ 2122 else { 2123 //other cases already handled 2124 return combineMetadata(t, t); 2125 } 2126 } 2127 2128 @Override 2129 public Type visitWildcardType(WildcardType t, Boolean recurse) { 2130 Type erased = erasure(wildUpperBound(t), recurse); 2131 return combineMetadata(erased, t); 2132 } 2133 2134 @Override 2135 public Type visitClassType(ClassType t, Boolean recurse) { 2136 Type erased = t.tsym.erasure(Types.this); 2137 if (recurse) { 2138 erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym, 2139 t.getMetadata().without(Kind.ANNOTATIONS)); 2140 return erased; 2141 } else { 2142 return combineMetadata(erased, t); 2143 } 2144 } 2145 2146 @Override 2147 public Type visitTypeVar(TypeVar t, Boolean recurse) { 2148 Type erased = erasure(t.bound, recurse); 2149 return combineMetadata(erased, t); 2150 } 2151 }; 2152 2153 public List<Type> erasure(List<Type> ts) { 2154 return erasure.visit(ts, false); 2155 } 2156 2157 public Type erasureRecursive(Type t) { 2158 return erasure(t, true); 2159 } 2160 2161 public List<Type> erasureRecursive(List<Type> ts) { 2162 return erasure.visit(ts, true); 2163 } 2164 // </editor-fold> 2165 2166 // <editor-fold defaultstate="collapsed" desc="makeIntersectionType"> 2167 /** 2168 * Make an intersection type from non-empty list of types. The list should be ordered according to 2169 * {@link TypeSymbol#precedes(TypeSymbol, Types)}. Note that this might cause a symbol completion. 2170 * Hence, this version of makeIntersectionType may not be called during a classfile read. 2171 * 2172 * @param bounds the types from which the intersection type is formed 2173 */ 2174 public IntersectionClassType makeIntersectionType(List<Type> bounds) { 2175 return makeIntersectionType(bounds, bounds.head.tsym.isInterface()); 2176 } 2177 2178 /** 2179 * Make an intersection type from non-empty list of types. The list should be ordered according to 2180 * {@link TypeSymbol#precedes(TypeSymbol, Types)}. This does not cause symbol completion as 2181 * an extra parameter indicates as to whether all bounds are interfaces - in which case the 2182 * supertype is implicitly assumed to be 'Object'. 2183 * 2184 * @param bounds the types from which the intersection type is formed 2185 * @param allInterfaces are all bounds interface types? 2186 */ 2187 public IntersectionClassType makeIntersectionType(List<Type> bounds, boolean allInterfaces) { 2188 Assert.check(bounds.nonEmpty()); 2189 Type firstExplicitBound = bounds.head; 2190 if (allInterfaces) { 2191 bounds = bounds.prepend(syms.objectType); 2192 } 2193 ClassSymbol bc = 2194 new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC, 2195 Type.moreInfo 2196 ? names.fromString(bounds.toString()) 2197 : names.empty, 2198 null, 2199 syms.noSymbol); 2200 IntersectionClassType intersectionType = new IntersectionClassType(bounds, bc, allInterfaces); 2201 bc.type = intersectionType; 2202 bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ? 2203 syms.objectType : // error condition, recover 2204 erasure(firstExplicitBound); 2205 bc.members_field = WriteableScope.create(bc); 2206 return intersectionType; 2207 } 2208 // </editor-fold> 2209 2210 // <editor-fold defaultstate="collapsed" desc="supertype"> 2211 public Type supertype(Type t) { 2212 return supertype.visit(t); 2213 } 2214 // where 2215 private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() { 2216 2217 public Type visitType(Type t, Void ignored) { 2218 // A note on wildcards: there is no good way to 2219 // determine a supertype for a super bounded wildcard. 2220 return Type.noType; 2221 } 2222 2223 @Override 2224 public Type visitClassType(ClassType t, Void ignored) { 2225 if (t.supertype_field == null) { 2226 Type supertype = ((ClassSymbol)t.tsym).getSuperclass(); 2227 // An interface has no superclass; its supertype is Object. 2228 if (t.isInterface()) 2229 supertype = ((ClassType)t.tsym.type).supertype_field; 2230 if (t.supertype_field == null) { 2231 List<Type> actuals = classBound(t).allparams(); 2232 List<Type> formals = t.tsym.type.allparams(); 2233 if (t.hasErasedSupertypes()) { 2234 t.supertype_field = erasureRecursive(supertype); 2235 } else if (formals.nonEmpty()) { 2236 t.supertype_field = subst(supertype, formals, actuals); 2237 } 2238 else { 2239 t.supertype_field = supertype; 2240 } 2241 } 2242 } 2243 return t.supertype_field; 2244 } 2245 2246 /** 2247 * The supertype is always a class type. If the type 2248 * variable's bounds start with a class type, this is also 2249 * the supertype. Otherwise, the supertype is 2250 * java.lang.Object. 2251 */ 2252 @Override 2253 public Type visitTypeVar(TypeVar t, Void ignored) { 2254 if (t.bound.hasTag(TYPEVAR) || 2255 (!t.bound.isCompound() && !t.bound.isInterface())) { 2256 return t.bound; 2257 } else { 2258 return supertype(t.bound); 2259 } 2260 } 2261 2262 @Override 2263 public Type visitArrayType(ArrayType t, Void ignored) { 2264 if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType)) 2265 return arraySuperType(); 2266 else 2267 return new ArrayType(supertype(t.elemtype), t.tsym); 2268 } 2269 2270 @Override 2271 public Type visitErrorType(ErrorType t, Void ignored) { 2272 return Type.noType; 2273 } 2274 }; 2275 // </editor-fold> 2276 2277 // <editor-fold defaultstate="collapsed" desc="interfaces"> 2278 /** 2279 * Return the interfaces implemented by this class. 2280 */ 2281 public List<Type> interfaces(Type t) { 2282 return interfaces.visit(t); 2283 } 2284 // where 2285 private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() { 2286 2287 public List<Type> visitType(Type t, Void ignored) { 2288 return List.nil(); 2289 } 2290 2291 @Override 2292 public List<Type> visitClassType(ClassType t, Void ignored) { 2293 if (t.interfaces_field == null) { 2294 List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces(); 2295 if (t.interfaces_field == null) { 2296 // If t.interfaces_field is null, then t must 2297 // be a parameterized type (not to be confused 2298 // with a generic type declaration). 2299 // Terminology: 2300 // Parameterized type: List<String> 2301 // Generic type declaration: class List<E> { ... } 2302 // So t corresponds to List<String> and 2303 // t.tsym.type corresponds to List<E>. 2304 // The reason t must be parameterized type is 2305 // that completion will happen as a side 2306 // effect of calling 2307 // ClassSymbol.getInterfaces. Since 2308 // t.interfaces_field is null after 2309 // completion, we can assume that t is not the 2310 // type of a class/interface declaration. 2311 Assert.check(t != t.tsym.type, t); 2312 List<Type> actuals = t.allparams(); 2313 List<Type> formals = t.tsym.type.allparams(); 2314 if (t.hasErasedSupertypes()) { 2315 t.interfaces_field = erasureRecursive(interfaces); 2316 } else if (formals.nonEmpty()) { 2317 t.interfaces_field = subst(interfaces, formals, actuals); 2318 } 2319 else { 2320 t.interfaces_field = interfaces; 2321 } 2322 } 2323 } 2324 return t.interfaces_field; 2325 } 2326 2327 @Override 2328 public List<Type> visitTypeVar(TypeVar t, Void ignored) { 2329 if (t.bound.isCompound()) 2330 return interfaces(t.bound); 2331 2332 if (t.bound.isInterface()) 2333 return List.of(t.bound); 2334 2335 return List.nil(); 2336 } 2337 }; 2338 2339 public List<Type> directSupertypes(Type t) { 2340 return directSupertypes.visit(t); 2341 } 2342 // where 2343 private final UnaryVisitor<List<Type>> directSupertypes = new UnaryVisitor<List<Type>>() { 2344 2345 public List<Type> visitType(final Type type, final Void ignored) { 2346 if (!type.isIntersection()) { 2347 final Type sup = supertype(type); 2348 return (sup == Type.noType || sup == type || sup == null) 2349 ? interfaces(type) 2350 : interfaces(type).prepend(sup); 2351 } else { 2352 return ((IntersectionClassType)type).getExplicitComponents(); 2353 } 2354 } 2355 }; 2356 2357 public boolean isDirectSuperInterface(TypeSymbol isym, TypeSymbol origin) { 2358 for (Type i2 : interfaces(origin.type)) { 2359 if (isym == i2.tsym) return true; 2360 } 2361 return false; 2362 } 2363 // </editor-fold> 2364 2365 // <editor-fold defaultstate="collapsed" desc="isDerivedRaw"> 2366 Map<Type,Boolean> isDerivedRawCache = new HashMap<>(); 2367 2368 public boolean isDerivedRaw(Type t) { 2369 Boolean result = isDerivedRawCache.get(t); 2370 if (result == null) { 2371 result = isDerivedRawInternal(t); 2372 isDerivedRawCache.put(t, result); 2373 } 2374 return result; 2375 } 2376 2377 public boolean isDerivedRawInternal(Type t) { 2378 if (t.isErroneous()) 2379 return false; 2380 return 2381 t.isRaw() || 2382 supertype(t) != Type.noType && isDerivedRaw(supertype(t)) || 2383 isDerivedRaw(interfaces(t)); 2384 } 2385 2386 public boolean isDerivedRaw(List<Type> ts) { 2387 List<Type> l = ts; 2388 while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail; 2389 return l.nonEmpty(); 2390 } 2391 // </editor-fold> 2392 2393 // <editor-fold defaultstate="collapsed" desc="setBounds"> 2394 /** 2395 * Same as {@link Types#setBounds(TypeVar, List, boolean)}, except that third parameter is computed directly, 2396 * as follows: if all all bounds are interface types, the computed supertype is Object,otherwise 2397 * the supertype is simply left null (in this case, the supertype is assumed to be the head of 2398 * the bound list passed as second argument). Note that this check might cause a symbol completion. 2399 * Hence, this version of setBounds may not be called during a classfile read. 2400 * 2401 * @param t a type variable 2402 * @param bounds the bounds, must be nonempty 2403 */ 2404 public void setBounds(TypeVar t, List<Type> bounds) { 2405 setBounds(t, bounds, bounds.head.tsym.isInterface()); 2406 } 2407 2408 /** 2409 * Set the bounds field of the given type variable to reflect a (possibly multiple) list of bounds. 2410 * This does not cause symbol completion as an extra parameter indicates as to whether all bounds 2411 * are interfaces - in which case the supertype is implicitly assumed to be 'Object'. 2412 * 2413 * @param t a type variable 2414 * @param bounds the bounds, must be nonempty 2415 * @param allInterfaces are all bounds interface types? 2416 */ 2417 public void setBounds(TypeVar t, List<Type> bounds, boolean allInterfaces) { 2418 t.bound = bounds.tail.isEmpty() ? 2419 bounds.head : 2420 makeIntersectionType(bounds, allInterfaces); 2421 t.rank_field = -1; 2422 } 2423 // </editor-fold> 2424 2425 // <editor-fold defaultstate="collapsed" desc="getBounds"> 2426 /** 2427 * Return list of bounds of the given type variable. 2428 */ 2429 public List<Type> getBounds(TypeVar t) { 2430 if (t.bound.hasTag(NONE)) 2431 return List.nil(); 2432 else if (t.bound.isErroneous() || !t.bound.isCompound()) 2433 return List.of(t.bound); 2434 else if ((erasure(t).tsym.flags() & INTERFACE) == 0) 2435 return interfaces(t).prepend(supertype(t)); 2436 else 2437 // No superclass was given in bounds. 2438 // In this case, supertype is Object, erasure is first interface. 2439 return interfaces(t); 2440 } 2441 // </editor-fold> 2442 2443 // <editor-fold defaultstate="collapsed" desc="classBound"> 2444 /** 2445 * If the given type is a (possibly selected) type variable, 2446 * return the bounding class of this type, otherwise return the 2447 * type itself. 2448 */ 2449 public Type classBound(Type t) { 2450 return classBound.visit(t); 2451 } 2452 // where 2453 private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() { 2454 2455 public Type visitType(Type t, Void ignored) { 2456 return t; 2457 } 2458 2459 @Override 2460 public Type visitClassType(ClassType t, Void ignored) { 2461 Type outer1 = classBound(t.getEnclosingType()); 2462 if (outer1 != t.getEnclosingType()) 2463 return new ClassType(outer1, t.getTypeArguments(), t.tsym, 2464 t.getMetadata()); 2465 else 2466 return t; 2467 } 2468 2469 @Override 2470 public Type visitTypeVar(TypeVar t, Void ignored) { 2471 return classBound(supertype(t)); 2472 } 2473 2474 @Override 2475 public Type visitErrorType(ErrorType t, Void ignored) { 2476 return t; 2477 } 2478 }; 2479 // </editor-fold> 2480 2481 // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence"> 2482 /** 2483 * Returns true iff the first signature is a <em>sub 2484 * signature</em> of the other. This is <b>not</b> an equivalence 2485 * relation. 2486 * 2487 * @jls section 8.4.2. 2488 * @see #overrideEquivalent(Type t, Type s) 2489 * @param t first signature (possibly raw). 2490 * @param s second signature (could be subjected to erasure). 2491 * @return true if t is a sub signature of s. 2492 */ 2493 public boolean isSubSignature(Type t, Type s) { 2494 return isSubSignature(t, s, true); 2495 } 2496 2497 public boolean isSubSignature(Type t, Type s, boolean strict) { 2498 return hasSameArgs(t, s, strict) || hasSameArgs(t, erasure(s), strict); 2499 } 2500 2501 /** 2502 * Returns true iff these signatures are related by <em>override 2503 * equivalence</em>. This is the natural extension of 2504 * isSubSignature to an equivalence relation. 2505 * 2506 * @jls section 8.4.2. 2507 * @see #isSubSignature(Type t, Type s) 2508 * @param t a signature (possible raw, could be subjected to 2509 * erasure). 2510 * @param s a signature (possible raw, could be subjected to 2511 * erasure). 2512 * @return true if either argument is a sub signature of the other. 2513 */ 2514 public boolean overrideEquivalent(Type t, Type s) { 2515 return hasSameArgs(t, s) || 2516 hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s); 2517 } 2518 2519 public boolean overridesObjectMethod(TypeSymbol origin, Symbol msym) { 2520 for (Symbol sym : syms.objectType.tsym.members().getSymbolsByName(msym.name)) { 2521 if (msym.overrides(sym, origin, Types.this, true)) { 2522 return true; 2523 } 2524 } 2525 return false; 2526 } 2527 2528 /** 2529 * This enum defines the strategy for implementing most specific return type check 2530 * during the most specific and functional interface checks. 2531 */ 2532 public enum MostSpecificReturnCheck { 2533 /** 2534 * Return r1 is more specific than r2 if {@code r1 <: r2}. Extra care required for (i) handling 2535 * method type variables (if either method is generic) and (ii) subtyping should be replaced 2536 * by type-equivalence for primitives. This is essentially an inlined version of 2537 * {@link Types#resultSubtype(Type, Type, Warner)}, where the assignability check has been 2538 * replaced with a strict subtyping check. 2539 */ 2540 BASIC() { 2541 @Override 2542 public boolean test(Type mt1, Type mt2, Types types) { 2543 List<Type> tvars = mt1.getTypeArguments(); 2544 List<Type> svars = mt2.getTypeArguments(); 2545 Type t = mt1.getReturnType(); 2546 Type s = types.subst(mt2.getReturnType(), svars, tvars); 2547 return types.isSameType(t, s) || 2548 !t.isPrimitive() && 2549 !s.isPrimitive() && 2550 types.isSubtype(t, s); 2551 } 2552 }, 2553 /** 2554 * Return r1 is more specific than r2 if r1 is return-type-substitutable for r2. 2555 */ 2556 RTS() { 2557 @Override 2558 public boolean test(Type mt1, Type mt2, Types types) { 2559 return types.returnTypeSubstitutable(mt1, mt2); 2560 } 2561 }; 2562 2563 public abstract boolean test(Type mt1, Type mt2, Types types); 2564 } 2565 2566 /** 2567 * Merge multiple abstract methods. The preferred method is a method that is a subsignature 2568 * of all the other signatures and whose return type is more specific {@see MostSpecificReturnCheck}. 2569 * The resulting preferred method has a thrown clause that is the intersection of the merged 2570 * methods' clauses. 2571 */ 2572 public Optional<Symbol> mergeAbstracts(List<Symbol> ambiguousInOrder, Type site, boolean sigCheck) { 2573 //first check for preconditions 2574 boolean shouldErase = false; 2575 List<Type> erasedParams = ambiguousInOrder.head.erasure(this).getParameterTypes(); 2576 for (Symbol s : ambiguousInOrder) { 2577 if ((s.flags() & ABSTRACT) == 0 || 2578 (sigCheck && !isSameTypes(erasedParams, s.erasure(this).getParameterTypes()))) { 2579 return Optional.empty(); 2580 } else if (s.type.hasTag(FORALL)) { 2581 shouldErase = true; 2582 } 2583 } 2584 //then merge abstracts 2585 for (MostSpecificReturnCheck mostSpecificReturnCheck : MostSpecificReturnCheck.values()) { 2586 outer: for (Symbol s : ambiguousInOrder) { 2587 Type mt = memberType(site, s); 2588 List<Type> allThrown = mt.getThrownTypes(); 2589 for (Symbol s2 : ambiguousInOrder) { 2590 if (s != s2) { 2591 Type mt2 = memberType(site, s2); 2592 if (!isSubSignature(mt, mt2) || 2593 !mostSpecificReturnCheck.test(mt, mt2, this)) { 2594 //ambiguity cannot be resolved 2595 continue outer; 2596 } else { 2597 List<Type> thrownTypes2 = mt2.getThrownTypes(); 2598 if (!mt.hasTag(FORALL) && shouldErase) { 2599 thrownTypes2 = erasure(thrownTypes2); 2600 } else if (mt.hasTag(FORALL)) { 2601 //subsignature implies that if most specific is generic, then all other 2602 //methods are too 2603 Assert.check(mt2.hasTag(FORALL)); 2604 // if both are generic methods, adjust thrown types ahead of intersection computation 2605 thrownTypes2 = subst(thrownTypes2, mt2.getTypeArguments(), mt.getTypeArguments()); 2606 } 2607 allThrown = chk.intersect(allThrown, thrownTypes2); 2608 } 2609 } 2610 } 2611 return (allThrown == mt.getThrownTypes()) ? 2612 Optional.of(s) : 2613 Optional.of(new MethodSymbol( 2614 s.flags(), 2615 s.name, 2616 createMethodTypeWithThrown(s.type, allThrown), 2617 s.owner) { 2618 @Override 2619 public Symbol baseSymbol() { 2620 return s; 2621 } 2622 }); 2623 } 2624 } 2625 return Optional.empty(); 2626 } 2627 2628 // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site"> 2629 class ImplementationCache { 2630 2631 private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>> _map = new WeakHashMap<>(); 2632 2633 class Entry { 2634 final MethodSymbol cachedImpl; 2635 final Filter<Symbol> implFilter; 2636 final boolean checkResult; 2637 final int prevMark; 2638 2639 public Entry(MethodSymbol cachedImpl, 2640 Filter<Symbol> scopeFilter, 2641 boolean checkResult, 2642 int prevMark) { 2643 this.cachedImpl = cachedImpl; 2644 this.implFilter = scopeFilter; 2645 this.checkResult = checkResult; 2646 this.prevMark = prevMark; 2647 } 2648 2649 boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, int mark) { 2650 return this.implFilter == scopeFilter && 2651 this.checkResult == checkResult && 2652 this.prevMark == mark; 2653 } 2654 } 2655 2656 MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) { 2657 SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms); 2658 Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null; 2659 if (cache == null) { 2660 cache = new HashMap<>(); 2661 _map.put(ms, new SoftReference<>(cache)); 2662 } 2663 Entry e = cache.get(origin); 2664 CompoundScope members = membersClosure(origin.type, true); 2665 if (e == null || 2666 !e.matches(implFilter, checkResult, members.getMark())) { 2667 MethodSymbol impl = implementationInternal(ms, origin, checkResult, implFilter); 2668 cache.put(origin, new Entry(impl, implFilter, checkResult, members.getMark())); 2669 return impl; 2670 } 2671 else { 2672 return e.cachedImpl; 2673 } 2674 } 2675 2676 private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) { 2677 for (Type t = origin.type; t.hasTag(CLASS) || t.hasTag(TYPEVAR); t = supertype(t)) { 2678 t = skipTypeVars(t, false); 2679 TypeSymbol c = t.tsym; 2680 Symbol bestSoFar = null; 2681 for (Symbol sym : c.members().getSymbolsByName(ms.name, implFilter)) { 2682 if (sym != null && sym.overrides(ms, origin, Types.this, checkResult)) { 2683 bestSoFar = sym; 2684 if ((sym.flags() & ABSTRACT) == 0) { 2685 //if concrete impl is found, exit immediately 2686 break; 2687 } 2688 } 2689 } 2690 if (bestSoFar != null) { 2691 //return either the (only) concrete implementation or the first abstract one 2692 return (MethodSymbol)bestSoFar; 2693 } 2694 } 2695 return null; 2696 } 2697 } 2698 2699 private ImplementationCache implCache = new ImplementationCache(); 2700 2701 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) { 2702 return implCache.get(ms, origin, checkResult, implFilter); 2703 } 2704 // </editor-fold> 2705 2706 // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site"> 2707 class MembersClosureCache extends SimpleVisitor<Scope.CompoundScope, Void> { 2708 2709 private Map<TypeSymbol, CompoundScope> _map = new HashMap<>(); 2710 2711 Set<TypeSymbol> seenTypes = new HashSet<>(); 2712 2713 class MembersScope extends CompoundScope { 2714 2715 CompoundScope scope; 2716 2717 public MembersScope(CompoundScope scope) { 2718 super(scope.owner); 2719 this.scope = scope; 2720 } 2721 2722 Filter<Symbol> combine(Filter<Symbol> sf) { 2723 return s -> !s.owner.isInterface() && (sf == null || sf.accepts(s)); 2724 } 2725 2726 @Override 2727 public Iterable<Symbol> getSymbols(Filter<Symbol> sf, LookupKind lookupKind) { 2728 return scope.getSymbols(combine(sf), lookupKind); 2729 } 2730 2731 @Override 2732 public Iterable<Symbol> getSymbolsByName(Name name, Filter<Symbol> sf, LookupKind lookupKind) { 2733 return scope.getSymbolsByName(name, combine(sf), lookupKind); 2734 } 2735 2736 @Override 2737 public int getMark() { 2738 return scope.getMark(); 2739 } 2740 } 2741 2742 CompoundScope nilScope; 2743 2744 /** members closure visitor methods **/ 2745 2746 public CompoundScope visitType(Type t, Void _unused) { 2747 if (nilScope == null) { 2748 nilScope = new CompoundScope(syms.noSymbol); 2749 } 2750 return nilScope; 2751 } 2752 2753 @Override 2754 public CompoundScope visitClassType(ClassType t, Void _unused) { 2755 if (!seenTypes.add(t.tsym)) { 2756 //this is possible when an interface is implemented in multiple 2757 //superclasses, or when a class hierarchy is circular - in such 2758 //cases we don't need to recurse (empty scope is returned) 2759 return new CompoundScope(t.tsym); 2760 } 2761 try { 2762 seenTypes.add(t.tsym); 2763 ClassSymbol csym = (ClassSymbol)t.tsym; 2764 CompoundScope membersClosure = _map.get(csym); 2765 if (membersClosure == null) { 2766 membersClosure = new CompoundScope(csym); 2767 for (Type i : interfaces(t)) { 2768 membersClosure.prependSubScope(visit(i, null)); 2769 } 2770 membersClosure.prependSubScope(visit(supertype(t), null)); 2771 membersClosure.prependSubScope(csym.members()); 2772 _map.put(csym, membersClosure); 2773 } 2774 return membersClosure; 2775 } 2776 finally { 2777 seenTypes.remove(t.tsym); 2778 } 2779 } 2780 2781 @Override 2782 public CompoundScope visitTypeVar(TypeVar t, Void _unused) { 2783 return visit(t.getUpperBound(), null); 2784 } 2785 } 2786 2787 private MembersClosureCache membersCache = new MembersClosureCache(); 2788 2789 public CompoundScope membersClosure(Type site, boolean skipInterface) { 2790 CompoundScope cs = membersCache.visit(site, null); 2791 Assert.checkNonNull(cs, () -> "type " + site); 2792 return skipInterface ? membersCache.new MembersScope(cs) : cs; 2793 } 2794 // </editor-fold> 2795 2796 2797 /** Return first abstract member of class `sym'. 2798 */ 2799 public MethodSymbol firstUnimplementedAbstract(ClassSymbol sym) { 2800 try { 2801 return firstUnimplementedAbstractImpl(sym, sym); 2802 } catch (CompletionFailure ex) { 2803 chk.completionError(enter.getEnv(sym).tree.pos(), ex); 2804 return null; 2805 } 2806 } 2807 //where: 2808 private MethodSymbol firstUnimplementedAbstractImpl(ClassSymbol impl, ClassSymbol c) { 2809 MethodSymbol undef = null; 2810 // Do not bother to search in classes that are not abstract, 2811 // since they cannot have abstract members. 2812 if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) { 2813 Scope s = c.members(); 2814 for (Symbol sym : s.getSymbols(NON_RECURSIVE)) { 2815 if (sym.kind == MTH && 2816 (sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) { 2817 MethodSymbol absmeth = (MethodSymbol)sym; 2818 MethodSymbol implmeth = absmeth.implementation(impl, this, true); 2819 if (implmeth == null || implmeth == absmeth) { 2820 //look for default implementations 2821 if (allowDefaultMethods) { 2822 MethodSymbol prov = interfaceCandidates(impl.type, absmeth).head; 2823 if (prov != null && prov.overrides(absmeth, impl, this, true)) { 2824 implmeth = prov; 2825 } 2826 } 2827 } 2828 if (implmeth == null || implmeth == absmeth) { 2829 undef = absmeth; 2830 break; 2831 } 2832 } 2833 } 2834 if (undef == null) { 2835 Type st = supertype(c.type); 2836 if (st.hasTag(CLASS)) 2837 undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)st.tsym); 2838 } 2839 for (List<Type> l = interfaces(c.type); 2840 undef == null && l.nonEmpty(); 2841 l = l.tail) { 2842 undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)l.head.tsym); 2843 } 2844 } 2845 return undef; 2846 } 2847 2848 public class CandidatesCache { 2849 public Map<Entry, List<MethodSymbol>> cache = new WeakHashMap<>(); 2850 2851 class Entry { 2852 Type site; 2853 MethodSymbol msym; 2854 2855 Entry(Type site, MethodSymbol msym) { 2856 this.site = site; 2857 this.msym = msym; 2858 } 2859 2860 @Override 2861 public boolean equals(Object obj) { 2862 if (obj instanceof Entry) { 2863 Entry e = (Entry)obj; 2864 return e.msym == msym && isSameType(site, e.site); 2865 } else { 2866 return false; 2867 } 2868 } 2869 2870 @Override 2871 public int hashCode() { 2872 return Types.this.hashCode(site) & ~msym.hashCode(); 2873 } 2874 } 2875 2876 public List<MethodSymbol> get(Entry e) { 2877 return cache.get(e); 2878 } 2879 2880 public void put(Entry e, List<MethodSymbol> msymbols) { 2881 cache.put(e, msymbols); 2882 } 2883 } 2884 2885 public CandidatesCache candidatesCache = new CandidatesCache(); 2886 2887 //where 2888 public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) { 2889 CandidatesCache.Entry e = candidatesCache.new Entry(site, ms); 2890 List<MethodSymbol> candidates = candidatesCache.get(e); 2891 if (candidates == null) { 2892 Filter<Symbol> filter = new MethodFilter(ms, site); 2893 List<MethodSymbol> candidates2 = List.nil(); 2894 for (Symbol s : membersClosure(site, false).getSymbols(filter)) { 2895 if (!site.tsym.isInterface() && !s.owner.isInterface()) { 2896 return List.of((MethodSymbol)s); 2897 } else if (!candidates2.contains(s)) { 2898 candidates2 = candidates2.prepend((MethodSymbol)s); 2899 } 2900 } 2901 candidates = prune(candidates2); 2902 candidatesCache.put(e, candidates); 2903 } 2904 return candidates; 2905 } 2906 2907 public List<MethodSymbol> prune(List<MethodSymbol> methods) { 2908 ListBuffer<MethodSymbol> methodsMin = new ListBuffer<>(); 2909 for (MethodSymbol m1 : methods) { 2910 boolean isMin_m1 = true; 2911 for (MethodSymbol m2 : methods) { 2912 if (m1 == m2) continue; 2913 if (m2.owner != m1.owner && 2914 asSuper(m2.owner.type, m1.owner) != null) { 2915 isMin_m1 = false; 2916 break; 2917 } 2918 } 2919 if (isMin_m1) 2920 methodsMin.append(m1); 2921 } 2922 return methodsMin.toList(); 2923 } 2924 // where 2925 private class MethodFilter implements Filter<Symbol> { 2926 2927 Symbol msym; 2928 Type site; 2929 2930 MethodFilter(Symbol msym, Type site) { 2931 this.msym = msym; 2932 this.site = site; 2933 } 2934 2935 public boolean accepts(Symbol s) { 2936 return s.kind == MTH && 2937 s.name == msym.name && 2938 (s.flags() & SYNTHETIC) == 0 && 2939 s.isInheritedIn(site.tsym, Types.this) && 2940 overrideEquivalent(memberType(site, s), memberType(site, msym)); 2941 } 2942 } 2943 // </editor-fold> 2944 2945 /** 2946 * Does t have the same arguments as s? It is assumed that both 2947 * types are (possibly polymorphic) method types. Monomorphic 2948 * method types "have the same arguments", if their argument lists 2949 * are equal. Polymorphic method types "have the same arguments", 2950 * if they have the same arguments after renaming all type 2951 * variables of one to corresponding type variables in the other, 2952 * where correspondence is by position in the type parameter list. 2953 */ 2954 public boolean hasSameArgs(Type t, Type s) { 2955 return hasSameArgs(t, s, true); 2956 } 2957 2958 public boolean hasSameArgs(Type t, Type s, boolean strict) { 2959 return hasSameArgs(t, s, strict ? hasSameArgs_strict : hasSameArgs_nonstrict); 2960 } 2961 2962 private boolean hasSameArgs(Type t, Type s, TypeRelation hasSameArgs) { 2963 return hasSameArgs.visit(t, s); 2964 } 2965 // where 2966 private class HasSameArgs extends TypeRelation { 2967 2968 boolean strict; 2969 2970 public HasSameArgs(boolean strict) { 2971 this.strict = strict; 2972 } 2973 2974 public Boolean visitType(Type t, Type s) { 2975 throw new AssertionError(); 2976 } 2977 2978 @Override 2979 public Boolean visitMethodType(MethodType t, Type s) { 2980 return s.hasTag(METHOD) 2981 && containsTypeEquivalent(t.argtypes, s.getParameterTypes()); 2982 } 2983 2984 @Override 2985 public Boolean visitForAll(ForAll t, Type s) { 2986 if (!s.hasTag(FORALL)) 2987 return strict ? false : visitMethodType(t.asMethodType(), s); 2988 2989 ForAll forAll = (ForAll)s; 2990 return hasSameBounds(t, forAll) 2991 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars)); 2992 } 2993 2994 @Override 2995 public Boolean visitErrorType(ErrorType t, Type s) { 2996 return false; 2997 } 2998 } 2999 3000 TypeRelation hasSameArgs_strict = new HasSameArgs(true); 3001 TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false); 3002 3003 // </editor-fold> 3004 3005 // <editor-fold defaultstate="collapsed" desc="subst"> 3006 public List<Type> subst(List<Type> ts, 3007 List<Type> from, 3008 List<Type> to) { 3009 return ts.map(new Subst(from, to)); 3010 } 3011 3012 /** 3013 * Substitute all occurrences of a type in `from' with the 3014 * corresponding type in `to' in 't'. Match lists `from' and `to' 3015 * from the right: If lists have different length, discard leading 3016 * elements of the longer list. 3017 */ 3018 public Type subst(Type t, List<Type> from, List<Type> to) { 3019 return t.map(new Subst(from, to)); 3020 } 3021 3022 private class Subst extends TypeMapping<Void> { 3023 List<Type> from; 3024 List<Type> to; 3025 3026 public Subst(List<Type> from, List<Type> to) { 3027 int fromLength = from.length(); 3028 int toLength = to.length(); 3029 while (fromLength > toLength) { 3030 fromLength--; 3031 from = from.tail; 3032 } 3033 while (fromLength < toLength) { 3034 toLength--; 3035 to = to.tail; 3036 } 3037 this.from = from; 3038 this.to = to; 3039 } 3040 3041 @Override 3042 public Type visitTypeVar(TypeVar t, Void ignored) { 3043 for (List<Type> from = this.from, to = this.to; 3044 from.nonEmpty(); 3045 from = from.tail, to = to.tail) { 3046 if (t.equalsIgnoreMetadata(from.head)) { 3047 return to.head.withTypeVar(t); 3048 } 3049 } 3050 return t; 3051 } 3052 3053 @Override 3054 public Type visitClassType(ClassType t, Void ignored) { 3055 if (!t.isCompound()) { 3056 return super.visitClassType(t, ignored); 3057 } else { 3058 Type st = visit(supertype(t)); 3059 List<Type> is = visit(interfaces(t), ignored); 3060 if (st == supertype(t) && is == interfaces(t)) 3061 return t; 3062 else 3063 return makeIntersectionType(is.prepend(st)); 3064 } 3065 } 3066 3067 @Override 3068 public Type visitWildcardType(WildcardType t, Void ignored) { 3069 WildcardType t2 = (WildcardType)super.visitWildcardType(t, ignored); 3070 if (t2 != t && t.isExtendsBound() && t2.type.isExtendsBound()) { 3071 t2.type = wildUpperBound(t2.type); 3072 } 3073 return t2; 3074 } 3075 3076 @Override 3077 public Type visitForAll(ForAll t, Void ignored) { 3078 if (Type.containsAny(to, t.tvars)) { 3079 //perform alpha-renaming of free-variables in 't' 3080 //if 'to' types contain variables that are free in 't' 3081 List<Type> freevars = newInstances(t.tvars); 3082 t = new ForAll(freevars, 3083 Types.this.subst(t.qtype, t.tvars, freevars)); 3084 } 3085 List<Type> tvars1 = substBounds(t.tvars, from, to); 3086 Type qtype1 = visit(t.qtype); 3087 if (tvars1 == t.tvars && qtype1 == t.qtype) { 3088 return t; 3089 } else if (tvars1 == t.tvars) { 3090 return new ForAll(tvars1, qtype1) { 3091 @Override 3092 public boolean needsStripping() { 3093 return true; 3094 } 3095 }; 3096 } else { 3097 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1)) { 3098 @Override 3099 public boolean needsStripping() { 3100 return true; 3101 } 3102 }; 3103 } 3104 } 3105 } 3106 3107 public List<Type> substBounds(List<Type> tvars, 3108 List<Type> from, 3109 List<Type> to) { 3110 if (tvars.isEmpty()) 3111 return tvars; 3112 ListBuffer<Type> newBoundsBuf = new ListBuffer<>(); 3113 boolean changed = false; 3114 // calculate new bounds 3115 for (Type t : tvars) { 3116 TypeVar tv = (TypeVar) t; 3117 Type bound = subst(tv.bound, from, to); 3118 if (bound != tv.bound) 3119 changed = true; 3120 newBoundsBuf.append(bound); 3121 } 3122 if (!changed) 3123 return tvars; 3124 ListBuffer<Type> newTvars = new ListBuffer<>(); 3125 // create new type variables without bounds 3126 for (Type t : tvars) { 3127 newTvars.append(new TypeVar(t.tsym, null, syms.botType, 3128 t.getMetadata())); 3129 } 3130 // the new bounds should use the new type variables in place 3131 // of the old 3132 List<Type> newBounds = newBoundsBuf.toList(); 3133 from = tvars; 3134 to = newTvars.toList(); 3135 for (; !newBounds.isEmpty(); newBounds = newBounds.tail) { 3136 newBounds.head = subst(newBounds.head, from, to); 3137 } 3138 newBounds = newBoundsBuf.toList(); 3139 // set the bounds of new type variables to the new bounds 3140 for (Type t : newTvars.toList()) { 3141 TypeVar tv = (TypeVar) t; 3142 tv.bound = newBounds.head; 3143 newBounds = newBounds.tail; 3144 } 3145 return newTvars.toList(); 3146 } 3147 3148 public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) { 3149 Type bound1 = subst(t.bound, from, to); 3150 if (bound1 == t.bound) 3151 return t; 3152 else { 3153 // create new type variable without bounds 3154 TypeVar tv = new TypeVar(t.tsym, null, syms.botType, 3155 t.getMetadata()); 3156 // the new bound should use the new type variable in place 3157 // of the old 3158 tv.bound = subst(bound1, List.of(t), List.of(tv)); 3159 return tv; 3160 } 3161 } 3162 // </editor-fold> 3163 3164 // <editor-fold defaultstate="collapsed" desc="hasSameBounds"> 3165 /** 3166 * Does t have the same bounds for quantified variables as s? 3167 */ 3168 public boolean hasSameBounds(ForAll t, ForAll s) { 3169 List<Type> l1 = t.tvars; 3170 List<Type> l2 = s.tvars; 3171 while (l1.nonEmpty() && l2.nonEmpty() && 3172 isSameType(l1.head.getUpperBound(), 3173 subst(l2.head.getUpperBound(), 3174 s.tvars, 3175 t.tvars))) { 3176 l1 = l1.tail; 3177 l2 = l2.tail; 3178 } 3179 return l1.isEmpty() && l2.isEmpty(); 3180 } 3181 // </editor-fold> 3182 3183 // <editor-fold defaultstate="collapsed" desc="newInstances"> 3184 /** Create new vector of type variables from list of variables 3185 * changing all recursive bounds from old to new list. 3186 */ 3187 public List<Type> newInstances(List<Type> tvars) { 3188 List<Type> tvars1 = tvars.map(newInstanceFun); 3189 for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) { 3190 TypeVar tv = (TypeVar) l.head; 3191 tv.bound = subst(tv.bound, tvars, tvars1); 3192 } 3193 return tvars1; 3194 } 3195 private static final TypeMapping<Void> newInstanceFun = new TypeMapping<Void>() { 3196 @Override 3197 public TypeVar visitTypeVar(TypeVar t, Void _unused) { 3198 return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getMetadata()); 3199 } 3200 }; 3201 // </editor-fold> 3202 3203 public Type createMethodTypeWithParameters(Type original, List<Type> newParams) { 3204 return original.accept(methodWithParameters, newParams); 3205 } 3206 // where 3207 private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() { 3208 public Type visitType(Type t, List<Type> newParams) { 3209 throw new IllegalArgumentException("Not a method type: " + t); 3210 } 3211 public Type visitMethodType(MethodType t, List<Type> newParams) { 3212 return new MethodType(newParams, t.restype, t.thrown, t.tsym); 3213 } 3214 public Type visitForAll(ForAll t, List<Type> newParams) { 3215 return new ForAll(t.tvars, t.qtype.accept(this, newParams)); 3216 } 3217 }; 3218 3219 public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) { 3220 return original.accept(methodWithThrown, newThrown); 3221 } 3222 // where 3223 private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() { 3224 public Type visitType(Type t, List<Type> newThrown) { 3225 throw new IllegalArgumentException("Not a method type: " + t); 3226 } 3227 public Type visitMethodType(MethodType t, List<Type> newThrown) { 3228 return new MethodType(t.argtypes, t.restype, newThrown, t.tsym); 3229 } 3230 public Type visitForAll(ForAll t, List<Type> newThrown) { 3231 return new ForAll(t.tvars, t.qtype.accept(this, newThrown)); 3232 } 3233 }; 3234 3235 public Type createMethodTypeWithReturn(Type original, Type newReturn) { 3236 return original.accept(methodWithReturn, newReturn); 3237 } 3238 // where 3239 private final MapVisitor<Type> methodWithReturn = new MapVisitor<Type>() { 3240 public Type visitType(Type t, Type newReturn) { 3241 throw new IllegalArgumentException("Not a method type: " + t); 3242 } 3243 public Type visitMethodType(MethodType t, Type newReturn) { 3244 return new MethodType(t.argtypes, newReturn, t.thrown, t.tsym) { 3245 @Override 3246 public Type baseType() { 3247 return t; 3248 } 3249 }; 3250 } 3251 public Type visitForAll(ForAll t, Type newReturn) { 3252 return new ForAll(t.tvars, t.qtype.accept(this, newReturn)) { 3253 @Override 3254 public Type baseType() { 3255 return t; 3256 } 3257 }; 3258 } 3259 }; 3260 3261 // <editor-fold defaultstate="collapsed" desc="createErrorType"> 3262 public Type createErrorType(Type originalType) { 3263 return new ErrorType(originalType, syms.errSymbol); 3264 } 3265 3266 public Type createErrorType(ClassSymbol c, Type originalType) { 3267 return new ErrorType(c, originalType); 3268 } 3269 3270 public Type createErrorType(Name name, TypeSymbol container, Type originalType) { 3271 return new ErrorType(name, container, originalType); 3272 } 3273 // </editor-fold> 3274 3275 // <editor-fold defaultstate="collapsed" desc="rank"> 3276 /** 3277 * The rank of a class is the length of the longest path between 3278 * the class and java.lang.Object in the class inheritance 3279 * graph. Undefined for all but reference types. 3280 */ 3281 public int rank(Type t) { 3282 switch(t.getTag()) { 3283 case CLASS: { 3284 ClassType cls = (ClassType)t; 3285 if (cls.rank_field < 0) { 3286 Name fullname = cls.tsym.getQualifiedName(); 3287 if (fullname == names.java_lang_Object) 3288 cls.rank_field = 0; 3289 else { 3290 int r = rank(supertype(cls)); 3291 for (List<Type> l = interfaces(cls); 3292 l.nonEmpty(); 3293 l = l.tail) { 3294 if (rank(l.head) > r) 3295 r = rank(l.head); 3296 } 3297 cls.rank_field = r + 1; 3298 } 3299 } 3300 return cls.rank_field; 3301 } 3302 case TYPEVAR: { 3303 TypeVar tvar = (TypeVar)t; 3304 if (tvar.rank_field < 0) { 3305 int r = rank(supertype(tvar)); 3306 for (List<Type> l = interfaces(tvar); 3307 l.nonEmpty(); 3308 l = l.tail) { 3309 if (rank(l.head) > r) r = rank(l.head); 3310 } 3311 tvar.rank_field = r + 1; 3312 } 3313 return tvar.rank_field; 3314 } 3315 case ERROR: 3316 case NONE: 3317 return 0; 3318 default: 3319 throw new AssertionError(); 3320 } 3321 } 3322 // </editor-fold> 3323 3324 /** 3325 * Helper method for generating a string representation of a given type 3326 * accordingly to a given locale 3327 */ 3328 public String toString(Type t, Locale locale) { 3329 return Printer.createStandardPrinter(messages).visit(t, locale); 3330 } 3331 3332 /** 3333 * Helper method for generating a string representation of a given type 3334 * accordingly to a given locale 3335 */ 3336 public String toString(Symbol t, Locale locale) { 3337 return Printer.createStandardPrinter(messages).visit(t, locale); 3338 } 3339 3340 // <editor-fold defaultstate="collapsed" desc="toString"> 3341 /** 3342 * This toString is slightly more descriptive than the one on Type. 3343 * 3344 * @deprecated Types.toString(Type t, Locale l) provides better support 3345 * for localization 3346 */ 3347 @Deprecated 3348 public String toString(Type t) { 3349 if (t.hasTag(FORALL)) { 3350 ForAll forAll = (ForAll)t; 3351 return typaramsString(forAll.tvars) + forAll.qtype; 3352 } 3353 return "" + t; 3354 } 3355 // where 3356 private String typaramsString(List<Type> tvars) { 3357 StringBuilder s = new StringBuilder(); 3358 s.append('<'); 3359 boolean first = true; 3360 for (Type t : tvars) { 3361 if (!first) s.append(", "); 3362 first = false; 3363 appendTyparamString(((TypeVar)t), s); 3364 } 3365 s.append('>'); 3366 return s.toString(); 3367 } 3368 private void appendTyparamString(TypeVar t, StringBuilder buf) { 3369 buf.append(t); 3370 if (t.bound == null || 3371 t.bound.tsym.getQualifiedName() == names.java_lang_Object) 3372 return; 3373 buf.append(" extends "); // Java syntax; no need for i18n 3374 Type bound = t.bound; 3375 if (!bound.isCompound()) { 3376 buf.append(bound); 3377 } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) { 3378 buf.append(supertype(t)); 3379 for (Type intf : interfaces(t)) { 3380 buf.append('&'); 3381 buf.append(intf); 3382 } 3383 } else { 3384 // No superclass was given in bounds. 3385 // In this case, supertype is Object, erasure is first interface. 3386 boolean first = true; 3387 for (Type intf : interfaces(t)) { 3388 if (!first) buf.append('&'); 3389 first = false; 3390 buf.append(intf); 3391 } 3392 } 3393 } 3394 // </editor-fold> 3395 3396 // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types"> 3397 /** 3398 * A cache for closures. 3399 * 3400 * <p>A closure is a list of all the supertypes and interfaces of 3401 * a class or interface type, ordered by ClassSymbol.precedes 3402 * (that is, subclasses come first, arbitrary but fixed 3403 * otherwise). 3404 */ 3405 private Map<Type,List<Type>> closureCache = new HashMap<>(); 3406 3407 /** 3408 * Returns the closure of a class or interface type. 3409 */ 3410 public List<Type> closure(Type t) { 3411 List<Type> cl = closureCache.get(t); 3412 if (cl == null) { 3413 Type st = supertype(t); 3414 if (!t.isCompound()) { 3415 if (st.hasTag(CLASS)) { 3416 cl = insert(closure(st), t); 3417 } else if (st.hasTag(TYPEVAR)) { 3418 cl = closure(st).prepend(t); 3419 } else { 3420 cl = List.of(t); 3421 } 3422 } else { 3423 cl = closure(supertype(t)); 3424 } 3425 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) 3426 cl = union(cl, closure(l.head)); 3427 closureCache.put(t, cl); 3428 } 3429 return cl; 3430 } 3431 3432 /** 3433 * Collect types into a new closure (using a @code{ClosureHolder}) 3434 */ 3435 public Collector<Type, ClosureHolder, List<Type>> closureCollector(boolean minClosure, BiPredicate<Type, Type> shouldSkip) { 3436 return Collector.of(() -> new ClosureHolder(minClosure, shouldSkip), 3437 ClosureHolder::add, 3438 ClosureHolder::merge, 3439 ClosureHolder::closure); 3440 } 3441 //where 3442 class ClosureHolder { 3443 List<Type> closure; 3444 final boolean minClosure; 3445 final BiPredicate<Type, Type> shouldSkip; 3446 3447 ClosureHolder(boolean minClosure, BiPredicate<Type, Type> shouldSkip) { 3448 this.closure = List.nil(); 3449 this.minClosure = minClosure; 3450 this.shouldSkip = shouldSkip; 3451 } 3452 3453 void add(Type type) { 3454 closure = insert(closure, type, shouldSkip); 3455 } 3456 3457 ClosureHolder merge(ClosureHolder other) { 3458 closure = union(closure, other.closure, shouldSkip); 3459 return this; 3460 } 3461 3462 List<Type> closure() { 3463 return minClosure ? closureMin(closure) : closure; 3464 } 3465 } 3466 3467 BiPredicate<Type, Type> basicClosureSkip = (t1, t2) -> t1.tsym == t2.tsym; 3468 3469 /** 3470 * Insert a type in a closure 3471 */ 3472 public List<Type> insert(List<Type> cl, Type t, BiPredicate<Type, Type> shouldSkip) { 3473 if (cl.isEmpty()) { 3474 return cl.prepend(t); 3475 } else if (shouldSkip.test(t, cl.head)) { 3476 return cl; 3477 } else if (t.tsym.precedes(cl.head.tsym, this)) { 3478 return cl.prepend(t); 3479 } else { 3480 // t comes after head, or the two are unrelated 3481 return insert(cl.tail, t, shouldSkip).prepend(cl.head); 3482 } 3483 } 3484 3485 public List<Type> insert(List<Type> cl, Type t) { 3486 return insert(cl, t, basicClosureSkip); 3487 } 3488 3489 /** 3490 * Form the union of two closures 3491 */ 3492 public List<Type> union(List<Type> cl1, List<Type> cl2, BiPredicate<Type, Type> shouldSkip) { 3493 if (cl1.isEmpty()) { 3494 return cl2; 3495 } else if (cl2.isEmpty()) { 3496 return cl1; 3497 } else if (shouldSkip.test(cl1.head, cl2.head)) { 3498 return union(cl1.tail, cl2.tail, shouldSkip).prepend(cl1.head); 3499 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) { 3500 return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head); 3501 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { 3502 return union(cl1, cl2.tail, shouldSkip).prepend(cl2.head); 3503 } else { 3504 // unrelated types 3505 return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head); 3506 } 3507 } 3508 3509 public List<Type> union(List<Type> cl1, List<Type> cl2) { 3510 return union(cl1, cl2, basicClosureSkip); 3511 } 3512 3513 /** 3514 * Intersect two closures 3515 */ 3516 public List<Type> intersect(List<Type> cl1, List<Type> cl2) { 3517 if (cl1 == cl2) 3518 return cl1; 3519 if (cl1.isEmpty() || cl2.isEmpty()) 3520 return List.nil(); 3521 if (cl1.head.tsym.precedes(cl2.head.tsym, this)) 3522 return intersect(cl1.tail, cl2); 3523 if (cl2.head.tsym.precedes(cl1.head.tsym, this)) 3524 return intersect(cl1, cl2.tail); 3525 if (isSameType(cl1.head, cl2.head)) 3526 return intersect(cl1.tail, cl2.tail).prepend(cl1.head); 3527 if (cl1.head.tsym == cl2.head.tsym && 3528 cl1.head.hasTag(CLASS) && cl2.head.hasTag(CLASS)) { 3529 if (cl1.head.isParameterized() && cl2.head.isParameterized()) { 3530 Type merge = merge(cl1.head,cl2.head); 3531 return intersect(cl1.tail, cl2.tail).prepend(merge); 3532 } 3533 if (cl1.head.isRaw() || cl2.head.isRaw()) 3534 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head)); 3535 } 3536 return intersect(cl1.tail, cl2.tail); 3537 } 3538 // where 3539 class TypePair { 3540 final Type t1; 3541 final Type t2; 3542 boolean strict; 3543 3544 TypePair(Type t1, Type t2) { 3545 this(t1, t2, false); 3546 } 3547 3548 TypePair(Type t1, Type t2, boolean strict) { 3549 this.t1 = t1; 3550 this.t2 = t2; 3551 this.strict = strict; 3552 } 3553 @Override 3554 public int hashCode() { 3555 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2); 3556 } 3557 @Override 3558 public boolean equals(Object obj) { 3559 if (!(obj instanceof TypePair)) 3560 return false; 3561 TypePair typePair = (TypePair)obj; 3562 return isSameType(t1, typePair.t1, strict) 3563 && isSameType(t2, typePair.t2, strict); 3564 } 3565 } 3566 Set<TypePair> mergeCache = new HashSet<>(); 3567 private Type merge(Type c1, Type c2) { 3568 ClassType class1 = (ClassType) c1; 3569 List<Type> act1 = class1.getTypeArguments(); 3570 ClassType class2 = (ClassType) c2; 3571 List<Type> act2 = class2.getTypeArguments(); 3572 ListBuffer<Type> merged = new ListBuffer<>(); 3573 List<Type> typarams = class1.tsym.type.getTypeArguments(); 3574 3575 while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) { 3576 if (containsType(act1.head, act2.head)) { 3577 merged.append(act1.head); 3578 } else if (containsType(act2.head, act1.head)) { 3579 merged.append(act2.head); 3580 } else { 3581 TypePair pair = new TypePair(c1, c2); 3582 Type m; 3583 if (mergeCache.add(pair)) { 3584 m = new WildcardType(lub(wildUpperBound(act1.head), 3585 wildUpperBound(act2.head)), 3586 BoundKind.EXTENDS, 3587 syms.boundClass); 3588 mergeCache.remove(pair); 3589 } else { 3590 m = new WildcardType(syms.objectType, 3591 BoundKind.UNBOUND, 3592 syms.boundClass); 3593 } 3594 merged.append(m.withTypeVar(typarams.head)); 3595 } 3596 act1 = act1.tail; 3597 act2 = act2.tail; 3598 typarams = typarams.tail; 3599 } 3600 Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty()); 3601 // There is no spec detailing how type annotations are to 3602 // be inherited. So set it to noAnnotations for now 3603 return new ClassType(class1.getEnclosingType(), merged.toList(), 3604 class1.tsym); 3605 } 3606 3607 /** 3608 * Return the minimum type of a closure, a compound type if no 3609 * unique minimum exists. 3610 */ 3611 private Type compoundMin(List<Type> cl) { 3612 if (cl.isEmpty()) return syms.objectType; 3613 List<Type> compound = closureMin(cl); 3614 if (compound.isEmpty()) 3615 return null; 3616 else if (compound.tail.isEmpty()) 3617 return compound.head; 3618 else 3619 return makeIntersectionType(compound); 3620 } 3621 3622 /** 3623 * Return the minimum types of a closure, suitable for computing 3624 * compoundMin or glb. 3625 */ 3626 private List<Type> closureMin(List<Type> cl) { 3627 ListBuffer<Type> classes = new ListBuffer<>(); 3628 ListBuffer<Type> interfaces = new ListBuffer<>(); 3629 Set<Type> toSkip = new HashSet<>(); 3630 while (!cl.isEmpty()) { 3631 Type current = cl.head; 3632 boolean keep = !toSkip.contains(current); 3633 if (keep && current.hasTag(TYPEVAR)) { 3634 // skip lower-bounded variables with a subtype in cl.tail 3635 for (Type t : cl.tail) { 3636 if (isSubtypeNoCapture(t, current)) { 3637 keep = false; 3638 break; 3639 } 3640 } 3641 } 3642 if (keep) { 3643 if (current.isInterface()) 3644 interfaces.append(current); 3645 else 3646 classes.append(current); 3647 for (Type t : cl.tail) { 3648 // skip supertypes of 'current' in cl.tail 3649 if (isSubtypeNoCapture(current, t)) 3650 toSkip.add(t); 3651 } 3652 } 3653 cl = cl.tail; 3654 } 3655 return classes.appendList(interfaces).toList(); 3656 } 3657 3658 /** 3659 * Return the least upper bound of list of types. if the lub does 3660 * not exist return null. 3661 */ 3662 public Type lub(List<Type> ts) { 3663 return lub(ts.toArray(new Type[ts.length()])); 3664 } 3665 3666 /** 3667 * Return the least upper bound (lub) of set of types. If the lub 3668 * does not exist return the type of null (bottom). 3669 */ 3670 public Type lub(Type... ts) { 3671 final int UNKNOWN_BOUND = 0; 3672 final int ARRAY_BOUND = 1; 3673 final int CLASS_BOUND = 2; 3674 3675 int[] kinds = new int[ts.length]; 3676 3677 int boundkind = UNKNOWN_BOUND; 3678 for (int i = 0 ; i < ts.length ; i++) { 3679 Type t = ts[i]; 3680 switch (t.getTag()) { 3681 case CLASS: 3682 boundkind |= kinds[i] = CLASS_BOUND; 3683 break; 3684 case ARRAY: 3685 boundkind |= kinds[i] = ARRAY_BOUND; 3686 break; 3687 case TYPEVAR: 3688 do { 3689 t = t.getUpperBound(); 3690 } while (t.hasTag(TYPEVAR)); 3691 if (t.hasTag(ARRAY)) { 3692 boundkind |= kinds[i] = ARRAY_BOUND; 3693 } else { 3694 boundkind |= kinds[i] = CLASS_BOUND; 3695 } 3696 break; 3697 default: 3698 kinds[i] = UNKNOWN_BOUND; 3699 if (t.isPrimitive()) 3700 return syms.errType; 3701 } 3702 } 3703 switch (boundkind) { 3704 case 0: 3705 return syms.botType; 3706 3707 case ARRAY_BOUND: 3708 // calculate lub(A[], B[]) 3709 Type[] elements = new Type[ts.length]; 3710 for (int i = 0 ; i < ts.length ; i++) { 3711 Type elem = elements[i] = elemTypeFun.apply(ts[i]); 3712 if (elem.isPrimitive()) { 3713 // if a primitive type is found, then return 3714 // arraySuperType unless all the types are the 3715 // same 3716 Type first = ts[0]; 3717 for (int j = 1 ; j < ts.length ; j++) { 3718 if (!isSameType(first, ts[j])) { 3719 // lub(int[], B[]) is Cloneable & Serializable 3720 return arraySuperType(); 3721 } 3722 } 3723 // all the array types are the same, return one 3724 // lub(int[], int[]) is int[] 3725 return first; 3726 } 3727 } 3728 // lub(A[], B[]) is lub(A, B)[] 3729 return new ArrayType(lub(elements), syms.arrayClass); 3730 3731 case CLASS_BOUND: 3732 // calculate lub(A, B) 3733 int startIdx = 0; 3734 for (int i = 0; i < ts.length ; i++) { 3735 Type t = ts[i]; 3736 if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) { 3737 break; 3738 } else { 3739 startIdx++; 3740 } 3741 } 3742 Assert.check(startIdx < ts.length); 3743 //step 1 - compute erased candidate set (EC) 3744 List<Type> cl = erasedSupertypes(ts[startIdx]); 3745 for (int i = startIdx + 1 ; i < ts.length ; i++) { 3746 Type t = ts[i]; 3747 if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) 3748 cl = intersect(cl, erasedSupertypes(t)); 3749 } 3750 //step 2 - compute minimal erased candidate set (MEC) 3751 List<Type> mec = closureMin(cl); 3752 //step 3 - for each element G in MEC, compute lci(Inv(G)) 3753 List<Type> candidates = List.nil(); 3754 for (Type erasedSupertype : mec) { 3755 List<Type> lci = List.of(asSuper(ts[startIdx], erasedSupertype.tsym)); 3756 for (int i = startIdx + 1 ; i < ts.length ; i++) { 3757 Type superType = asSuper(ts[i], erasedSupertype.tsym); 3758 lci = intersect(lci, superType != null ? List.of(superType) : List.nil()); 3759 } 3760 candidates = candidates.appendList(lci); 3761 } 3762 //step 4 - let MEC be { G1, G2 ... Gn }, then we have that 3763 //lub = lci(Inv(G1)) & lci(Inv(G2)) & ... & lci(Inv(Gn)) 3764 return compoundMin(candidates); 3765 3766 default: 3767 // calculate lub(A, B[]) 3768 List<Type> classes = List.of(arraySuperType()); 3769 for (int i = 0 ; i < ts.length ; i++) { 3770 if (kinds[i] != ARRAY_BOUND) // Filter out any arrays 3771 classes = classes.prepend(ts[i]); 3772 } 3773 // lub(A, B[]) is lub(A, arraySuperType) 3774 return lub(classes); 3775 } 3776 } 3777 // where 3778 List<Type> erasedSupertypes(Type t) { 3779 ListBuffer<Type> buf = new ListBuffer<>(); 3780 for (Type sup : closure(t)) { 3781 if (sup.hasTag(TYPEVAR)) { 3782 buf.append(sup); 3783 } else { 3784 buf.append(erasure(sup)); 3785 } 3786 } 3787 return buf.toList(); 3788 } 3789 3790 private Type arraySuperType = null; 3791 private Type arraySuperType() { 3792 // initialized lazily to avoid problems during compiler startup 3793 if (arraySuperType == null) { 3794 synchronized (this) { 3795 if (arraySuperType == null) { 3796 // JLS 10.8: all arrays implement Cloneable and Serializable. 3797 arraySuperType = makeIntersectionType(List.of(syms.serializableType, 3798 syms.cloneableType), true); 3799 } 3800 } 3801 } 3802 return arraySuperType; 3803 } 3804 // </editor-fold> 3805 3806 // <editor-fold defaultstate="collapsed" desc="Greatest lower bound"> 3807 public Type glb(List<Type> ts) { 3808 Type t1 = ts.head; 3809 for (Type t2 : ts.tail) { 3810 if (t1.isErroneous()) 3811 return t1; 3812 t1 = glb(t1, t2); 3813 } 3814 return t1; 3815 } 3816 //where 3817 public Type glb(Type t, Type s) { 3818 if (s == null) 3819 return t; 3820 else if (t.isPrimitive() || s.isPrimitive()) 3821 return syms.errType; 3822 else if (isSubtypeNoCapture(t, s)) 3823 return t; 3824 else if (isSubtypeNoCapture(s, t)) 3825 return s; 3826 3827 List<Type> closure = union(closure(t), closure(s)); 3828 return glbFlattened(closure, t); 3829 } 3830 //where 3831 /** 3832 * Perform glb for a list of non-primitive, non-error, non-compound types; 3833 * redundant elements are removed. Bounds should be ordered according to 3834 * {@link Symbol#precedes(TypeSymbol,Types)}. 3835 * 3836 * @param flatBounds List of type to glb 3837 * @param errT Original type to use if the result is an error type 3838 */ 3839 private Type glbFlattened(List<Type> flatBounds, Type errT) { 3840 List<Type> bounds = closureMin(flatBounds); 3841 3842 if (bounds.isEmpty()) { // length == 0 3843 return syms.objectType; 3844 } else if (bounds.tail.isEmpty()) { // length == 1 3845 return bounds.head; 3846 } else { // length > 1 3847 int classCount = 0; 3848 List<Type> cvars = List.nil(); 3849 List<Type> lowers = List.nil(); 3850 for (Type bound : bounds) { 3851 if (!bound.isInterface()) { 3852 classCount++; 3853 Type lower = cvarLowerBound(bound); 3854 if (bound != lower && !lower.hasTag(BOT)) { 3855 cvars = cvars.append(bound); 3856 lowers = lowers.append(lower); 3857 } 3858 } 3859 } 3860 if (classCount > 1) { 3861 if (lowers.isEmpty()) { 3862 return createErrorType(errT); 3863 } else { 3864 // try again with lower bounds included instead of capture variables 3865 List<Type> newBounds = bounds.diff(cvars).appendList(lowers); 3866 return glb(newBounds); 3867 } 3868 } 3869 } 3870 return makeIntersectionType(bounds); 3871 } 3872 // </editor-fold> 3873 3874 // <editor-fold defaultstate="collapsed" desc="hashCode"> 3875 /** 3876 * Compute a hash code on a type. 3877 */ 3878 public int hashCode(Type t) { 3879 return hashCode(t, false); 3880 } 3881 3882 public int hashCode(Type t, boolean strict) { 3883 return strict ? 3884 hashCodeStrictVisitor.visit(t) : 3885 hashCodeVisitor.visit(t); 3886 } 3887 // where 3888 private static final HashCodeVisitor hashCodeVisitor = new HashCodeVisitor(); 3889 private static final HashCodeVisitor hashCodeStrictVisitor = new HashCodeVisitor() { 3890 @Override 3891 public Integer visitTypeVar(TypeVar t, Void ignored) { 3892 return System.identityHashCode(t); 3893 } 3894 }; 3895 3896 private static class HashCodeVisitor extends UnaryVisitor<Integer> { 3897 public Integer visitType(Type t, Void ignored) { 3898 return t.getTag().ordinal(); 3899 } 3900 3901 @Override 3902 public Integer visitClassType(ClassType t, Void ignored) { 3903 int result = visit(t.getEnclosingType()); 3904 result *= 127; 3905 result += t.tsym.flatName().hashCode(); 3906 for (Type s : t.getTypeArguments()) { 3907 result *= 127; 3908 result += visit(s); 3909 } 3910 return result; 3911 } 3912 3913 @Override 3914 public Integer visitMethodType(MethodType t, Void ignored) { 3915 int h = METHOD.ordinal(); 3916 for (List<Type> thisargs = t.argtypes; 3917 thisargs.tail != null; 3918 thisargs = thisargs.tail) 3919 h = (h << 5) + visit(thisargs.head); 3920 return (h << 5) + visit(t.restype); 3921 } 3922 3923 @Override 3924 public Integer visitWildcardType(WildcardType t, Void ignored) { 3925 int result = t.kind.hashCode(); 3926 if (t.type != null) { 3927 result *= 127; 3928 result += visit(t.type); 3929 } 3930 return result; 3931 } 3932 3933 @Override 3934 public Integer visitArrayType(ArrayType t, Void ignored) { 3935 return visit(t.elemtype) + 12; 3936 } 3937 3938 @Override 3939 public Integer visitTypeVar(TypeVar t, Void ignored) { 3940 return System.identityHashCode(t); 3941 } 3942 3943 @Override 3944 public Integer visitUndetVar(UndetVar t, Void ignored) { 3945 return System.identityHashCode(t); 3946 } 3947 3948 @Override 3949 public Integer visitErrorType(ErrorType t, Void ignored) { 3950 return 0; 3951 } 3952 } 3953 // </editor-fold> 3954 3955 // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable"> 3956 /** 3957 * Does t have a result that is a subtype of the result type of s, 3958 * suitable for covariant returns? It is assumed that both types 3959 * are (possibly polymorphic) method types. Monomorphic method 3960 * types are handled in the obvious way. Polymorphic method types 3961 * require renaming all type variables of one to corresponding 3962 * type variables in the other, where correspondence is by 3963 * position in the type parameter list. */ 3964 public boolean resultSubtype(Type t, Type s, Warner warner) { 3965 List<Type> tvars = t.getTypeArguments(); 3966 List<Type> svars = s.getTypeArguments(); 3967 Type tres = t.getReturnType(); 3968 Type sres = subst(s.getReturnType(), svars, tvars); 3969 return covariantReturnType(tres, sres, warner); 3970 } 3971 3972 /** 3973 * Return-Type-Substitutable. 3974 * @jls section 8.4.5 3975 */ 3976 public boolean returnTypeSubstitutable(Type r1, Type r2) { 3977 if (hasSameArgs(r1, r2)) 3978 return resultSubtype(r1, r2, noWarnings); 3979 else 3980 return covariantReturnType(r1.getReturnType(), 3981 erasure(r2.getReturnType()), 3982 noWarnings); 3983 } 3984 3985 public boolean returnTypeSubstitutable(Type r1, 3986 Type r2, Type r2res, 3987 Warner warner) { 3988 if (isSameType(r1.getReturnType(), r2res)) 3989 return true; 3990 if (r1.getReturnType().isPrimitive() || r2res.isPrimitive()) 3991 return false; 3992 3993 if (hasSameArgs(r1, r2)) 3994 return covariantReturnType(r1.getReturnType(), r2res, warner); 3995 if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner)) 3996 return true; 3997 if (!isSubtype(r1.getReturnType(), erasure(r2res))) 3998 return false; 3999 warner.warn(LintCategory.UNCHECKED); 4000 return true; 4001 } 4002 4003 /** 4004 * Is t an appropriate return type in an overrider for a 4005 * method that returns s? 4006 */ 4007 public boolean covariantReturnType(Type t, Type s, Warner warner) { 4008 return 4009 isSameType(t, s) || 4010 !t.isPrimitive() && 4011 !s.isPrimitive() && 4012 isAssignable(t, s, warner); 4013 } 4014 // </editor-fold> 4015 4016 // <editor-fold defaultstate="collapsed" desc="Box/unbox support"> 4017 /** 4018 * Return the class that boxes the given primitive. 4019 */ 4020 public ClassSymbol boxedClass(Type t) { 4021 return syms.enterClass(syms.java_base, syms.boxedName[t.getTag().ordinal()]); 4022 } 4023 4024 /** 4025 * Return the boxed type if 't' is primitive, otherwise return 't' itself. 4026 */ 4027 public Type boxedTypeOrType(Type t) { 4028 return t.isPrimitive() ? 4029 boxedClass(t).type : 4030 t; 4031 } 4032 4033 /** 4034 * Return the primitive type corresponding to a boxed type. 4035 */ 4036 public Type unboxedType(Type t) { 4037 for (int i=0; i<syms.boxedName.length; i++) { 4038 Name box = syms.boxedName[i]; 4039 if (box != null && 4040 asSuper(t, syms.enterClass(syms.java_base, box)) != null) 4041 return syms.typeOfTag[i]; 4042 } 4043 return Type.noType; 4044 } 4045 4046 /** 4047 * Return the unboxed type if 't' is a boxed class, otherwise return 't' itself. 4048 */ 4049 public Type unboxedTypeOrType(Type t) { 4050 Type unboxedType = unboxedType(t); 4051 return unboxedType.hasTag(NONE) ? t : unboxedType; 4052 } 4053 // </editor-fold> 4054 4055 // <editor-fold defaultstate="collapsed" desc="Capture conversion"> 4056 /* 4057 * JLS 5.1.10 Capture Conversion: 4058 * 4059 * Let G name a generic type declaration with n formal type 4060 * parameters A1 ... An with corresponding bounds U1 ... Un. There 4061 * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>, 4062 * where, for 1 <= i <= n: 4063 * 4064 * + If Ti is a wildcard type argument (4.5.1) of the form ? then 4065 * Si is a fresh type variable whose upper bound is 4066 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null 4067 * type. 4068 * 4069 * + If Ti is a wildcard type argument of the form ? extends Bi, 4070 * then Si is a fresh type variable whose upper bound is 4071 * glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is 4072 * the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is 4073 * a compile-time error if for any two classes (not interfaces) 4074 * Vi and Vj,Vi is not a subclass of Vj or vice versa. 4075 * 4076 * + If Ti is a wildcard type argument of the form ? super Bi, 4077 * then Si is a fresh type variable whose upper bound is 4078 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi. 4079 * 4080 * + Otherwise, Si = Ti. 4081 * 4082 * Capture conversion on any type other than a parameterized type 4083 * (4.5) acts as an identity conversion (5.1.1). Capture 4084 * conversions never require a special action at run time and 4085 * therefore never throw an exception at run time. 4086 * 4087 * Capture conversion is not applied recursively. 4088 */ 4089 /** 4090 * Capture conversion as specified by the JLS. 4091 */ 4092 4093 public List<Type> capture(List<Type> ts) { 4094 List<Type> buf = List.nil(); 4095 for (Type t : ts) { 4096 buf = buf.prepend(capture(t)); 4097 } 4098 return buf.reverse(); 4099 } 4100 4101 public Type capture(Type t) { 4102 if (!t.hasTag(CLASS)) { 4103 return t; 4104 } 4105 if (t.getEnclosingType() != Type.noType) { 4106 Type capturedEncl = capture(t.getEnclosingType()); 4107 if (capturedEncl != t.getEnclosingType()) { 4108 Type type1 = memberType(capturedEncl, t.tsym); 4109 t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments()); 4110 } 4111 } 4112 ClassType cls = (ClassType)t; 4113 if (cls.isRaw() || !cls.isParameterized()) 4114 return cls; 4115 4116 ClassType G = (ClassType)cls.asElement().asType(); 4117 List<Type> A = G.getTypeArguments(); 4118 List<Type> T = cls.getTypeArguments(); 4119 List<Type> S = freshTypeVariables(T); 4120 4121 List<Type> currentA = A; 4122 List<Type> currentT = T; 4123 List<Type> currentS = S; 4124 boolean captured = false; 4125 while (!currentA.isEmpty() && 4126 !currentT.isEmpty() && 4127 !currentS.isEmpty()) { 4128 if (currentS.head != currentT.head) { 4129 captured = true; 4130 WildcardType Ti = (WildcardType)currentT.head; 4131 Type Ui = currentA.head.getUpperBound(); 4132 CapturedType Si = (CapturedType)currentS.head; 4133 if (Ui == null) 4134 Ui = syms.objectType; 4135 switch (Ti.kind) { 4136 case UNBOUND: 4137 Si.bound = subst(Ui, A, S); 4138 Si.lower = syms.botType; 4139 break; 4140 case EXTENDS: 4141 Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S)); 4142 Si.lower = syms.botType; 4143 break; 4144 case SUPER: 4145 Si.bound = subst(Ui, A, S); 4146 Si.lower = Ti.getSuperBound(); 4147 break; 4148 } 4149 Type tmpBound = Si.bound.hasTag(UNDETVAR) ? ((UndetVar)Si.bound).qtype : Si.bound; 4150 Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar)Si.lower).qtype : Si.lower; 4151 if (!Si.bound.hasTag(ERROR) && 4152 !Si.lower.hasTag(ERROR) && 4153 isSameType(tmpBound, tmpLower, false)) { 4154 currentS.head = Si.bound; 4155 } 4156 } 4157 currentA = currentA.tail; 4158 currentT = currentT.tail; 4159 currentS = currentS.tail; 4160 } 4161 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty()) 4162 return erasure(t); // some "rare" type involved 4163 4164 if (captured) 4165 return new ClassType(cls.getEnclosingType(), S, cls.tsym, 4166 cls.getMetadata()); 4167 else 4168 return t; 4169 } 4170 // where 4171 public List<Type> freshTypeVariables(List<Type> types) { 4172 ListBuffer<Type> result = new ListBuffer<>(); 4173 for (Type t : types) { 4174 if (t.hasTag(WILDCARD)) { 4175 Type bound = ((WildcardType)t).getExtendsBound(); 4176 if (bound == null) 4177 bound = syms.objectType; 4178 result.append(new CapturedType(capturedName, 4179 syms.noSymbol, 4180 bound, 4181 syms.botType, 4182 (WildcardType)t)); 4183 } else { 4184 result.append(t); 4185 } 4186 } 4187 return result.toList(); 4188 } 4189 // </editor-fold> 4190 4191 // <editor-fold defaultstate="collapsed" desc="Internal utility methods"> 4192 private boolean sideCast(Type from, Type to, Warner warn) { 4193 // We are casting from type $from$ to type $to$, which are 4194 // non-final unrelated types. This method 4195 // tries to reject a cast by transferring type parameters 4196 // from $to$ to $from$ by common superinterfaces. 4197 boolean reverse = false; 4198 Type target = to; 4199 if ((to.tsym.flags() & INTERFACE) == 0) { 4200 Assert.check((from.tsym.flags() & INTERFACE) != 0); 4201 reverse = true; 4202 to = from; 4203 from = target; 4204 } 4205 List<Type> commonSupers = superClosure(to, erasure(from)); 4206 boolean giveWarning = commonSupers.isEmpty(); 4207 // The arguments to the supers could be unified here to 4208 // get a more accurate analysis 4209 while (commonSupers.nonEmpty()) { 4210 Type t1 = asSuper(from, commonSupers.head.tsym); 4211 Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym); 4212 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) 4213 return false; 4214 giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)); 4215 commonSupers = commonSupers.tail; 4216 } 4217 if (giveWarning && !isReifiable(reverse ? from : to)) 4218 warn.warn(LintCategory.UNCHECKED); 4219 return true; 4220 } 4221 4222 private boolean sideCastFinal(Type from, Type to, Warner warn) { 4223 // We are casting from type $from$ to type $to$, which are 4224 // unrelated types one of which is final and the other of 4225 // which is an interface. This method 4226 // tries to reject a cast by transferring type parameters 4227 // from the final class to the interface. 4228 boolean reverse = false; 4229 Type target = to; 4230 if ((to.tsym.flags() & INTERFACE) == 0) { 4231 Assert.check((from.tsym.flags() & INTERFACE) != 0); 4232 reverse = true; 4233 to = from; 4234 from = target; 4235 } 4236 Assert.check((from.tsym.flags() & FINAL) != 0); 4237 Type t1 = asSuper(from, to.tsym); 4238 if (t1 == null) return false; 4239 Type t2 = to; 4240 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) 4241 return false; 4242 if (!isReifiable(target) && 4243 (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2))) 4244 warn.warn(LintCategory.UNCHECKED); 4245 return true; 4246 } 4247 4248 private boolean giveWarning(Type from, Type to) { 4249 List<Type> bounds = to.isCompound() ? 4250 directSupertypes(to) : List.of(to); 4251 for (Type b : bounds) { 4252 Type subFrom = asSub(from, b.tsym); 4253 if (b.isParameterized() && 4254 (!(isUnbounded(b) || 4255 isSubtype(from, b) || 4256 ((subFrom != null) && containsType(b.allparams(), subFrom.allparams()))))) { 4257 return true; 4258 } 4259 } 4260 return false; 4261 } 4262 4263 private List<Type> superClosure(Type t, Type s) { 4264 List<Type> cl = List.nil(); 4265 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) { 4266 if (isSubtype(s, erasure(l.head))) { 4267 cl = insert(cl, l.head); 4268 } else { 4269 cl = union(cl, superClosure(l.head, s)); 4270 } 4271 } 4272 return cl; 4273 } 4274 4275 private boolean containsTypeEquivalent(Type t, Type s) { 4276 return isSameType(t, s) || // shortcut 4277 containsType(t, s) && containsType(s, t); 4278 } 4279 4280 // <editor-fold defaultstate="collapsed" desc="adapt"> 4281 /** 4282 * Adapt a type by computing a substitution which maps a source 4283 * type to a target type. 4284 * 4285 * @param source the source type 4286 * @param target the target type 4287 * @param from the type variables of the computed substitution 4288 * @param to the types of the computed substitution. 4289 */ 4290 public void adapt(Type source, 4291 Type target, 4292 ListBuffer<Type> from, 4293 ListBuffer<Type> to) throws AdaptFailure { 4294 new Adapter(from, to).adapt(source, target); 4295 } 4296 4297 class Adapter extends SimpleVisitor<Void, Type> { 4298 4299 ListBuffer<Type> from; 4300 ListBuffer<Type> to; 4301 Map<Symbol,Type> mapping; 4302 4303 Adapter(ListBuffer<Type> from, ListBuffer<Type> to) { 4304 this.from = from; 4305 this.to = to; 4306 mapping = new HashMap<>(); 4307 } 4308 4309 public void adapt(Type source, Type target) throws AdaptFailure { 4310 visit(source, target); 4311 List<Type> fromList = from.toList(); 4312 List<Type> toList = to.toList(); 4313 while (!fromList.isEmpty()) { 4314 Type val = mapping.get(fromList.head.tsym); 4315 if (toList.head != val) 4316 toList.head = val; 4317 fromList = fromList.tail; 4318 toList = toList.tail; 4319 } 4320 } 4321 4322 @Override 4323 public Void visitClassType(ClassType source, Type target) throws AdaptFailure { 4324 if (target.hasTag(CLASS)) 4325 adaptRecursive(source.allparams(), target.allparams()); 4326 return null; 4327 } 4328 4329 @Override 4330 public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure { 4331 if (target.hasTag(ARRAY)) 4332 adaptRecursive(elemtype(source), elemtype(target)); 4333 return null; 4334 } 4335 4336 @Override 4337 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { 4338 if (source.isExtendsBound()) 4339 adaptRecursive(wildUpperBound(source), wildUpperBound(target)); 4340 else if (source.isSuperBound()) 4341 adaptRecursive(wildLowerBound(source), wildLowerBound(target)); 4342 return null; 4343 } 4344 4345 @Override 4346 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure { 4347 // Check to see if there is 4348 // already a mapping for $source$, in which case 4349 // the old mapping will be merged with the new 4350 Type val = mapping.get(source.tsym); 4351 if (val != null) { 4352 if (val.isSuperBound() && target.isSuperBound()) { 4353 val = isSubtype(wildLowerBound(val), wildLowerBound(target)) 4354 ? target : val; 4355 } else if (val.isExtendsBound() && target.isExtendsBound()) { 4356 val = isSubtype(wildUpperBound(val), wildUpperBound(target)) 4357 ? val : target; 4358 } else if (!isSameType(val, target)) { 4359 throw new AdaptFailure(); 4360 } 4361 } else { 4362 val = target; 4363 from.append(source); 4364 to.append(target); 4365 } 4366 mapping.put(source.tsym, val); 4367 return null; 4368 } 4369 4370 @Override 4371 public Void visitType(Type source, Type target) { 4372 return null; 4373 } 4374 4375 private Set<TypePair> cache = new HashSet<>(); 4376 4377 private void adaptRecursive(Type source, Type target) { 4378 TypePair pair = new TypePair(source, target); 4379 if (cache.add(pair)) { 4380 try { 4381 visit(source, target); 4382 } finally { 4383 cache.remove(pair); 4384 } 4385 } 4386 } 4387 4388 private void adaptRecursive(List<Type> source, List<Type> target) { 4389 if (source.length() == target.length()) { 4390 while (source.nonEmpty()) { 4391 adaptRecursive(source.head, target.head); 4392 source = source.tail; 4393 target = target.tail; 4394 } 4395 } 4396 } 4397 } 4398 4399 public static class AdaptFailure extends RuntimeException { 4400 static final long serialVersionUID = -7490231548272701566L; 4401 } 4402 4403 private void adaptSelf(Type t, 4404 ListBuffer<Type> from, 4405 ListBuffer<Type> to) { 4406 try { 4407 //if (t.tsym.type != t) 4408 adapt(t.tsym.type, t, from, to); 4409 } catch (AdaptFailure ex) { 4410 // Adapt should never fail calculating a mapping from 4411 // t.tsym.type to t as there can be no merge problem. 4412 throw new AssertionError(ex); 4413 } 4414 } 4415 // </editor-fold> 4416 4417 /** 4418 * Rewrite all type variables (universal quantifiers) in the given 4419 * type to wildcards (existential quantifiers). This is used to 4420 * determine if a cast is allowed. For example, if high is true 4421 * and {@code T <: Number}, then {@code List<T>} is rewritten to 4422 * {@code List<? extends Number>}. Since {@code List<Integer> <: 4423 * List<? extends Number>} a {@code List<T>} can be cast to {@code 4424 * List<Integer>} with a warning. 4425 * @param t a type 4426 * @param high if true return an upper bound; otherwise a lower 4427 * bound 4428 * @param rewriteTypeVars only rewrite captured wildcards if false; 4429 * otherwise rewrite all type variables 4430 * @return the type rewritten with wildcards (existential 4431 * quantifiers) only 4432 */ 4433 private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) { 4434 return new Rewriter(high, rewriteTypeVars).visit(t); 4435 } 4436 4437 class Rewriter extends UnaryVisitor<Type> { 4438 4439 boolean high; 4440 boolean rewriteTypeVars; 4441 4442 Rewriter(boolean high, boolean rewriteTypeVars) { 4443 this.high = high; 4444 this.rewriteTypeVars = rewriteTypeVars; 4445 } 4446 4447 @Override 4448 public Type visitClassType(ClassType t, Void s) { 4449 ListBuffer<Type> rewritten = new ListBuffer<>(); 4450 boolean changed = false; 4451 for (Type arg : t.allparams()) { 4452 Type bound = visit(arg); 4453 if (arg != bound) { 4454 changed = true; 4455 } 4456 rewritten.append(bound); 4457 } 4458 if (changed) 4459 return subst(t.tsym.type, 4460 t.tsym.type.allparams(), 4461 rewritten.toList()); 4462 else 4463 return t; 4464 } 4465 4466 public Type visitType(Type t, Void s) { 4467 return t; 4468 } 4469 4470 @Override 4471 public Type visitCapturedType(CapturedType t, Void s) { 4472 Type w_bound = t.wildcard.type; 4473 Type bound = w_bound.contains(t) ? 4474 erasure(w_bound) : 4475 visit(w_bound); 4476 return rewriteAsWildcardType(visit(bound), t.wildcard.bound, t.wildcard.kind); 4477 } 4478 4479 @Override 4480 public Type visitTypeVar(TypeVar t, Void s) { 4481 if (rewriteTypeVars) { 4482 Type bound = t.bound.contains(t) ? 4483 erasure(t.bound) : 4484 visit(t.bound); 4485 return rewriteAsWildcardType(bound, t, EXTENDS); 4486 } else { 4487 return t; 4488 } 4489 } 4490 4491 @Override 4492 public Type visitWildcardType(WildcardType t, Void s) { 4493 Type bound2 = visit(t.type); 4494 return t.type == bound2 ? t : rewriteAsWildcardType(bound2, t.bound, t.kind); 4495 } 4496 4497 private Type rewriteAsWildcardType(Type bound, TypeVar formal, BoundKind bk) { 4498 switch (bk) { 4499 case EXTENDS: return high ? 4500 makeExtendsWildcard(B(bound), formal) : 4501 makeExtendsWildcard(syms.objectType, formal); 4502 case SUPER: return high ? 4503 makeSuperWildcard(syms.botType, formal) : 4504 makeSuperWildcard(B(bound), formal); 4505 case UNBOUND: return makeExtendsWildcard(syms.objectType, formal); 4506 default: 4507 Assert.error("Invalid bound kind " + bk); 4508 return null; 4509 } 4510 } 4511 4512 Type B(Type t) { 4513 while (t.hasTag(WILDCARD)) { 4514 WildcardType w = (WildcardType)t; 4515 t = high ? 4516 w.getExtendsBound() : 4517 w.getSuperBound(); 4518 if (t == null) { 4519 t = high ? syms.objectType : syms.botType; 4520 } 4521 } 4522 return t; 4523 } 4524 } 4525 4526 4527 /** 4528 * Create a wildcard with the given upper (extends) bound; create 4529 * an unbounded wildcard if bound is Object. 4530 * 4531 * @param bound the upper bound 4532 * @param formal the formal type parameter that will be 4533 * substituted by the wildcard 4534 */ 4535 private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) { 4536 if (bound == syms.objectType) { 4537 return new WildcardType(syms.objectType, 4538 BoundKind.UNBOUND, 4539 syms.boundClass, 4540 formal); 4541 } else { 4542 return new WildcardType(bound, 4543 BoundKind.EXTENDS, 4544 syms.boundClass, 4545 formal); 4546 } 4547 } 4548 4549 /** 4550 * Create a wildcard with the given lower (super) bound; create an 4551 * unbounded wildcard if bound is bottom (type of {@code null}). 4552 * 4553 * @param bound the lower bound 4554 * @param formal the formal type parameter that will be 4555 * substituted by the wildcard 4556 */ 4557 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) { 4558 if (bound.hasTag(BOT)) { 4559 return new WildcardType(syms.objectType, 4560 BoundKind.UNBOUND, 4561 syms.boundClass, 4562 formal); 4563 } else { 4564 return new WildcardType(bound, 4565 BoundKind.SUPER, 4566 syms.boundClass, 4567 formal); 4568 } 4569 } 4570 4571 /** 4572 * A wrapper for a type that allows use in sets. 4573 */ 4574 public static class UniqueType { 4575 public final Type type; 4576 final Types types; 4577 4578 public UniqueType(Type type, Types types) { 4579 this.type = type; 4580 this.types = types; 4581 } 4582 4583 public int hashCode() { 4584 return types.hashCode(type); 4585 } 4586 4587 public boolean equals(Object obj) { 4588 return (obj instanceof UniqueType) && 4589 types.isSameType(type, ((UniqueType)obj).type); 4590 } 4591 4592 public String toString() { 4593 return type.toString(); 4594 } 4595 4596 } 4597 // </editor-fold> 4598 4599 // <editor-fold defaultstate="collapsed" desc="Visitors"> 4600 /** 4601 * A default visitor for types. All visitor methods except 4602 * visitType are implemented by delegating to visitType. Concrete 4603 * subclasses must provide an implementation of visitType and can 4604 * override other methods as needed. 4605 * 4606 * @param <R> the return type of the operation implemented by this 4607 * visitor; use Void if no return type is needed. 4608 * @param <S> the type of the second argument (the first being the 4609 * type itself) of the operation implemented by this visitor; use 4610 * Void if a second argument is not needed. 4611 */ 4612 public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> { 4613 final public R visit(Type t, S s) { return t.accept(this, s); } 4614 public R visitClassType(ClassType t, S s) { return visitType(t, s); } 4615 public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); } 4616 public R visitArrayType(ArrayType t, S s) { return visitType(t, s); } 4617 public R visitMethodType(MethodType t, S s) { return visitType(t, s); } 4618 public R visitPackageType(PackageType t, S s) { return visitType(t, s); } 4619 public R visitModuleType(ModuleType t, S s) { return visitType(t, s); } 4620 public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); } 4621 public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); } 4622 public R visitForAll(ForAll t, S s) { return visitType(t, s); } 4623 public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); } 4624 public R visitErrorType(ErrorType t, S s) { return visitType(t, s); } 4625 } 4626 4627 /** 4628 * A default visitor for symbols. All visitor methods except 4629 * visitSymbol are implemented by delegating to visitSymbol. Concrete 4630 * subclasses must provide an implementation of visitSymbol and can 4631 * override other methods as needed. 4632 * 4633 * @param <R> the return type of the operation implemented by this 4634 * visitor; use Void if no return type is needed. 4635 * @param <S> the type of the second argument (the first being the 4636 * symbol itself) of the operation implemented by this visitor; use 4637 * Void if a second argument is not needed. 4638 */ 4639 public static abstract class DefaultSymbolVisitor<R,S> implements Symbol.Visitor<R,S> { 4640 final public R visit(Symbol s, S arg) { return s.accept(this, arg); } 4641 public R visitClassSymbol(ClassSymbol s, S arg) { return visitSymbol(s, arg); } 4642 public R visitMethodSymbol(MethodSymbol s, S arg) { return visitSymbol(s, arg); } 4643 public R visitOperatorSymbol(OperatorSymbol s, S arg) { return visitSymbol(s, arg); } 4644 public R visitPackageSymbol(PackageSymbol s, S arg) { return visitSymbol(s, arg); } 4645 public R visitTypeSymbol(TypeSymbol s, S arg) { return visitSymbol(s, arg); } 4646 public R visitVarSymbol(VarSymbol s, S arg) { return visitSymbol(s, arg); } 4647 } 4648 4649 /** 4650 * A <em>simple</em> visitor for types. This visitor is simple as 4651 * captured wildcards, for-all types (generic methods), and 4652 * undetermined type variables (part of inference) are hidden. 4653 * Captured wildcards are hidden by treating them as type 4654 * variables and the rest are hidden by visiting their qtypes. 4655 * 4656 * @param <R> the return type of the operation implemented by this 4657 * visitor; use Void if no return type is needed. 4658 * @param <S> the type of the second argument (the first being the 4659 * type itself) of the operation implemented by this visitor; use 4660 * Void if a second argument is not needed. 4661 */ 4662 public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> { 4663 @Override 4664 public R visitCapturedType(CapturedType t, S s) { 4665 return visitTypeVar(t, s); 4666 } 4667 @Override 4668 public R visitForAll(ForAll t, S s) { 4669 return visit(t.qtype, s); 4670 } 4671 @Override 4672 public R visitUndetVar(UndetVar t, S s) { 4673 return visit(t.qtype, s); 4674 } 4675 } 4676 4677 /** 4678 * A plain relation on types. That is a 2-ary function on the 4679 * form Type × Type → Boolean. 4680 * <!-- In plain text: Type x Type -> Boolean --> 4681 */ 4682 public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {} 4683 4684 /** 4685 * A convenience visitor for implementing operations that only 4686 * require one argument (the type itself), that is, unary 4687 * operations. 4688 * 4689 * @param <R> the return type of the operation implemented by this 4690 * visitor; use Void if no return type is needed. 4691 */ 4692 public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> { 4693 final public R visit(Type t) { return t.accept(this, null); } 4694 } 4695 4696 /** 4697 * A visitor for implementing a mapping from types to types. The 4698 * default behavior of this class is to implement the identity 4699 * mapping (mapping a type to itself). This can be overridden in 4700 * subclasses. 4701 * 4702 * @param <S> the type of the second argument (the first being the 4703 * type itself) of this mapping; use Void if a second argument is 4704 * not needed. 4705 */ 4706 public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> { 4707 final public Type visit(Type t) { return t.accept(this, null); } 4708 public Type visitType(Type t, S s) { return t; } 4709 } 4710 // </editor-fold> 4711 4712 4713 // <editor-fold defaultstate="collapsed" desc="Annotation support"> 4714 4715 public RetentionPolicy getRetention(Attribute.Compound a) { 4716 return getRetention(a.type.tsym); 4717 } 4718 4719 public RetentionPolicy getRetention(TypeSymbol sym) { 4720 RetentionPolicy vis = RetentionPolicy.CLASS; // the default 4721 Attribute.Compound c = sym.attribute(syms.retentionType.tsym); 4722 if (c != null) { 4723 Attribute value = c.member(names.value); 4724 if (value != null && value instanceof Attribute.Enum) { 4725 Name levelName = ((Attribute.Enum)value).value.name; 4726 if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE; 4727 else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS; 4728 else if (levelName == names.RUNTIME) vis = RetentionPolicy.RUNTIME; 4729 else ;// /* fail soft */ throw new AssertionError(levelName); 4730 } 4731 } 4732 return vis; 4733 } 4734 // </editor-fold> 4735 4736 // <editor-fold defaultstate="collapsed" desc="Signature Generation"> 4737 4738 public static abstract class SignatureGenerator { 4739 4740 private final Types types; 4741 4742 protected abstract void append(char ch); 4743 protected abstract void append(byte[] ba); 4744 protected abstract void append(Name name); 4745 protected void classReference(ClassSymbol c) { /* by default: no-op */ } 4746 4747 protected SignatureGenerator(Types types) { 4748 this.types = types; 4749 } 4750 4751 /** 4752 * Assemble signature of given type in string buffer. 4753 */ 4754 public void assembleSig(Type type) { 4755 switch (type.getTag()) { 4756 case BYTE: 4757 append('B'); 4758 break; 4759 case SHORT: 4760 append('S'); 4761 break; 4762 case CHAR: 4763 append('C'); 4764 break; 4765 case INT: 4766 append('I'); 4767 break; 4768 case LONG: 4769 append('J'); 4770 break; 4771 case FLOAT: 4772 append('F'); 4773 break; 4774 case DOUBLE: 4775 append('D'); 4776 break; 4777 case BOOLEAN: 4778 append('Z'); 4779 break; 4780 case VOID: 4781 append('V'); 4782 break; 4783 case CLASS: 4784 append('L'); 4785 assembleClassSig(type); 4786 append(';'); 4787 break; 4788 case ARRAY: 4789 ArrayType at = (ArrayType) type; 4790 append('['); 4791 assembleSig(at.elemtype); 4792 break; 4793 case METHOD: 4794 MethodType mt = (MethodType) type; 4795 append('('); 4796 assembleSig(mt.argtypes); 4797 append(')'); 4798 assembleSig(mt.restype); 4799 if (hasTypeVar(mt.thrown)) { 4800 for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) { 4801 append('^'); 4802 assembleSig(l.head); 4803 } 4804 } 4805 break; 4806 case WILDCARD: { 4807 Type.WildcardType ta = (Type.WildcardType) type; 4808 switch (ta.kind) { 4809 case SUPER: 4810 append('-'); 4811 assembleSig(ta.type); 4812 break; 4813 case EXTENDS: 4814 append('+'); 4815 assembleSig(ta.type); 4816 break; 4817 case UNBOUND: 4818 append('*'); 4819 break; 4820 default: 4821 throw new AssertionError(ta.kind); 4822 } 4823 break; 4824 } 4825 case TYPEVAR: 4826 append('T'); 4827 append(type.tsym.name); 4828 append(';'); 4829 break; 4830 case FORALL: 4831 Type.ForAll ft = (Type.ForAll) type; 4832 assembleParamsSig(ft.tvars); 4833 assembleSig(ft.qtype); 4834 break; 4835 default: 4836 throw new AssertionError("typeSig " + type.getTag()); 4837 } 4838 } 4839 4840 public boolean hasTypeVar(List<Type> l) { 4841 while (l.nonEmpty()) { 4842 if (l.head.hasTag(TypeTag.TYPEVAR)) { 4843 return true; 4844 } 4845 l = l.tail; 4846 } 4847 return false; 4848 } 4849 4850 public void assembleClassSig(Type type) { 4851 ClassType ct = (ClassType) type; 4852 ClassSymbol c = (ClassSymbol) ct.tsym; 4853 classReference(c); 4854 Type outer = ct.getEnclosingType(); 4855 if (outer.allparams().nonEmpty()) { 4856 boolean rawOuter = 4857 c.owner.kind == MTH || // either a local class 4858 c.name == types.names.empty; // or anonymous 4859 assembleClassSig(rawOuter 4860 ? types.erasure(outer) 4861 : outer); 4862 append(rawOuter ? '$' : '.'); 4863 Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname)); 4864 append(rawOuter 4865 ? c.flatname.subName(c.owner.enclClass().flatname.getByteLength() + 1, c.flatname.getByteLength()) 4866 : c.name); 4867 } else { 4868 append(externalize(c.flatname)); 4869 } 4870 if (ct.getTypeArguments().nonEmpty()) { 4871 append('<'); 4872 assembleSig(ct.getTypeArguments()); 4873 append('>'); 4874 } 4875 } 4876 4877 public void assembleParamsSig(List<Type> typarams) { 4878 append('<'); 4879 for (List<Type> ts = typarams; ts.nonEmpty(); ts = ts.tail) { 4880 Type.TypeVar tvar = (Type.TypeVar) ts.head; 4881 append(tvar.tsym.name); 4882 List<Type> bounds = types.getBounds(tvar); 4883 if ((bounds.head.tsym.flags() & INTERFACE) != 0) { 4884 append(':'); 4885 } 4886 for (List<Type> l = bounds; l.nonEmpty(); l = l.tail) { 4887 append(':'); 4888 assembleSig(l.head); 4889 } 4890 } 4891 append('>'); 4892 } 4893 4894 private void assembleSig(List<Type> types) { 4895 for (List<Type> ts = types; ts.nonEmpty(); ts = ts.tail) { 4896 assembleSig(ts.head); 4897 } 4898 } 4899 } 4900 // </editor-fold> 4901 4902 public void newRound() { 4903 descCache._map.clear(); 4904 isDerivedRawCache.clear(); 4905 implCache._map.clear(); 4906 membersCache._map.clear(); 4907 closureCache.clear(); 4908 } 4909} 4910