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