1 /*
   2  * Copyright (c) 1999, 2019, 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.comp;
  27 
  28 import com.sun.tools.javac.api.Formattable.LocalizedString;
  29 import com.sun.tools.javac.code.*;
  30 import com.sun.tools.javac.code.Scope.WriteableScope;
  31 import com.sun.tools.javac.code.Source.Feature;
  32 import com.sun.tools.javac.code.Symbol.*;
  33 import com.sun.tools.javac.code.Type.*;
  34 import com.sun.tools.javac.comp.Attr.ResultInfo;
  35 import com.sun.tools.javac.comp.Check.CheckContext;
  36 import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
  37 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
  38 import com.sun.tools.javac.comp.DeferredAttr.DeferredType;
  39 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
  40 import com.sun.tools.javac.comp.Resolve.MethodResolutionDiagHelper.Template;
  41 import com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind;
  42 import com.sun.tools.javac.jvm.*;
  43 import com.sun.tools.javac.main.Option;
  44 import com.sun.tools.javac.resources.CompilerProperties.Errors;
  45 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  46 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  47 import com.sun.tools.javac.tree.*;
  48 import com.sun.tools.javac.tree.JCTree.*;
  49 import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
  50 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*;
  51 import com.sun.tools.javac.util.*;
  52 import com.sun.tools.javac.util.DefinedBy.Api;
  53 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  54 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  55 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
  56 import com.sun.tools.javac.util.JCDiagnostic.Warning;
  57 
  58 import java.util.Arrays;
  59 import java.util.Collection;
  60 import java.util.EnumSet;
  61 import java.util.HashSet;
  62 import java.util.Iterator;
  63 import java.util.LinkedHashMap;
  64 import java.util.Map;
  65 import java.util.Set;
  66 import java.util.function.BiFunction;
  67 import java.util.function.BiPredicate;
  68 import java.util.function.Consumer;
  69 import java.util.function.Function;
  70 import java.util.function.Predicate;
  71 import java.util.stream.Stream;
  72 
  73 import javax.lang.model.element.ElementVisitor;
  74 
  75 import static com.sun.tools.javac.code.Flags.*;
  76 import static com.sun.tools.javac.code.Flags.BLOCK;
  77 import static com.sun.tools.javac.code.Flags.STATIC;
  78 import static com.sun.tools.javac.code.Kinds.*;
  79 import static com.sun.tools.javac.code.Kinds.Kind.*;
  80 import static com.sun.tools.javac.code.TypeTag.*;
  81 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
  82 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  83 import static com.sun.tools.javac.util.Iterators.createCompoundIterator;
  84 
  85 /** Helper class for name resolution, used mostly by the attribution phase.
  86  *
  87  *  <p><b>This is NOT part of any supported API.
  88  *  If you write code that depends on this, you do so at your own risk.
  89  *  This code and its internal interfaces are subject to change or
  90  *  deletion without notice.</b>
  91  */
  92 public class Resolve {
  93     protected static final Context.Key<Resolve> resolveKey = new Context.Key<>();
  94 
  95     Names names;
  96     Log log;
  97     Symtab syms;
  98     Attr attr;
  99     DeferredAttr deferredAttr;
 100     Check chk;
 101     Infer infer;
 102     ClassFinder finder;
 103     ModuleFinder moduleFinder;
 104     Types types;
 105     JCDiagnostic.Factory diags;
 106     public final boolean allowFunctionalInterfaceMostSpecific;
 107     public final boolean allowModules;
 108     public final boolean checkVarargsAccessAfterResolution;
 109     private final boolean compactMethodDiags;
 110     private final boolean allowLocalVariableTypeInference;
 111     private final boolean allowYieldStatement;
 112     final EnumSet<VerboseResolutionMode> verboseResolutionMode;
 113 
 114     WriteableScope polymorphicSignatureScope;
 115 
 116     protected Resolve(Context context) {
 117         context.put(resolveKey, this);
 118         syms = Symtab.instance(context);
 119 
 120         varNotFound = new SymbolNotFoundError(ABSENT_VAR);
 121         methodNotFound = new SymbolNotFoundError(ABSENT_MTH);
 122         typeNotFound = new SymbolNotFoundError(ABSENT_TYP);
 123         referenceNotFound = ReferenceLookupResult.error(methodNotFound);
 124 
 125         names = Names.instance(context);
 126         log = Log.instance(context);
 127         attr = Attr.instance(context);
 128         deferredAttr = DeferredAttr.instance(context);
 129         chk = Check.instance(context);
 130         infer = Infer.instance(context);
 131         finder = ClassFinder.instance(context);
 132         moduleFinder = ModuleFinder.instance(context);
 133         types = Types.instance(context);
 134         diags = JCDiagnostic.Factory.instance(context);
 135         Preview preview = Preview.instance(context);
 136         Source source = Source.instance(context);
 137         Options options = Options.instance(context);
 138         compactMethodDiags = options.isSet(Option.XDIAGS, "compact") ||
 139                 options.isUnset(Option.XDIAGS) && options.isUnset("rawDiagnostics");
 140         verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
 141         Target target = Target.instance(context);
 142         allowFunctionalInterfaceMostSpecific = Feature.FUNCTIONAL_INTERFACE_MOST_SPECIFIC.allowedInSource(source);
 143         allowLocalVariableTypeInference = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source);
 144         allowYieldStatement = (!preview.isPreview(Feature.SWITCH_EXPRESSION) || preview.isEnabled()) &&
 145                 Feature.SWITCH_EXPRESSION.allowedInSource(source);
 146         checkVarargsAccessAfterResolution =
 147                 Feature.POST_APPLICABILITY_VARARGS_ACCESS_CHECK.allowedInSource(source);
 148         polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
 149         allowModules = Feature.MODULES.allowedInSource(source);
 150     }
 151 
 152     /** error symbols, which are returned when resolution fails
 153      */
 154     private final SymbolNotFoundError varNotFound;
 155     private final SymbolNotFoundError methodNotFound;
 156     private final SymbolNotFoundError typeNotFound;
 157 
 158     /** empty reference lookup result */
 159     private final ReferenceLookupResult referenceNotFound;
 160 
 161     public static Resolve instance(Context context) {
 162         Resolve instance = context.get(resolveKey);
 163         if (instance == null)
 164             instance = new Resolve(context);
 165         return instance;
 166     }
 167 
 168     private static Symbol bestOf(Symbol s1,
 169                                  Symbol s2) {
 170         return s1.kind.betterThan(s2.kind) ? s1 : s2;
 171     }
 172 
 173     // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
 174     enum VerboseResolutionMode {
 175         SUCCESS("success"),
 176         FAILURE("failure"),
 177         APPLICABLE("applicable"),
 178         INAPPLICABLE("inapplicable"),
 179         DEFERRED_INST("deferred-inference"),
 180         PREDEF("predef"),
 181         OBJECT_INIT("object-init"),
 182         INTERNAL("internal");
 183 
 184         final String opt;
 185 
 186         private VerboseResolutionMode(String opt) {
 187             this.opt = opt;
 188         }
 189 
 190         static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
 191             String s = opts.get("debug.verboseResolution");
 192             EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
 193             if (s == null) return res;
 194             if (s.contains("all")) {
 195                 res = EnumSet.allOf(VerboseResolutionMode.class);
 196             }
 197             Collection<String> args = Arrays.asList(s.split(","));
 198             for (VerboseResolutionMode mode : values()) {
 199                 if (args.contains(mode.opt)) {
 200                     res.add(mode);
 201                 } else if (args.contains("-" + mode.opt)) {
 202                     res.remove(mode);
 203                 }
 204             }
 205             return res;
 206         }
 207     }
 208 
 209     void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
 210             List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
 211         boolean success = !bestSoFar.kind.isResolutionError();
 212 
 213         if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
 214             return;
 215         } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
 216             return;
 217         }
 218 
 219         if (bestSoFar.name == names.init &&
 220                 bestSoFar.owner == syms.objectType.tsym &&
 221                 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
 222             return; //skip diags for Object constructor resolution
 223         } else if (site == syms.predefClass.type &&
 224                 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
 225             return; //skip spurious diags for predef symbols (i.e. operators)
 226         } else if (currentResolutionContext.internalResolution &&
 227                 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
 228             return;
 229         }
 230 
 231         int pos = 0;
 232         int mostSpecificPos = -1;
 233         ListBuffer<JCDiagnostic> subDiags = new ListBuffer<>();
 234         for (Candidate c : currentResolutionContext.candidates) {
 235             if (currentResolutionContext.step != c.step ||
 236                     (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
 237                     (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
 238                 continue;
 239             } else {
 240                 subDiags.append(c.isApplicable() ?
 241                         getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
 242                         getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
 243                 if (c.sym == bestSoFar)
 244                     mostSpecificPos = pos;
 245                 pos++;
 246             }
 247         }
 248         String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
 249         List<Type> argtypes2 = argtypes.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step));
 250         JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
 251                 site.tsym, mostSpecificPos, currentResolutionContext.step,
 252                 methodArguments(argtypes2),
 253                 methodArguments(typeargtypes));
 254         JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
 255         log.report(d);
 256     }
 257 
 258     JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
 259         JCDiagnostic subDiag = null;
 260         if (sym.type.hasTag(FORALL)) {
 261             subDiag = diags.fragment(Fragments.PartialInstSig(inst));
 262         }
 263 
 264         String key = subDiag == null ?
 265                 "applicable.method.found" :
 266                 "applicable.method.found.1";
 267 
 268         return diags.fragment(key, pos, sym, subDiag);
 269     }
 270 
 271     JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
 272         return diags.fragment(Fragments.NotApplicableMethodFound(pos, sym, subDiag));
 273     }
 274     // </editor-fold>
 275 
 276 /* ************************************************************************
 277  * Identifier resolution
 278  *************************************************************************/
 279 
 280     /** An environment is "static" if its static level is greater than
 281      *  the one of its outer environment
 282      */
 283     protected static boolean isStatic(Env<AttrContext> env) {
 284         return env.outer != null && env.info.staticLevel > env.outer.info.staticLevel;
 285     }
 286 
 287     /** An environment is an "initializer" if it is a constructor or
 288      *  an instance initializer.
 289      */
 290     static boolean isInitializer(Env<AttrContext> env) {
 291         Symbol owner = env.info.scope.owner;
 292         return owner.isConstructor() ||
 293             owner.owner.kind == TYP &&
 294             (owner.kind == VAR ||
 295              owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
 296             (owner.flags() & STATIC) == 0;
 297     }
 298 
 299     /** Is class accessible in given environment?
 300      *  @param env    The current environment.
 301      *  @param c      The class whose accessibility is checked.
 302      */
 303     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
 304         return isAccessible(env, c, false);
 305     }
 306 
 307     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
 308 
 309         /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
 310            to refer to an inaccessible type
 311         */
 312         if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
 313             return true;
 314 
 315         if (env.info.visitingServiceImplementation &&
 316             env.toplevel.modle == c.packge().modle) {
 317             return true;
 318         }
 319 
 320         boolean isAccessible = false;
 321         switch ((short)(c.flags() & AccessFlags)) {
 322             case PRIVATE:
 323                 isAccessible =
 324                     env.enclClass.sym.outermostClass() ==
 325                     c.owner.outermostClass();
 326                 break;
 327             case 0:
 328                 isAccessible =
 329                     env.toplevel.packge == c.owner // fast special case
 330                     ||
 331                     env.toplevel.packge == c.packge();
 332                 break;
 333             default: // error recovery
 334                 isAccessible = true;
 335                 break;
 336             case PUBLIC:
 337                 if (allowModules) {
 338                     ModuleSymbol currModule = env.toplevel.modle;
 339                     currModule.complete();
 340                     PackageSymbol p = c.packge();
 341                     isAccessible =
 342                         currModule == p.modle ||
 343                         currModule.visiblePackages.get(p.fullname) == p ||
 344                         p == syms.rootPackage ||
 345                         (p.modle == syms.unnamedModule && currModule.readModules.contains(p.modle));
 346                 } else {
 347                     isAccessible = true;
 348                 }
 349                 break;
 350             case PROTECTED:
 351                 isAccessible =
 352                     env.toplevel.packge == c.owner // fast special case
 353                     ||
 354                     env.toplevel.packge == c.packge()
 355                     ||
 356                     isInnerSubClass(env.enclClass.sym, c.owner);
 357                 break;
 358         }
 359         return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
 360             isAccessible :
 361             isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
 362     }
 363     //where
 364         /** Is given class a subclass of given base class, or an inner class
 365          *  of a subclass?
 366          *  Return null if no such class exists.
 367          *  @param c     The class which is the subclass or is contained in it.
 368          *  @param base  The base class
 369          */
 370         private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
 371             while (c != null && !c.isSubClass(base, types)) {
 372                 c = c.owner.enclClass();
 373             }
 374             return c != null;
 375         }
 376 
 377     boolean isAccessible(Env<AttrContext> env, Type t) {
 378         return isAccessible(env, t, false);
 379     }
 380 
 381     boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
 382         return (t.hasTag(ARRAY))
 383             ? isAccessible(env, types.cvarUpperBound(types.elemtype(t)))
 384             : isAccessible(env, t.tsym, checkInner);
 385     }
 386 
 387     /** Is symbol accessible as a member of given type in given environment?
 388      *  @param env    The current environment.
 389      *  @param site   The type of which the tested symbol is regarded
 390      *                as a member.
 391      *  @param sym    The symbol.
 392      */
 393     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
 394         return isAccessible(env, site, sym, false);
 395     }
 396     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
 397         if (sym.name == names.init && sym.owner != site.tsym) return false;
 398 
 399         /* 15.9.5.1: Note that it is possible for the signature of the anonymous constructor
 400            to refer to an inaccessible type
 401         */
 402         if (env.enclMethod != null && (env.enclMethod.mods.flags & ANONCONSTR) != 0)
 403             return true;
 404 
 405         if (env.info.visitingServiceImplementation &&
 406             env.toplevel.modle == sym.packge().modle) {
 407             return true;
 408         }
 409 
 410         switch ((short)(sym.flags() & AccessFlags)) {
 411         case PRIVATE:
 412             return
 413                 (env.enclClass.sym == sym.owner // fast special case
 414                  ||
 415                  env.enclClass.sym.outermostClass() ==
 416                  sym.owner.outermostClass())
 417                 &&
 418                 sym.isInheritedIn(site.tsym, types);
 419         case 0:
 420             return
 421                 (env.toplevel.packge == sym.owner.owner // fast special case
 422                  ||
 423                  env.toplevel.packge == sym.packge())
 424                 &&
 425                 isAccessible(env, site, checkInner)
 426                 &&
 427                 sym.isInheritedIn(site.tsym, types)
 428                 &&
 429                 notOverriddenIn(site, sym);
 430         case PROTECTED:
 431             return
 432                 (env.toplevel.packge == sym.owner.owner // fast special case
 433                  ||
 434                  env.toplevel.packge == sym.packge()
 435                  ||
 436                  isProtectedAccessible(sym, env.enclClass.sym, site)
 437                  ||
 438                  // OK to select instance method or field from 'super' or type name
 439                  // (but type names should be disallowed elsewhere!)
 440                  env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
 441                 &&
 442                 isAccessible(env, site, checkInner)
 443                 &&
 444                 notOverriddenIn(site, sym);
 445         default: // this case includes erroneous combinations as well
 446             return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
 447         }
 448     }
 449     //where
 450     /* `sym' is accessible only if not overridden by
 451      * another symbol which is a member of `site'
 452      * (because, if it is overridden, `sym' is not strictly
 453      * speaking a member of `site'). A polymorphic signature method
 454      * cannot be overridden (e.g. MH.invokeExact(Object[])).
 455      */
 456     private boolean notOverriddenIn(Type site, Symbol sym) {
 457         if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
 458             return true;
 459         else {
 460             Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
 461             return (s2 == null || s2 == sym || sym.owner == s2.owner ||
 462                     !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
 463         }
 464     }
 465     //where
 466         /** Is given protected symbol accessible if it is selected from given site
 467          *  and the selection takes place in given class?
 468          *  @param sym     The symbol with protected access
 469          *  @param c       The class where the access takes place
 470          *  @site          The type of the qualifier
 471          */
 472         private
 473         boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
 474             Type newSite = site.hasTag(TYPEVAR) ? site.getUpperBound() : site;
 475             while (c != null &&
 476                    !(c.isSubClass(sym.owner, types) &&
 477                      (c.flags() & INTERFACE) == 0 &&
 478                      // In JLS 2e 6.6.2.1, the subclass restriction applies
 479                      // only to instance fields and methods -- types are excluded
 480                      // regardless of whether they are declared 'static' or not.
 481                      ((sym.flags() & STATIC) != 0 || sym.kind == TYP || newSite.tsym.isSubClass(c, types))))
 482                 c = c.owner.enclClass();
 483             return c != null;
 484         }
 485 
 486     /**
 487      * Performs a recursive scan of a type looking for accessibility problems
 488      * from current attribution environment
 489      */
 490     void checkAccessibleType(Env<AttrContext> env, Type t) {
 491         accessibilityChecker.visit(t, env);
 492     }
 493 
 494     /**
 495      * Accessibility type-visitor
 496      */
 497     Types.SimpleVisitor<Void, Env<AttrContext>> accessibilityChecker =
 498             new Types.SimpleVisitor<Void, Env<AttrContext>>() {
 499 
 500         void visit(List<Type> ts, Env<AttrContext> env) {
 501             for (Type t : ts) {
 502                 visit(t, env);
 503             }
 504         }
 505 
 506         public Void visitType(Type t, Env<AttrContext> env) {
 507             return null;
 508         }
 509 
 510         @Override
 511         public Void visitArrayType(ArrayType t, Env<AttrContext> env) {
 512             visit(t.elemtype, env);
 513             return null;
 514         }
 515 
 516         @Override
 517         public Void visitClassType(ClassType t, Env<AttrContext> env) {
 518             visit(t.getTypeArguments(), env);
 519             if (!isAccessible(env, t, true)) {
 520                 accessBase(new AccessError(env, null, t.tsym), env.tree.pos(), env.enclClass.sym, t, t.tsym.name, true);
 521             }
 522             return null;
 523         }
 524 
 525         @Override
 526         public Void visitWildcardType(WildcardType t, Env<AttrContext> env) {
 527             visit(t.type, env);
 528             return null;
 529         }
 530 
 531         @Override
 532         public Void visitMethodType(MethodType t, Env<AttrContext> env) {
 533             visit(t.getParameterTypes(), env);
 534             visit(t.getReturnType(), env);
 535             visit(t.getThrownTypes(), env);
 536             return null;
 537         }
 538     };
 539 
 540     /** Try to instantiate the type of a method so that it fits
 541      *  given type arguments and argument types. If successful, return
 542      *  the method's instantiated type, else return null.
 543      *  The instantiation will take into account an additional leading
 544      *  formal parameter if the method is an instance method seen as a member
 545      *  of an under determined site. In this case, we treat site as an additional
 546      *  parameter and the parameters of the class containing the method as
 547      *  additional type variables that get instantiated.
 548      *
 549      *  @param env         The current environment
 550      *  @param site        The type of which the method is a member.
 551      *  @param m           The method symbol.
 552      *  @param argtypes    The invocation's given value arguments.
 553      *  @param typeargtypes    The invocation's given type arguments.
 554      *  @param allowBoxing Allow boxing conversions of arguments.
 555      *  @param useVarargs Box trailing arguments into an array for varargs.
 556      */
 557     Type rawInstantiate(Env<AttrContext> env,
 558                         Type site,
 559                         Symbol m,
 560                         ResultInfo resultInfo,
 561                         List<Type> argtypes,
 562                         List<Type> typeargtypes,
 563                         boolean allowBoxing,
 564                         boolean useVarargs,
 565                         Warner warn) throws Infer.InferenceException {
 566         Type mt = types.memberType(site, m);
 567         // tvars is the list of formal type variables for which type arguments
 568         // need to inferred.
 569         List<Type> tvars = List.nil();
 570         if (typeargtypes == null) typeargtypes = List.nil();
 571         if (!mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
 572             // This is not a polymorphic method, but typeargs are supplied
 573             // which is fine, see JLS 15.12.2.1
 574         } else if (mt.hasTag(FORALL) && typeargtypes.nonEmpty()) {
 575             ForAll pmt = (ForAll) mt;
 576             if (typeargtypes.length() != pmt.tvars.length())
 577                  // not enough args
 578                 throw new InapplicableMethodException(diags.fragment(Fragments.WrongNumberTypeArgs(Integer.toString(pmt.tvars.length()))));
 579             // Check type arguments are within bounds
 580             List<Type> formals = pmt.tvars;
 581             List<Type> actuals = typeargtypes;
 582             while (formals.nonEmpty() && actuals.nonEmpty()) {
 583                 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
 584                                                 pmt.tvars, typeargtypes);
 585                 for (; bounds.nonEmpty(); bounds = bounds.tail) {
 586                     if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) {
 587                         throw new InapplicableMethodException(diags.fragment(Fragments.ExplicitParamDoNotConformToBounds(actuals.head, bounds)));
 588                     }
 589                 }
 590                 formals = formals.tail;
 591                 actuals = actuals.tail;
 592             }
 593             mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
 594         } else if (mt.hasTag(FORALL)) {
 595             ForAll pmt = (ForAll) mt;
 596             List<Type> tvars1 = types.newInstances(pmt.tvars);
 597             tvars = tvars.appendList(tvars1);
 598             mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
 599         }
 600 
 601         // find out whether we need to go the slow route via infer
 602         boolean instNeeded = tvars.tail != null; /*inlined: tvars.nonEmpty()*/
 603         for (List<Type> l = argtypes;
 604              l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
 605              l = l.tail) {
 606             if (l.head.hasTag(FORALL)) instNeeded = true;
 607         }
 608 
 609         if (instNeeded) {
 610             return infer.instantiateMethod(env,
 611                                     tvars,
 612                                     (MethodType)mt,
 613                                     resultInfo,
 614                                     (MethodSymbol)m,
 615                                     argtypes,
 616                                     allowBoxing,
 617                                     useVarargs,
 618                                     currentResolutionContext,
 619                                     warn);
 620         }
 621 
 622         DeferredAttr.DeferredAttrContext dc = currentResolutionContext.deferredAttrContext(m, infer.emptyContext, resultInfo, warn);
 623         currentResolutionContext.methodCheck.argumentsAcceptable(env, dc,
 624                                 argtypes, mt.getParameterTypes(), warn);
 625         dc.complete();
 626         return mt;
 627     }
 628 
 629     Type checkMethod(Env<AttrContext> env,
 630                      Type site,
 631                      Symbol m,
 632                      ResultInfo resultInfo,
 633                      List<Type> argtypes,
 634                      List<Type> typeargtypes,
 635                      Warner warn) {
 636         MethodResolutionContext prevContext = currentResolutionContext;
 637         try {
 638             currentResolutionContext = new MethodResolutionContext();
 639             currentResolutionContext.attrMode = (resultInfo.pt == Infer.anyPoly) ?
 640                     AttrMode.SPECULATIVE : DeferredAttr.AttrMode.CHECK;
 641             if (env.tree.hasTag(JCTree.Tag.REFERENCE)) {
 642                 //method/constructor references need special check class
 643                 //to handle inference variables in 'argtypes' (might happen
 644                 //during an unsticking round)
 645                 currentResolutionContext.methodCheck =
 646                         new MethodReferenceCheck(resultInfo.checkContext.inferenceContext());
 647             }
 648             MethodResolutionPhase step = currentResolutionContext.step = env.info.pendingResolutionPhase;
 649             return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
 650                     step.isBoxingRequired(), step.isVarargsRequired(), warn);
 651         }
 652         finally {
 653             currentResolutionContext = prevContext;
 654         }
 655     }
 656 
 657     /** Same but returns null instead throwing a NoInstanceException
 658      */
 659     Type instantiate(Env<AttrContext> env,
 660                      Type site,
 661                      Symbol m,
 662                      ResultInfo resultInfo,
 663                      List<Type> argtypes,
 664                      List<Type> typeargtypes,
 665                      boolean allowBoxing,
 666                      boolean useVarargs,
 667                      Warner warn) {
 668         try {
 669             return rawInstantiate(env, site, m, resultInfo, argtypes, typeargtypes,
 670                                   allowBoxing, useVarargs, warn);
 671         } catch (InapplicableMethodException ex) {
 672             return null;
 673         }
 674     }
 675 
 676     /**
 677      * This interface defines an entry point that should be used to perform a
 678      * method check. A method check usually consist in determining as to whether
 679      * a set of types (actuals) is compatible with another set of types (formals).
 680      * Since the notion of compatibility can vary depending on the circumstances,
 681      * this interfaces allows to easily add new pluggable method check routines.
 682      */
 683     interface MethodCheck {
 684         /**
 685          * Main method check routine. A method check usually consist in determining
 686          * as to whether a set of types (actuals) is compatible with another set of
 687          * types (formals). If an incompatibility is found, an unchecked exception
 688          * is assumed to be thrown.
 689          */
 690         void argumentsAcceptable(Env<AttrContext> env,
 691                                 DeferredAttrContext deferredAttrContext,
 692                                 List<Type> argtypes,
 693                                 List<Type> formals,
 694                                 Warner warn);
 695 
 696         /**
 697          * Retrieve the method check object that will be used during a
 698          * most specific check.
 699          */
 700         MethodCheck mostSpecificCheck(List<Type> actuals);
 701     }
 702 
 703     /**
 704      * Helper enum defining all method check diagnostics (used by resolveMethodCheck).
 705      */
 706     enum MethodCheckDiag {
 707         /**
 708          * Actuals and formals differs in length.
 709          */
 710         ARITY_MISMATCH("arg.length.mismatch", "infer.arg.length.mismatch"),
 711         /**
 712          * An actual is incompatible with a formal.
 713          */
 714         ARG_MISMATCH("no.conforming.assignment.exists", "infer.no.conforming.assignment.exists"),
 715         /**
 716          * An actual is incompatible with the varargs element type.
 717          */
 718         VARARG_MISMATCH("varargs.argument.mismatch", "infer.varargs.argument.mismatch"),
 719         /**
 720          * The varargs element type is inaccessible.
 721          */
 722         INACCESSIBLE_VARARGS("inaccessible.varargs.type", "inaccessible.varargs.type");
 723 
 724         final String basicKey;
 725         final String inferKey;
 726 
 727         MethodCheckDiag(String basicKey, String inferKey) {
 728             this.basicKey = basicKey;
 729             this.inferKey = inferKey;
 730         }
 731 
 732         String regex() {
 733             return String.format("([a-z]*\\.)*(%s|%s)", basicKey, inferKey);
 734         }
 735     }
 736 
 737     /**
 738      * Dummy method check object. All methods are deemed applicable, regardless
 739      * of their formal parameter types.
 740      */
 741     MethodCheck nilMethodCheck = new MethodCheck() {
 742         public void argumentsAcceptable(Env<AttrContext> env, DeferredAttrContext deferredAttrContext, List<Type> argtypes, List<Type> formals, Warner warn) {
 743             //do nothing - method always applicable regardless of actuals
 744         }
 745 
 746         public MethodCheck mostSpecificCheck(List<Type> actuals) {
 747             return this;
 748         }
 749     };
 750 
 751     /**
 752      * Base class for 'real' method checks. The class defines the logic for
 753      * iterating through formals and actuals and provides and entry point
 754      * that can be used by subclasses in order to define the actual check logic.
 755      */
 756     abstract class AbstractMethodCheck implements MethodCheck {
 757         @Override
 758         public void argumentsAcceptable(final Env<AttrContext> env,
 759                                     DeferredAttrContext deferredAttrContext,
 760                                     List<Type> argtypes,
 761                                     List<Type> formals,
 762                                     Warner warn) {
 763             //should we expand formals?
 764             boolean useVarargs = deferredAttrContext.phase.isVarargsRequired();
 765             JCTree callTree = treeForDiagnostics(env);
 766             List<JCExpression> trees = TreeInfo.args(callTree);
 767 
 768             //inference context used during this method check
 769             InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
 770 
 771             Type varargsFormal = useVarargs ? formals.last() : null;
 772 
 773             if (varargsFormal == null &&
 774                     argtypes.size() != formals.size()) {
 775                 reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
 776             }
 777 
 778             while (argtypes.nonEmpty() && formals.head != varargsFormal) {
 779                 DiagnosticPosition pos = trees != null ? trees.head : null;
 780                 checkArg(pos, false, argtypes.head, formals.head, deferredAttrContext, warn);
 781                 argtypes = argtypes.tail;
 782                 formals = formals.tail;
 783                 trees = trees != null ? trees.tail : trees;
 784             }
 785 
 786             if (formals.head != varargsFormal) {
 787                 reportMC(callTree, MethodCheckDiag.ARITY_MISMATCH, inferenceContext); // not enough args
 788             }
 789 
 790             if (useVarargs) {
 791                 //note: if applicability check is triggered by most specific test,
 792                 //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
 793                 final Type elt = types.elemtype(varargsFormal);
 794                 while (argtypes.nonEmpty()) {
 795                     DiagnosticPosition pos = trees != null ? trees.head : null;
 796                     checkArg(pos, true, argtypes.head, elt, deferredAttrContext, warn);
 797                     argtypes = argtypes.tail;
 798                     trees = trees != null ? trees.tail : trees;
 799                 }
 800             }
 801         }
 802 
 803             // where
 804             private JCTree treeForDiagnostics(Env<AttrContext> env) {
 805                 return env.info.preferredTreeForDiagnostics != null ? env.info.preferredTreeForDiagnostics : env.tree;
 806             }
 807 
 808         /**
 809          * Does the actual argument conforms to the corresponding formal?
 810          */
 811         abstract void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn);
 812 
 813         protected void reportMC(DiagnosticPosition pos, MethodCheckDiag diag, InferenceContext inferenceContext, Object... args) {
 814             boolean inferDiag = inferenceContext != infer.emptyContext;
 815             if (inferDiag && (!diag.inferKey.equals(diag.basicKey))) {
 816                 Object[] args2 = new Object[args.length + 1];
 817                 System.arraycopy(args, 0, args2, 1, args.length);
 818                 args2[0] = inferenceContext.inferenceVars();
 819                 args = args2;
 820             }
 821             String key = inferDiag ? diag.inferKey : diag.basicKey;
 822             throw inferDiag ?
 823                 infer.error(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args)) :
 824                 methodCheckFailure.setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args));
 825         }
 826 
 827         /**
 828          * To eliminate the overhead associated with allocating an exception object in such an
 829          * hot execution path, we use flyweight pattern - and share the same exception instance
 830          * across multiple method check failures.
 831          */
 832         class SharedInapplicableMethodException extends InapplicableMethodException {
 833             private static final long serialVersionUID = 0;
 834 
 835             SharedInapplicableMethodException() {
 836                 super(null);
 837             }
 838 
 839             SharedInapplicableMethodException setMessage(JCDiagnostic details) {
 840                 this.diagnostic = details;
 841                 return this;
 842             }
 843         }
 844 
 845         SharedInapplicableMethodException methodCheckFailure = new SharedInapplicableMethodException();
 846 
 847         public MethodCheck mostSpecificCheck(List<Type> actuals) {
 848             return nilMethodCheck;
 849         }
 850 
 851     }
 852 
 853     /**
 854      * Arity-based method check. A method is applicable if the number of actuals
 855      * supplied conforms to the method signature.
 856      */
 857     MethodCheck arityMethodCheck = new AbstractMethodCheck() {
 858         @Override
 859         void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
 860             //do nothing - actual always compatible to formals
 861         }
 862 
 863         @Override
 864         public String toString() {
 865             return "arityMethodCheck";
 866         }
 867     };
 868 
 869     /**
 870      * Main method applicability routine. Given a list of actual types A,
 871      * a list of formal types F, determines whether the types in A are
 872      * compatible (by method invocation conversion) with the types in F.
 873      *
 874      * Since this routine is shared between overload resolution and method
 875      * type-inference, a (possibly empty) inference context is used to convert
 876      * formal types to the corresponding 'undet' form ahead of a compatibility
 877      * check so that constraints can be propagated and collected.
 878      *
 879      * Moreover, if one or more types in A is a deferred type, this routine uses
 880      * DeferredAttr in order to perform deferred attribution. If one or more actual
 881      * deferred types are stuck, they are placed in a queue and revisited later
 882      * after the remainder of the arguments have been seen. If this is not sufficient
 883      * to 'unstuck' the argument, a cyclic inference error is called out.
 884      *
 885      * A method check handler (see above) is used in order to report errors.
 886      */
 887     MethodCheck resolveMethodCheck = new AbstractMethodCheck() {
 888 
 889         @Override
 890         void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
 891             ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
 892             mresult.check(pos, actual);
 893         }
 894 
 895         @Override
 896         public void argumentsAcceptable(final Env<AttrContext> env,
 897                                     DeferredAttrContext deferredAttrContext,
 898                                     List<Type> argtypes,
 899                                     List<Type> formals,
 900                                     Warner warn) {
 901             super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
 902             // should we check varargs element type accessibility?
 903             if (deferredAttrContext.phase.isVarargsRequired()) {
 904                 if (deferredAttrContext.mode == AttrMode.CHECK || !checkVarargsAccessAfterResolution) {
 905                     varargsAccessible(env, types.elemtype(formals.last()), deferredAttrContext.inferenceContext);
 906                 }
 907             }
 908         }
 909 
 910         /**
 911          * Test that the runtime array element type corresponding to 't' is accessible.  't' should be the
 912          * varargs element type of either the method invocation type signature (after inference completes)
 913          * or the method declaration signature (before inference completes).
 914          */
 915         private void varargsAccessible(final Env<AttrContext> env, final Type t, final InferenceContext inferenceContext) {
 916             if (inferenceContext.free(t)) {
 917                 inferenceContext.addFreeTypeListener(List.of(t),
 918                         solvedContext -> varargsAccessible(env, solvedContext.asInstType(t), solvedContext));
 919             } else {
 920                 if (!isAccessible(env, types.erasure(t))) {
 921                     Symbol location = env.enclClass.sym;
 922                     reportMC(env.tree, MethodCheckDiag.INACCESSIBLE_VARARGS, inferenceContext, t, Kinds.kindName(location), location);
 923                 }
 924             }
 925         }
 926 
 927         private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
 928                 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
 929             CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
 930                 MethodCheckDiag methodDiag = varargsCheck ?
 931                                  MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
 932 
 933                 @Override
 934                 public void report(DiagnosticPosition pos, JCDiagnostic details) {
 935                     reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
 936                 }
 937             };
 938             return new MethodResultInfo(to, checkContext);
 939         }
 940 
 941         @Override
 942         public MethodCheck mostSpecificCheck(List<Type> actuals) {
 943             return new MostSpecificCheck(actuals);
 944         }
 945 
 946         @Override
 947         public String toString() {
 948             return "resolveMethodCheck";
 949         }
 950     };
 951 
 952     /**
 953      * This class handles method reference applicability checks; since during
 954      * these checks it's sometime possible to have inference variables on
 955      * the actual argument types list, the method applicability check must be
 956      * extended so that inference variables are 'opened' as needed.
 957      */
 958     class MethodReferenceCheck extends AbstractMethodCheck {
 959 
 960         InferenceContext pendingInferenceContext;
 961 
 962         MethodReferenceCheck(InferenceContext pendingInferenceContext) {
 963             this.pendingInferenceContext = pendingInferenceContext;
 964         }
 965 
 966         @Override
 967         void checkArg(DiagnosticPosition pos, boolean varargs, Type actual, Type formal, DeferredAttrContext deferredAttrContext, Warner warn) {
 968             ResultInfo mresult = methodCheckResult(varargs, formal, deferredAttrContext, warn);
 969             mresult.check(pos, actual);
 970         }
 971 
 972         private ResultInfo methodCheckResult(final boolean varargsCheck, Type to,
 973                 final DeferredAttr.DeferredAttrContext deferredAttrContext, Warner rsWarner) {
 974             CheckContext checkContext = new MethodCheckContext(!deferredAttrContext.phase.isBoxingRequired(), deferredAttrContext, rsWarner) {
 975                 MethodCheckDiag methodDiag = varargsCheck ?
 976                                  MethodCheckDiag.VARARG_MISMATCH : MethodCheckDiag.ARG_MISMATCH;
 977 
 978                 @Override
 979                 public boolean compatible(Type found, Type req, Warner warn) {
 980                     found = pendingInferenceContext.asUndetVar(found);
 981                     if (found.hasTag(UNDETVAR) && req.isPrimitive()) {
 982                         req = types.boxedClass(req).type;
 983                     }
 984                     return super.compatible(found, req, warn);
 985                 }
 986 
 987                 @Override
 988                 public void report(DiagnosticPosition pos, JCDiagnostic details) {
 989                     reportMC(pos, methodDiag, deferredAttrContext.inferenceContext, details);
 990                 }
 991             };
 992             return new MethodResultInfo(to, checkContext);
 993         }
 994 
 995         @Override
 996         public MethodCheck mostSpecificCheck(List<Type> actuals) {
 997             return new MostSpecificCheck(actuals);
 998         }
 999 
1000         @Override
1001         public String toString() {
1002             return "MethodReferenceCheck";
1003         }
1004     }
1005 
1006     /**
1007      * Check context to be used during method applicability checks. A method check
1008      * context might contain inference variables.
1009      */
1010     abstract class MethodCheckContext implements CheckContext {
1011 
1012         boolean strict;
1013         DeferredAttrContext deferredAttrContext;
1014         Warner rsWarner;
1015 
1016         public MethodCheckContext(boolean strict, DeferredAttrContext deferredAttrContext, Warner rsWarner) {
1017            this.strict = strict;
1018            this.deferredAttrContext = deferredAttrContext;
1019            this.rsWarner = rsWarner;
1020         }
1021 
1022         public boolean compatible(Type found, Type req, Warner warn) {
1023             InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
1024             return strict ?
1025                     types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) :
1026                     types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn);
1027         }
1028 
1029         public void report(DiagnosticPosition pos, JCDiagnostic details) {
1030             throw new InapplicableMethodException(details);
1031         }
1032 
1033         public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
1034             return rsWarner;
1035         }
1036 
1037         public InferenceContext inferenceContext() {
1038             return deferredAttrContext.inferenceContext;
1039         }
1040 
1041         public DeferredAttrContext deferredAttrContext() {
1042             return deferredAttrContext;
1043         }
1044 
1045         @Override
1046         public String toString() {
1047             return "MethodCheckContext";
1048         }
1049     }
1050 
1051     /**
1052      * ResultInfo class to be used during method applicability checks. Check
1053      * for deferred types goes through special path.
1054      */
1055     class MethodResultInfo extends ResultInfo {
1056 
1057         public MethodResultInfo(Type pt, CheckContext checkContext) {
1058             attr.super(KindSelector.VAL, pt, checkContext);
1059         }
1060 
1061         @Override
1062         protected Type check(DiagnosticPosition pos, Type found) {
1063             if (found.hasTag(DEFERRED)) {
1064                 DeferredType dt = (DeferredType)found;
1065                 return dt.check(this);
1066             } else {
1067                 Type uResult = U(found);
1068                 Type capturedType = pos == null || pos.getTree() == null ?
1069                         types.capture(uResult) :
1070                         checkContext.inferenceContext()
1071                             .cachedCapture(pos.getTree(), uResult, true);
1072                 return super.check(pos, chk.checkNonVoid(pos, capturedType));
1073             }
1074         }
1075 
1076         /**
1077          * javac has a long-standing 'simplification' (see 6391995):
1078          * given an actual argument type, the method check is performed
1079          * on its upper bound. This leads to inconsistencies when an
1080          * argument type is checked against itself. For example, given
1081          * a type-variable T, it is not true that {@code U(T) <: T},
1082          * so we need to guard against that.
1083          */
1084         private Type U(Type found) {
1085             return found == pt ?
1086                     found : types.cvarUpperBound(found);
1087         }
1088 
1089         @Override
1090         protected MethodResultInfo dup(Type newPt) {
1091             return new MethodResultInfo(newPt, checkContext);
1092         }
1093 
1094         @Override
1095         protected ResultInfo dup(CheckContext newContext) {
1096             return new MethodResultInfo(pt, newContext);
1097         }
1098 
1099         @Override
1100         protected ResultInfo dup(Type newPt, CheckContext newContext) {
1101             return new MethodResultInfo(newPt, newContext);
1102         }
1103     }
1104 
1105     /**
1106      * Most specific method applicability routine. Given a list of actual types A,
1107      * a list of formal types F1, and a list of formal types F2, the routine determines
1108      * as to whether the types in F1 can be considered more specific than those in F2 w.r.t.
1109      * argument types A.
1110      */
1111     class MostSpecificCheck implements MethodCheck {
1112 
1113         List<Type> actuals;
1114 
1115         MostSpecificCheck(List<Type> actuals) {
1116             this.actuals = actuals;
1117         }
1118 
1119         @Override
1120         public void argumentsAcceptable(final Env<AttrContext> env,
1121                                     DeferredAttrContext deferredAttrContext,
1122                                     List<Type> formals1,
1123                                     List<Type> formals2,
1124                                     Warner warn) {
1125             formals2 = adjustArgs(formals2, deferredAttrContext.msym, formals1.length(), deferredAttrContext.phase.isVarargsRequired());
1126             while (formals2.nonEmpty()) {
1127                 ResultInfo mresult = methodCheckResult(formals2.head, deferredAttrContext, warn, actuals.head);
1128                 mresult.check(null, formals1.head);
1129                 formals1 = formals1.tail;
1130                 formals2 = formals2.tail;
1131                 actuals = actuals.isEmpty() ? actuals : actuals.tail;
1132             }
1133         }
1134 
1135        /**
1136         * Create a method check context to be used during the most specific applicability check
1137         */
1138         ResultInfo methodCheckResult(Type to, DeferredAttr.DeferredAttrContext deferredAttrContext,
1139                Warner rsWarner, Type actual) {
1140             return attr.new ResultInfo(KindSelector.VAL, to,
1141                    new MostSpecificCheckContext(deferredAttrContext, rsWarner, actual));
1142         }
1143 
1144         /**
1145          * Subclass of method check context class that implements most specific
1146          * method conversion. If the actual type under analysis is a deferred type
1147          * a full blown structural analysis is carried out.
1148          */
1149         class MostSpecificCheckContext extends MethodCheckContext {
1150 
1151             Type actual;
1152 
1153             public MostSpecificCheckContext(DeferredAttrContext deferredAttrContext, Warner rsWarner, Type actual) {
1154                 super(true, deferredAttrContext, rsWarner);
1155                 this.actual = actual;
1156             }
1157 
1158             public boolean compatible(Type found, Type req, Warner warn) {
1159                 if (allowFunctionalInterfaceMostSpecific &&
1160                         unrelatedFunctionalInterfaces(found, req) &&
1161                         (actual != null && actual.getTag() == DEFERRED)) {
1162                     DeferredType dt = (DeferredType) actual;
1163                     JCTree speculativeTree = dt.speculativeTree(deferredAttrContext);
1164                     if (speculativeTree != deferredAttr.stuckTree) {
1165                         return functionalInterfaceMostSpecific(found, req, speculativeTree);
1166                     }
1167                 }
1168                 return compatibleBySubtyping(found, req);
1169             }
1170 
1171             private boolean compatibleBySubtyping(Type found, Type req) {
1172                 if (!strict && found.isPrimitive() != req.isPrimitive()) {
1173                     found = found.isPrimitive() ? types.boxedClass(found).type : types.unboxedType(found);
1174                 }
1175                 return types.isSubtypeNoCapture(found, deferredAttrContext.inferenceContext.asUndetVar(req));
1176             }
1177 
1178             /** Whether {@code t} and {@code s} are unrelated functional interface types. */
1179             private boolean unrelatedFunctionalInterfaces(Type t, Type s) {
1180                 return types.isFunctionalInterface(t.tsym) &&
1181                        types.isFunctionalInterface(s.tsym) &&
1182                        unrelatedInterfaces(t, s);
1183             }
1184 
1185             /** Whether {@code t} and {@code s} are unrelated interface types; recurs on intersections. **/
1186             private boolean unrelatedInterfaces(Type t, Type s) {
1187                 if (t.isCompound()) {
1188                     for (Type ti : types.interfaces(t)) {
1189                         if (!unrelatedInterfaces(ti, s)) {
1190                             return false;
1191                         }
1192                     }
1193                     return true;
1194                 } else if (s.isCompound()) {
1195                     for (Type si : types.interfaces(s)) {
1196                         if (!unrelatedInterfaces(t, si)) {
1197                             return false;
1198                         }
1199                     }
1200                     return true;
1201                 } else {
1202                     return types.asSuper(t, s.tsym) == null && types.asSuper(s, t.tsym) == null;
1203                 }
1204             }
1205 
1206             /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1207             private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) {
1208                 Type tDesc = types.findDescriptorType(types.capture(t));
1209                 Type tDescNoCapture = types.findDescriptorType(t);
1210                 Type sDesc = types.findDescriptorType(s);
1211                 final List<Type> tTypeParams = tDesc.getTypeArguments();
1212                 final List<Type> tTypeParamsNoCapture = tDescNoCapture.getTypeArguments();
1213                 final List<Type> sTypeParams = sDesc.getTypeArguments();
1214 
1215                 // compare type parameters
1216                 if (tDesc.hasTag(FORALL) && !types.hasSameBounds((ForAll) tDesc, (ForAll) tDescNoCapture)) {
1217                     return false;
1218                 }
1219                 // can't use Types.hasSameBounds on sDesc because bounds may have ivars
1220                 List<Type> tIter = tTypeParams;
1221                 List<Type> sIter = sTypeParams;
1222                 while (tIter.nonEmpty() && sIter.nonEmpty()) {
1223                     Type tBound = tIter.head.getUpperBound();
1224                     Type sBound = types.subst(sIter.head.getUpperBound(), sTypeParams, tTypeParams);
1225                     if (tBound.containsAny(tTypeParams) && inferenceContext().free(sBound)) {
1226                         return false;
1227                     }
1228                     if (!types.isSameType(tBound, inferenceContext().asUndetVar(sBound))) {
1229                         return false;
1230                     }
1231                     tIter = tIter.tail;
1232                     sIter = sIter.tail;
1233                 }
1234                 if (!tIter.isEmpty() || !sIter.isEmpty()) {
1235                     return false;
1236                 }
1237 
1238                 // compare parameters
1239                 List<Type> tParams = tDesc.getParameterTypes();
1240                 List<Type> tParamsNoCapture = tDescNoCapture.getParameterTypes();
1241                 List<Type> sParams = sDesc.getParameterTypes();
1242                 while (tParams.nonEmpty() && tParamsNoCapture.nonEmpty() && sParams.nonEmpty()) {
1243                     Type tParam = tParams.head;
1244                     Type tParamNoCapture = types.subst(tParamsNoCapture.head, tTypeParamsNoCapture, tTypeParams);
1245                     Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams);
1246                     if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) {
1247                         return false;
1248                     }
1249                     if (!types.isSubtype(inferenceContext().asUndetVar(sParam), tParam)) {
1250                         return false;
1251                     }
1252                     if (!types.isSameType(tParamNoCapture, inferenceContext().asUndetVar(sParam))) {
1253                         return false;
1254                     }
1255                     tParams = tParams.tail;
1256                     tParamsNoCapture = tParamsNoCapture.tail;
1257                     sParams = sParams.tail;
1258                 }
1259                 if (!tParams.isEmpty() || !tParamsNoCapture.isEmpty() || !sParams.isEmpty()) {
1260                     return false;
1261                 }
1262 
1263                 // compare returns
1264                 Type tRet = tDesc.getReturnType();
1265                 Type sRet = types.subst(sDesc.getReturnType(), sTypeParams, tTypeParams);
1266                 if (tRet.containsAny(tTypeParams) && inferenceContext().free(sRet)) {
1267                     return false;
1268                 }
1269                 MostSpecificFunctionReturnChecker msc = new MostSpecificFunctionReturnChecker(tRet, sRet);
1270                 msc.scan(tree);
1271                 return msc.result;
1272             }
1273 
1274             /**
1275              * Tests whether one functional interface type can be considered more specific
1276              * than another unrelated functional interface type for the scanned expression.
1277              */
1278             class MostSpecificFunctionReturnChecker extends DeferredAttr.PolyScanner {
1279 
1280                 final Type tRet;
1281                 final Type sRet;
1282                 boolean result;
1283 
1284                 /** Parameters {@code t} and {@code s} are unrelated functional interface types. */
1285                 MostSpecificFunctionReturnChecker(Type tRet, Type sRet) {
1286                     this.tRet = tRet;
1287                     this.sRet = sRet;
1288                     result = true;
1289                 }
1290 
1291                 @Override
1292                 void skip(JCTree tree) {
1293                     result &= false;
1294                 }
1295 
1296                 @Override
1297                 public void visitConditional(JCConditional tree) {
1298                     scan(asExpr(tree.truepart));
1299                     scan(asExpr(tree.falsepart));
1300                 }
1301 
1302                 @Override
1303                 public void visitReference(JCMemberReference tree) {
1304                     if (sRet.hasTag(VOID)) {
1305                         result &= true;
1306                     } else if (tRet.hasTag(VOID)) {
1307                         result &= false;
1308                     } else if (tRet.isPrimitive() != sRet.isPrimitive()) {
1309                         boolean retValIsPrimitive =
1310                                 tree.refPolyKind == PolyKind.STANDALONE &&
1311                                 tree.sym.type.getReturnType().isPrimitive();
1312                         result &= (retValIsPrimitive == tRet.isPrimitive()) &&
1313                                   (retValIsPrimitive != sRet.isPrimitive());
1314                     } else {
1315                         result &= compatibleBySubtyping(tRet, sRet);
1316                     }
1317                 }
1318 
1319                 @Override
1320                 public void visitParens(JCParens tree) {
1321                     scan(asExpr(tree.expr));
1322                 }
1323 
1324                 @Override
1325                 public void visitLambda(JCLambda tree) {
1326                     if (sRet.hasTag(VOID)) {
1327                         result &= true;
1328                     } else if (tRet.hasTag(VOID)) {
1329                         result &= false;
1330                     } else {
1331                         List<JCExpression> lambdaResults = lambdaResults(tree);
1332                         if (!lambdaResults.isEmpty() && unrelatedFunctionalInterfaces(tRet, sRet)) {
1333                             for (JCExpression expr : lambdaResults) {
1334                                 result &= functionalInterfaceMostSpecific(tRet, sRet, expr);
1335                             }
1336                         } else if (!lambdaResults.isEmpty() && tRet.isPrimitive() != sRet.isPrimitive()) {
1337                             for (JCExpression expr : lambdaResults) {
1338                                 boolean retValIsPrimitive = expr.isStandalone() && expr.type.isPrimitive();
1339                                 result &= (retValIsPrimitive == tRet.isPrimitive()) &&
1340                                         (retValIsPrimitive != sRet.isPrimitive());
1341                             }
1342                         } else {
1343                             result &= compatibleBySubtyping(tRet, sRet);
1344                         }
1345                     }
1346                 }
1347                 //where
1348 
1349                 private List<JCExpression> lambdaResults(JCLambda lambda) {
1350                     if (lambda.getBodyKind() == JCTree.JCLambda.BodyKind.EXPRESSION) {
1351                         return List.of(asExpr((JCExpression) lambda.body));
1352                     } else {
1353                         final ListBuffer<JCExpression> buffer = new ListBuffer<>();
1354                         DeferredAttr.LambdaReturnScanner lambdaScanner =
1355                                 new DeferredAttr.LambdaReturnScanner() {
1356                                     @Override
1357                                     public void visitReturn(JCReturn tree) {
1358                                         if (tree.expr != null) {
1359                                             buffer.append(asExpr(tree.expr));
1360                                         }
1361                                     }
1362                                 };
1363                         lambdaScanner.scan(lambda.body);
1364                         return buffer.toList();
1365                     }
1366                 }
1367 
1368                 private JCExpression asExpr(JCExpression expr) {
1369                     if (expr.type.hasTag(DEFERRED)) {
1370                         JCTree speculativeTree = ((DeferredType)expr.type).speculativeTree(deferredAttrContext);
1371                         if (speculativeTree != deferredAttr.stuckTree) {
1372                             expr = (JCExpression)speculativeTree;
1373                         }
1374                     }
1375                     return expr;
1376                 }
1377             }
1378 
1379         }
1380 
1381         public MethodCheck mostSpecificCheck(List<Type> actuals) {
1382             Assert.error("Cannot get here!");
1383             return null;
1384         }
1385     }
1386 
1387     public static class InapplicableMethodException extends RuntimeException {
1388         private static final long serialVersionUID = 0;
1389 
1390         transient JCDiagnostic diagnostic;
1391 
1392         InapplicableMethodException(JCDiagnostic diag) {
1393             this.diagnostic = diag;
1394         }
1395 
1396         public JCDiagnostic getDiagnostic() {
1397             return diagnostic;
1398         }
1399     }
1400 
1401 /* ***************************************************************************
1402  *  Symbol lookup
1403  *  the following naming conventions for arguments are used
1404  *
1405  *       env      is the environment where the symbol was mentioned
1406  *       site     is the type of which the symbol is a member
1407  *       name     is the symbol's name
1408  *                if no arguments are given
1409  *       argtypes are the value arguments, if we search for a method
1410  *
1411  *  If no symbol was found, a ResolveError detailing the problem is returned.
1412  ****************************************************************************/
1413 
1414     /** Find field. Synthetic fields are always skipped.
1415      *  @param env     The current environment.
1416      *  @param site    The original type from where the selection takes place.
1417      *  @param name    The name of the field.
1418      *  @param c       The class to search for the field. This is always
1419      *                 a superclass or implemented interface of site's class.
1420      */
1421     Symbol findField(Env<AttrContext> env,
1422                      Type site,
1423                      Name name,
1424                      TypeSymbol c) {
1425         while (c.type.hasTag(TYPEVAR))
1426             c = c.type.getUpperBound().tsym;
1427         Symbol bestSoFar = varNotFound;
1428         Symbol sym;
1429         for (Symbol s : c.members().getSymbolsByName(name)) {
1430             if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1431                 return isAccessible(env, site, s)
1432                     ? s : new AccessError(env, site, s);
1433             }
1434         }
1435         Type st = types.supertype(c.type);
1436         if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
1437             sym = findField(env, site, name, st.tsym);
1438             bestSoFar = bestOf(bestSoFar, sym);
1439         }
1440         for (List<Type> l = types.interfaces(c.type);
1441              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1442              l = l.tail) {
1443             sym = findField(env, site, name, l.head.tsym);
1444             if (bestSoFar.exists() && sym.exists() &&
1445                 sym.owner != bestSoFar.owner)
1446                 bestSoFar = new AmbiguityError(bestSoFar, sym);
1447             else
1448                 bestSoFar = bestOf(bestSoFar, sym);
1449         }
1450         return bestSoFar;
1451     }
1452 
1453     /** Resolve a field identifier, throw a fatal error if not found.
1454      *  @param pos       The position to use for error reporting.
1455      *  @param env       The environment current at the method invocation.
1456      *  @param site      The type of the qualifying expression, in which
1457      *                   identifier is searched.
1458      *  @param name      The identifier's name.
1459      */
1460     public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
1461                                           Type site, Name name) {
1462         Symbol sym = findField(env, site, name, site.tsym);
1463         if (sym.kind == VAR) return (VarSymbol)sym;
1464         else throw new FatalError(
1465                  diags.fragment(Fragments.FatalErrCantLocateField(name)));
1466     }
1467 
1468     /** Find unqualified variable or field with given name.
1469      *  Synthetic fields always skipped.
1470      *  @param env     The current environment.
1471      *  @param name    The name of the variable or field.
1472      */
1473     Symbol findVar(Env<AttrContext> env, Name name) {
1474         Symbol bestSoFar = varNotFound;
1475         Env<AttrContext> env1 = env;
1476         boolean staticOnly = false;
1477         while (env1.outer != null) {
1478             Symbol sym = null;
1479             if (isStatic(env1)) staticOnly = true;
1480             for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
1481                 if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
1482                     sym = s;
1483                     break;
1484                 }
1485             }
1486             if (sym == null) {
1487                 sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
1488             }
1489             if (sym.exists()) {
1490                 if (staticOnly &&
1491                     sym.kind == VAR &&
1492                     sym.owner.kind == TYP &&
1493                     (sym.flags() & STATIC) == 0)
1494                     return new StaticError(sym);
1495                 else
1496                     return sym;
1497             } else {
1498                 bestSoFar = bestOf(bestSoFar, sym);
1499             }
1500 
1501             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1502             env1 = env1.outer;
1503         }
1504 
1505         Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass);
1506         if (sym.exists())
1507             return sym;
1508         if (bestSoFar.exists())
1509             return bestSoFar;
1510 
1511         Symbol origin = null;
1512         for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
1513             for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
1514                 if (currentSymbol.kind != VAR)
1515                     continue;
1516                 // invariant: sym.kind == Symbol.Kind.VAR
1517                 if (!bestSoFar.kind.isResolutionError() &&
1518                     currentSymbol.owner != bestSoFar.owner)
1519                     return new AmbiguityError(bestSoFar, currentSymbol);
1520                 else if (!bestSoFar.kind.betterThan(VAR)) {
1521                     origin = sc.getOrigin(currentSymbol).owner;
1522                     bestSoFar = isAccessible(env, origin.type, currentSymbol)
1523                         ? currentSymbol : new AccessError(env, origin.type, currentSymbol);
1524                 }
1525             }
1526             if (bestSoFar.exists()) break;
1527         }
1528         if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
1529             return bestSoFar.clone(origin);
1530         else
1531             return bestSoFar;
1532     }
1533 
1534     Warner noteWarner = new Warner();
1535 
1536     /** Select the best method for a call site among two choices.
1537      *  @param env              The current environment.
1538      *  @param site             The original type from where the
1539      *                          selection takes place.
1540      *  @param argtypes         The invocation's value arguments,
1541      *  @param typeargtypes     The invocation's type arguments,
1542      *  @param sym              Proposed new best match.
1543      *  @param bestSoFar        Previously found best match.
1544      *  @param allowBoxing Allow boxing conversions of arguments.
1545      *  @param useVarargs Box trailing arguments into an array for varargs.
1546      */
1547     @SuppressWarnings("fallthrough")
1548     Symbol selectBest(Env<AttrContext> env,
1549                       Type site,
1550                       List<Type> argtypes,
1551                       List<Type> typeargtypes,
1552                       Symbol sym,
1553                       Symbol bestSoFar,
1554                       boolean allowBoxing,
1555                       boolean useVarargs) {
1556         if (sym.kind == ERR ||
1557                 (site.tsym != sym.owner && !sym.isInheritedIn(site.tsym, types)) ||
1558                 !notOverriddenIn(site, sym)) {
1559             return bestSoFar;
1560         } else if (useVarargs && (sym.flags() & VARARGS) == 0) {
1561             return bestSoFar.kind.isResolutionError() ?
1562                     new BadVarargsMethod((ResolveError)bestSoFar.baseSymbol()) :
1563                     bestSoFar;
1564         }
1565         Assert.check(!sym.kind.isResolutionError());
1566         try {
1567             types.noWarnings.clear();
1568             Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
1569                                allowBoxing, useVarargs, types.noWarnings);
1570             currentResolutionContext.addApplicableCandidate(sym, mt);
1571         } catch (InapplicableMethodException ex) {
1572             currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
1573             switch (bestSoFar.kind) {
1574                 case ABSENT_MTH:
1575                     return new InapplicableSymbolError(currentResolutionContext);
1576                 case WRONG_MTH:
1577                     bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
1578                 default:
1579                     return bestSoFar;
1580             }
1581         }
1582         if (!isAccessible(env, site, sym)) {
1583             return (bestSoFar.kind == ABSENT_MTH)
1584                 ? new AccessError(env, site, sym)
1585                 : bestSoFar;
1586         }
1587         return (bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS)
1588             ? sym
1589             : mostSpecific(argtypes, sym, bestSoFar, env, site, useVarargs);
1590     }
1591 
1592     /* Return the most specific of the two methods for a call,
1593      *  given that both are accessible and applicable.
1594      *  @param m1               A new candidate for most specific.
1595      *  @param m2               The previous most specific candidate.
1596      *  @param env              The current environment.
1597      *  @param site             The original type from where the selection
1598      *                          takes place.
1599      *  @param allowBoxing Allow boxing conversions of arguments.
1600      *  @param useVarargs Box trailing arguments into an array for varargs.
1601      */
1602     Symbol mostSpecific(List<Type> argtypes, Symbol m1,
1603                         Symbol m2,
1604                         Env<AttrContext> env,
1605                         final Type site,
1606                         boolean useVarargs) {
1607         switch (m2.kind) {
1608         case MTH:
1609             if (m1 == m2) return m1;
1610             boolean m1SignatureMoreSpecific =
1611                     signatureMoreSpecific(argtypes, env, site, m1, m2, useVarargs);
1612             boolean m2SignatureMoreSpecific =
1613                     signatureMoreSpecific(argtypes, env, site, m2, m1, useVarargs);
1614             if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
1615                 Type mt1 = types.memberType(site, m1);
1616                 Type mt2 = types.memberType(site, m2);
1617                 if (!types.overrideEquivalent(mt1, mt2))
1618                     return ambiguityError(m1, m2);
1619 
1620                 // same signature; select (a) the non-bridge method, or
1621                 // (b) the one that overrides the other, or (c) the concrete
1622                 // one, or (d) merge both abstract signatures
1623                 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
1624                     return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
1625 
1626                 if (m1.baseSymbol() == m2.baseSymbol()) {
1627                     // this is the same imported symbol which has been cloned twice.
1628                     // Return the first one (either will do).
1629                     return m1;
1630                 }
1631 
1632                 // if one overrides or hides the other, use it
1633                 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
1634                 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
1635                 // the two owners can never be the same if the target methods are compiled from source,
1636                 // but we need to protect against cases where the methods are defined in some classfile
1637                 // and make sure we issue an ambiguity error accordingly (by skipping the logic below).
1638                 if (m1Owner != m2Owner) {
1639                     if (types.asSuper(m1Owner.type, m2Owner) != null &&
1640                         ((m1.owner.flags_field & INTERFACE) == 0 ||
1641                          (m2.owner.flags_field & INTERFACE) != 0) &&
1642                         m1.overrides(m2, m1Owner, types, false))
1643                         return m1;
1644                     if (types.asSuper(m2Owner.type, m1Owner) != null &&
1645                         ((m2.owner.flags_field & INTERFACE) == 0 ||
1646                          (m1.owner.flags_field & INTERFACE) != 0) &&
1647                         m2.overrides(m1, m2Owner, types, false))
1648                         return m2;
1649                 }
1650                 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
1651                 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
1652                 if (m1Abstract && !m2Abstract) return m2;
1653                 if (m2Abstract && !m1Abstract) return m1;
1654                 // both abstract or both concrete
1655                 return ambiguityError(m1, m2);
1656             }
1657             if (m1SignatureMoreSpecific) return m1;
1658             if (m2SignatureMoreSpecific) return m2;
1659             return ambiguityError(m1, m2);
1660         case AMBIGUOUS:
1661             //compare m1 to ambiguous methods in m2
1662             AmbiguityError e = (AmbiguityError)m2.baseSymbol();
1663             boolean m1MoreSpecificThanAnyAmbiguous = true;
1664             boolean allAmbiguousMoreSpecificThanM1 = true;
1665             for (Symbol s : e.ambiguousSyms) {
1666                 Symbol moreSpecific = mostSpecific(argtypes, m1, s, env, site, useVarargs);
1667                 m1MoreSpecificThanAnyAmbiguous &= moreSpecific == m1;
1668                 allAmbiguousMoreSpecificThanM1 &= moreSpecific == s;
1669             }
1670             if (m1MoreSpecificThanAnyAmbiguous)
1671                 return m1;
1672             //if m1 is more specific than some ambiguous methods, but other ambiguous methods are
1673             //more specific than m1, add it as a new ambiguous method:
1674             if (!allAmbiguousMoreSpecificThanM1)
1675                 e.addAmbiguousSymbol(m1);
1676             return e;
1677         default:
1678             throw new AssertionError();
1679         }
1680     }
1681     //where
1682     private boolean signatureMoreSpecific(List<Type> actuals, Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean useVarargs) {
1683         noteWarner.clear();
1684         int maxLength = Math.max(
1685                             Math.max(m1.type.getParameterTypes().length(), actuals.length()),
1686                             m2.type.getParameterTypes().length());
1687         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1688         try {
1689             currentResolutionContext = new MethodResolutionContext();
1690             currentResolutionContext.step = prevResolutionContext.step;
1691             currentResolutionContext.methodCheck =
1692                     prevResolutionContext.methodCheck.mostSpecificCheck(actuals);
1693             Type mst = instantiate(env, site, m2, null,
1694                     adjustArgs(types.cvarLowerBounds(types.memberType(site, m1).getParameterTypes()), m1, maxLength, useVarargs), null,
1695                     false, useVarargs, noteWarner);
1696             return mst != null &&
1697                     !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
1698         } finally {
1699             currentResolutionContext = prevResolutionContext;
1700         }
1701     }
1702 
1703     List<Type> adjustArgs(List<Type> args, Symbol msym, int length, boolean allowVarargs) {
1704         if ((msym.flags() & VARARGS) != 0 && allowVarargs) {
1705             Type varargsElem = types.elemtype(args.last());
1706             if (varargsElem == null) {
1707                 Assert.error("Bad varargs = " + args.last() + " " + msym);
1708             }
1709             List<Type> newArgs = args.reverse().tail.prepend(varargsElem).reverse();
1710             while (newArgs.length() < length) {
1711                 newArgs = newArgs.append(newArgs.last());
1712             }
1713             return newArgs;
1714         } else {
1715             return args;
1716         }
1717     }
1718     //where
1719     Symbol ambiguityError(Symbol m1, Symbol m2) {
1720         if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1721             return (m1.flags() & CLASH) == 0 ? m1 : m2;
1722         } else {
1723             return new AmbiguityError(m1, m2);
1724         }
1725     }
1726 
1727     Symbol findMethodInScope(Env<AttrContext> env,
1728             Type site,
1729             Name name,
1730             List<Type> argtypes,
1731             List<Type> typeargtypes,
1732             Scope sc,
1733             Symbol bestSoFar,
1734             boolean allowBoxing,
1735             boolean useVarargs,
1736             boolean abstractok) {
1737         for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) {
1738             bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
1739                     bestSoFar, allowBoxing, useVarargs);
1740         }
1741         return bestSoFar;
1742     }
1743     //where
1744         class LookupFilter implements Filter<Symbol> {
1745 
1746             boolean abstractOk;
1747 
1748             LookupFilter(boolean abstractOk) {
1749                 this.abstractOk = abstractOk;
1750             }
1751 
1752             public boolean accepts(Symbol s) {
1753                 long flags = s.flags();
1754                 return s.kind == MTH &&
1755                         (flags & SYNTHETIC) == 0 &&
1756                         (abstractOk ||
1757                         (flags & DEFAULT) != 0 ||
1758                         (flags & ABSTRACT) == 0);
1759             }
1760         }
1761 
1762     /** Find best qualified method matching given name, type and value
1763      *  arguments.
1764      *  @param env       The current environment.
1765      *  @param site      The original type from where the selection
1766      *                   takes place.
1767      *  @param name      The method's name.
1768      *  @param argtypes  The method's value arguments.
1769      *  @param typeargtypes The method's type arguments
1770      *  @param allowBoxing Allow boxing conversions of arguments.
1771      *  @param useVarargs Box trailing arguments into an array for varargs.
1772      */
1773     Symbol findMethod(Env<AttrContext> env,
1774                       Type site,
1775                       Name name,
1776                       List<Type> argtypes,
1777                       List<Type> typeargtypes,
1778                       boolean allowBoxing,
1779                       boolean useVarargs) {
1780         Symbol bestSoFar = methodNotFound;
1781         bestSoFar = findMethod(env,
1782                           site,
1783                           name,
1784                           argtypes,
1785                           typeargtypes,
1786                           site.tsym.type,
1787                           bestSoFar,
1788                           allowBoxing,
1789                           useVarargs);
1790         return bestSoFar;
1791     }
1792     // where
1793     private Symbol findMethod(Env<AttrContext> env,
1794                               Type site,
1795                               Name name,
1796                               List<Type> argtypes,
1797                               List<Type> typeargtypes,
1798                               Type intype,
1799                               Symbol bestSoFar,
1800                               boolean allowBoxing,
1801                               boolean useVarargs) {
1802         @SuppressWarnings({"unchecked","rawtypes"})
1803         List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
1804 
1805         InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
1806         for (TypeSymbol s : superclasses(intype)) {
1807             bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1808                     s.members(), bestSoFar, allowBoxing, useVarargs, true);
1809             if (name == names.init) return bestSoFar;
1810             iphase = (iphase == null) ? null : iphase.update(s, this);
1811             if (iphase != null) {
1812                 for (Type itype : types.interfaces(s.type)) {
1813                     itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
1814                 }
1815             }
1816         }
1817 
1818         Symbol concrete = bestSoFar.kind.isValid() &&
1819                 (bestSoFar.flags() & ABSTRACT) == 0 ?
1820                 bestSoFar : methodNotFound;
1821 
1822         for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
1823             //keep searching for abstract methods
1824             for (Type itype : itypes[iphase2.ordinal()]) {
1825                 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
1826                 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
1827                         (itype.tsym.flags() & DEFAULT) == 0) continue;
1828                 bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
1829                         itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, true);
1830                 if (concrete != bestSoFar &&
1831                     concrete.kind.isValid() &&
1832                     bestSoFar.kind.isValid() &&
1833                         types.isSubSignature(concrete.type, bestSoFar.type)) {
1834                     //this is an hack - as javac does not do full membership checks
1835                     //most specific ends up comparing abstract methods that might have
1836                     //been implemented by some concrete method in a subclass and,
1837                     //because of raw override, it is possible for an abstract method
1838                     //to be more specific than the concrete method - so we need
1839                     //to explicitly call that out (see CR 6178365)
1840                     bestSoFar = concrete;
1841                 }
1842             }
1843         }
1844         return bestSoFar;
1845     }
1846 
1847     enum InterfaceLookupPhase {
1848         ABSTRACT_OK() {
1849             @Override
1850             InterfaceLookupPhase update(Symbol s, Resolve rs) {
1851                 //We should not look for abstract methods if receiver is a concrete class
1852                 //(as concrete classes are expected to implement all abstracts coming
1853                 //from superinterfaces)
1854                 if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
1855                     return this;
1856                 } else {
1857                     return DEFAULT_OK;
1858                 }
1859             }
1860         },
1861         DEFAULT_OK() {
1862             @Override
1863             InterfaceLookupPhase update(Symbol s, Resolve rs) {
1864                 return this;
1865             }
1866         };
1867 
1868         abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
1869     }
1870 
1871     /**
1872      * Return an Iterable object to scan the superclasses of a given type.
1873      * It's crucial that the scan is done lazily, as we don't want to accidentally
1874      * access more supertypes than strictly needed (as this could trigger completion
1875      * errors if some of the not-needed supertypes are missing/ill-formed).
1876      */
1877     Iterable<TypeSymbol> superclasses(final Type intype) {
1878         return () -> new Iterator<TypeSymbol>() {
1879 
1880             List<TypeSymbol> seen = List.nil();
1881             TypeSymbol currentSym = symbolFor(intype);
1882             TypeSymbol prevSym = null;
1883 
1884             public boolean hasNext() {
1885                 if (currentSym == syms.noSymbol) {
1886                     currentSym = symbolFor(types.supertype(prevSym.type));
1887                 }
1888                 return currentSym != null;
1889             }
1890 
1891             public TypeSymbol next() {
1892                 prevSym = currentSym;
1893                 currentSym = syms.noSymbol;
1894                 Assert.check(prevSym != null || prevSym != syms.noSymbol);
1895                 return prevSym;
1896             }
1897 
1898             public void remove() {
1899                 throw new UnsupportedOperationException();
1900             }
1901 
1902             TypeSymbol symbolFor(Type t) {
1903                 if (!t.hasTag(CLASS) &&
1904                         !t.hasTag(TYPEVAR)) {
1905                     return null;
1906                 }
1907                 t = types.skipTypeVars(t, false);
1908                 if (seen.contains(t.tsym)) {
1909                     //degenerate case in which we have a circular
1910                     //class hierarchy - because of ill-formed classfiles
1911                     return null;
1912                 }
1913                 seen = seen.prepend(t.tsym);
1914                 return t.tsym;
1915             }
1916         };
1917     }
1918 
1919     /** Find unqualified method matching given name, type and value arguments.
1920      *  @param env       The current environment.
1921      *  @param name      The method's name.
1922      *  @param argtypes  The method's value arguments.
1923      *  @param typeargtypes  The method's type arguments.
1924      *  @param allowBoxing Allow boxing conversions of arguments.
1925      *  @param useVarargs Box trailing arguments into an array for varargs.
1926      */
1927     Symbol findFun(Env<AttrContext> env, Name name,
1928                    List<Type> argtypes, List<Type> typeargtypes,
1929                    boolean allowBoxing, boolean useVarargs) {
1930         Symbol bestSoFar = methodNotFound;
1931         Env<AttrContext> env1 = env;
1932         boolean staticOnly = false;
1933         while (env1.outer != null) {
1934             if (isStatic(env1)) staticOnly = true;
1935             Assert.check(env1.info.preferredTreeForDiagnostics == null);
1936             env1.info.preferredTreeForDiagnostics = env.tree;
1937             try {
1938                 Symbol sym = findMethod(
1939                     env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
1940                     allowBoxing, useVarargs);
1941                 if (sym.exists()) {
1942                     if (staticOnly &&
1943                         sym.kind == MTH &&
1944                         sym.owner.kind == TYP &&
1945                         (sym.flags() & STATIC) == 0) return new StaticError(sym);
1946                     else return sym;
1947                 } else {
1948                     bestSoFar = bestOf(bestSoFar, sym);
1949                 }
1950             } finally {
1951                 env1.info.preferredTreeForDiagnostics = null;
1952             }
1953             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1954             env1 = env1.outer;
1955         }
1956 
1957         Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
1958                                 typeargtypes, allowBoxing, useVarargs);
1959         if (sym.exists())
1960             return sym;
1961 
1962         for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
1963             Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
1964             if (currentSym.kind == MTH) {
1965                 if (currentSym.owner.type != origin.type)
1966                     currentSym = currentSym.clone(origin);
1967                 if (!isAccessible(env, origin.type, currentSym))
1968                     currentSym = new AccessError(env, origin.type, currentSym);
1969                 bestSoFar = selectBest(env, origin.type,
1970                                        argtypes, typeargtypes,
1971                                        currentSym, bestSoFar,
1972                                        allowBoxing, useVarargs);
1973             }
1974         }
1975         if (bestSoFar.exists())
1976             return bestSoFar;
1977 
1978         for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) {
1979             Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner;
1980             if (currentSym.kind == MTH) {
1981                 if (currentSym.owner.type != origin.type)
1982                     currentSym = currentSym.clone(origin);
1983                 if (!isAccessible(env, origin.type, currentSym))
1984                     currentSym = new AccessError(env, origin.type, currentSym);
1985                 bestSoFar = selectBest(env, origin.type,
1986                                        argtypes, typeargtypes,
1987                                        currentSym, bestSoFar,
1988                                        allowBoxing, useVarargs);
1989             }
1990         }
1991         return bestSoFar;
1992     }
1993 
1994     /** Load toplevel or member class with given fully qualified name and
1995      *  verify that it is accessible.
1996      *  @param env       The current environment.
1997      *  @param name      The fully qualified name of the class to be loaded.
1998      */
1999     Symbol loadClass(Env<AttrContext> env, Name name, RecoveryLoadClass recoveryLoadClass) {
2000         try {
2001             ClassSymbol c = finder.loadClass(env.toplevel.modle, name);
2002             return isAccessible(env, c) ? c : new AccessError(env, null, c);
2003         } catch (ClassFinder.BadClassFile err) {
2004             return new BadClassFileError(err);
2005         } catch (CompletionFailure ex) {
2006             Symbol candidate = recoveryLoadClass.loadClass(env, name);
2007 
2008             if (candidate != null) {
2009                 return candidate;
2010             }
2011 
2012             return typeNotFound;
2013         }
2014     }
2015 
2016     public interface RecoveryLoadClass {
2017         Symbol loadClass(Env<AttrContext> env, Name name);
2018     }
2019 
2020     private final RecoveryLoadClass noRecovery = (env, name) -> null;
2021 
2022     private final RecoveryLoadClass doRecoveryLoadClass = new RecoveryLoadClass() {
2023         @Override public Symbol loadClass(Env<AttrContext> env, Name name) {
2024             List<Name> candidates = Convert.classCandidates(name);
2025             return lookupInvisibleSymbol(env, name,
2026                                          n -> () -> createCompoundIterator(candidates,
2027                                                                            c -> syms.getClassesForName(c)
2028                                                                                     .iterator()),
2029                                          (ms, n) -> {
2030                 for (Name candidate : candidates) {
2031                     try {
2032                         return finder.loadClass(ms, candidate);
2033                     } catch (CompletionFailure cf) {
2034                         //ignore
2035                     }
2036                 }
2037                 return null;
2038             }, sym -> sym.kind == Kind.TYP, typeNotFound);
2039         }
2040     };
2041 
2042     private final RecoveryLoadClass namedImportScopeRecovery = (env, name) -> {
2043         Scope importScope = env.toplevel.namedImportScope;
2044         Symbol existing = importScope.findFirst(Convert.shortName(name),
2045                                                 sym -> sym.kind == TYP && sym.flatName() == name);
2046 
2047         if (existing != null) {
2048             return new InvisibleSymbolError(env, true, existing);
2049         }
2050         return null;
2051     };
2052 
2053     private final RecoveryLoadClass starImportScopeRecovery = (env, name) -> {
2054         Scope importScope = env.toplevel.starImportScope;
2055         Symbol existing = importScope.findFirst(Convert.shortName(name),
2056                                                 sym -> sym.kind == TYP && sym.flatName() == name);
2057 
2058         if (existing != null) {
2059             try {
2060                 existing = finder.loadClass(existing.packge().modle, name);
2061 
2062                 return new InvisibleSymbolError(env, true, existing);
2063             } catch (CompletionFailure cf) {
2064                 //ignore
2065             }
2066         }
2067 
2068         return null;
2069     };
2070 
2071     Symbol lookupPackage(Env<AttrContext> env, Name name) {
2072         PackageSymbol pack = syms.lookupPackage(env.toplevel.modle, name);
2073 
2074         if (allowModules && isImportOnDemand(env, name)) {
2075             if (pack.members().isEmpty()) {
2076                 return lookupInvisibleSymbol(env, name, syms::getPackagesForName, syms::enterPackage, sym -> {
2077                     sym.complete();
2078                     return !sym.members().isEmpty();
2079                 }, pack);
2080             }
2081         }
2082 
2083         return pack;
2084     }
2085 
2086     private boolean isImportOnDemand(Env<AttrContext> env, Name name) {
2087         if (!env.tree.hasTag(IMPORT))
2088             return false;
2089 
2090         JCTree qualid = ((JCImport) env.tree).qualid;
2091 
2092         if (!qualid.hasTag(SELECT))
2093             return false;
2094 
2095         if (TreeInfo.name(qualid) != names.asterisk)
2096             return false;
2097 
2098         return TreeInfo.fullName(((JCFieldAccess) qualid).selected) == name;
2099     }
2100 
2101     private <S extends Symbol> Symbol lookupInvisibleSymbol(Env<AttrContext> env,
2102                                                             Name name,
2103                                                             Function<Name, Iterable<S>> get,
2104                                                             BiFunction<ModuleSymbol, Name, S> load,
2105                                                             Predicate<S> validate,
2106                                                             Symbol defaultResult) {
2107         //even if a class/package cannot be found in the current module and among packages in modules
2108         //it depends on that are exported for any or this module, the class/package may exist internally
2109         //in some of these modules, or may exist in a module on which this module does not depend.
2110         //Provide better diagnostic in such cases by looking for the class in any module:
2111         Iterable<? extends S> candidates = get.apply(name);
2112 
2113         for (S sym : candidates) {
2114             if (validate.test(sym))
2115                 return createInvisibleSymbolError(env, sym);
2116         }
2117 
2118         Set<ModuleSymbol> recoverableModules = new HashSet<>(syms.getAllModules());
2119 
2120         recoverableModules.add(syms.unnamedModule);
2121         recoverableModules.remove(env.toplevel.modle);
2122 
2123         for (ModuleSymbol ms : recoverableModules) {
2124             //avoid overly eager completing classes from source-based modules, as those
2125             //may not be completable with the current compiler settings:
2126             if (ms.sourceLocation == null) {
2127                 if (ms.classLocation == null) {
2128                     ms = moduleFinder.findModule(ms);
2129                 }
2130 
2131                 if (ms.kind != ERR) {
2132                     S sym = load.apply(ms, name);
2133 
2134                     if (sym != null && validate.test(sym)) {
2135                         return createInvisibleSymbolError(env, sym);
2136                     }
2137                 }
2138             }
2139         }
2140 
2141         return defaultResult;
2142     }
2143 
2144     private Symbol createInvisibleSymbolError(Env<AttrContext> env, Symbol sym) {
2145         if (symbolPackageVisible(env, sym)) {
2146             return new AccessError(env, null, sym);
2147         } else {
2148             return new InvisibleSymbolError(env, false, sym);
2149         }
2150     }
2151 
2152     private boolean symbolPackageVisible(Env<AttrContext> env, Symbol sym) {
2153         ModuleSymbol envMod = env.toplevel.modle;
2154         PackageSymbol symPack = sym.packge();
2155         return envMod == symPack.modle ||
2156                envMod.visiblePackages.containsKey(symPack.fullname);
2157     }
2158 
2159     /**
2160      * Find a type declared in a scope (not inherited).  Return null
2161      * if none is found.
2162      *  @param env       The current environment.
2163      *  @param site      The original type from where the selection takes
2164      *                   place.
2165      *  @param name      The type's name.
2166      *  @param c         The class to search for the member type. This is
2167      *                   always a superclass or implemented interface of
2168      *                   site's class.
2169      */
2170     Symbol findImmediateMemberType(Env<AttrContext> env,
2171                                    Type site,
2172                                    Name name,
2173                                    TypeSymbol c) {
2174         for (Symbol sym : c.members().getSymbolsByName(name)) {
2175             if (sym.kind == TYP) {
2176                 return isAccessible(env, site, sym)
2177                     ? sym
2178                     : new AccessError(env, site, sym);
2179             }
2180         }
2181         return typeNotFound;
2182     }
2183 
2184     /** Find a member type inherited from a superclass or interface.
2185      *  @param env       The current environment.
2186      *  @param site      The original type from where the selection takes
2187      *                   place.
2188      *  @param name      The type's name.
2189      *  @param c         The class to search for the member type. This is
2190      *                   always a superclass or implemented interface of
2191      *                   site's class.
2192      */
2193     Symbol findInheritedMemberType(Env<AttrContext> env,
2194                                    Type site,
2195                                    Name name,
2196                                    TypeSymbol c) {
2197         Symbol bestSoFar = typeNotFound;
2198         Symbol sym;
2199         Type st = types.supertype(c.type);
2200         if (st != null && st.hasTag(CLASS)) {
2201             sym = findMemberType(env, site, name, st.tsym);
2202             bestSoFar = bestOf(bestSoFar, sym);
2203         }
2204         for (List<Type> l = types.interfaces(c.type);
2205              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
2206              l = l.tail) {
2207             sym = findMemberType(env, site, name, l.head.tsym);
2208             if (!bestSoFar.kind.isResolutionError() &&
2209                 !sym.kind.isResolutionError() &&
2210                 sym.owner != bestSoFar.owner)
2211                 bestSoFar = new AmbiguityError(bestSoFar, sym);
2212             else
2213                 bestSoFar = bestOf(bestSoFar, sym);
2214         }
2215         return bestSoFar;
2216     }
2217 
2218     /** Find qualified member type.
2219      *  @param env       The current environment.
2220      *  @param site      The original type from where the selection takes
2221      *                   place.
2222      *  @param name      The type's name.
2223      *  @param c         The class to search for the member type. This is
2224      *                   always a superclass or implemented interface of
2225      *                   site's class.
2226      */
2227     Symbol findMemberType(Env<AttrContext> env,
2228                           Type site,
2229                           Name name,
2230                           TypeSymbol c) {
2231         Symbol sym = findImmediateMemberType(env, site, name, c);
2232 
2233         if (sym != typeNotFound)
2234             return sym;
2235 
2236         return findInheritedMemberType(env, site, name, c);
2237 
2238     }
2239 
2240     /** Find a global type in given scope and load corresponding class.
2241      *  @param env       The current environment.
2242      *  @param scope     The scope in which to look for the type.
2243      *  @param name      The type's name.
2244      */
2245     Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name, RecoveryLoadClass recoveryLoadClass) {
2246         Symbol bestSoFar = typeNotFound;
2247         for (Symbol s : scope.getSymbolsByName(name)) {
2248             Symbol sym = loadClass(env, s.flatName(), recoveryLoadClass);
2249             if (bestSoFar.kind == TYP && sym.kind == TYP &&
2250                 bestSoFar != sym)
2251                 return new AmbiguityError(bestSoFar, sym);
2252             else
2253                 bestSoFar = bestOf(bestSoFar, sym);
2254         }
2255         return bestSoFar;
2256     }
2257 
2258     Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) {
2259         for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
2260             if (sym.kind == TYP) {
2261                 if (staticOnly &&
2262                     sym.type.hasTag(TYPEVAR) &&
2263                     sym.owner.kind == TYP)
2264                     return new StaticError(sym);
2265                 return sym;
2266             }
2267         }
2268         return typeNotFound;
2269     }
2270 
2271     /** Find an unqualified type symbol.
2272      *  @param env       The current environment.
2273      *  @param name      The type's name.
2274      */
2275     Symbol findType(Env<AttrContext> env, Name name) {
2276         if (name == names.empty)
2277             return typeNotFound; // do not allow inadvertent "lookup" of anonymous types
2278         Symbol bestSoFar = typeNotFound;
2279         Symbol sym;
2280         boolean staticOnly = false;
2281         for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
2282             if (isStatic(env1)) staticOnly = true;
2283             // First, look for a type variable and the first member type
2284             final Symbol tyvar = findTypeVar(env1, name, staticOnly);
2285             sym = findImmediateMemberType(env1, env1.enclClass.sym.type,
2286                                           name, env1.enclClass.sym);
2287 
2288             // Return the type variable if we have it, and have no
2289             // immediate member, OR the type variable is for a method.
2290             if (tyvar != typeNotFound) {
2291                 if (env.baseClause || sym == typeNotFound ||
2292                     (tyvar.kind == TYP && tyvar.exists() &&
2293                      tyvar.owner.kind == MTH)) {
2294                     return tyvar;
2295                 }
2296             }
2297 
2298             // If the environment is a class def, finish up,
2299             // otherwise, do the entire findMemberType
2300             if (sym == typeNotFound)
2301                 sym = findInheritedMemberType(env1, env1.enclClass.sym.type,
2302                                               name, env1.enclClass.sym);
2303 
2304             if (staticOnly && sym.kind == TYP &&
2305                 sym.type.hasTag(CLASS) &&
2306                 sym.type.getEnclosingType().hasTag(CLASS) &&
2307                 env1.enclClass.sym.type.isParameterized() &&
2308                 sym.type.getEnclosingType().isParameterized())
2309                 return new StaticError(sym);
2310             else if (sym.exists()) return sym;
2311             else bestSoFar = bestOf(bestSoFar, sym);
2312 
2313             JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
2314             if ((encl.sym.flags() & STATIC) != 0)
2315                 staticOnly = true;
2316         }
2317 
2318         if (!env.tree.hasTag(IMPORT)) {
2319             sym = findGlobalType(env, env.toplevel.namedImportScope, name, namedImportScopeRecovery);
2320             if (sym.exists()) return sym;
2321             else bestSoFar = bestOf(bestSoFar, sym);
2322 
2323             sym = findGlobalType(env, env.toplevel.toplevelScope, name, noRecovery);
2324             if (sym.exists()) return sym;
2325             else bestSoFar = bestOf(bestSoFar, sym);
2326 
2327             sym = findGlobalType(env, env.toplevel.packge.members(), name, noRecovery);
2328             if (sym.exists()) return sym;
2329             else bestSoFar = bestOf(bestSoFar, sym);
2330 
2331             sym = findGlobalType(env, env.toplevel.starImportScope, name, starImportScopeRecovery);
2332             if (sym.exists()) return sym;
2333             else bestSoFar = bestOf(bestSoFar, sym);
2334         }
2335 
2336         return bestSoFar;
2337     }
2338 
2339     /** Find an unqualified identifier which matches a specified kind set.
2340      *  @param pos       position on which report warnings, if any;
2341      *                   null warnings should not be reported
2342      *  @param env       The current environment.
2343      *  @param name      The identifier's name.
2344      *  @param kind      Indicates the possible symbol kinds
2345      *                   (a subset of VAL, TYP, PCK).
2346      */
2347     Symbol findIdent(DiagnosticPosition pos, Env<AttrContext> env, Name name, KindSelector kind) {
2348         return checkRestrictedType(pos, findIdentInternal(env, name, kind), name);
2349     }
2350 
2351     Symbol findIdentInternal(Env<AttrContext> env, Name name, KindSelector kind) {
2352         Symbol bestSoFar = typeNotFound;
2353         Symbol sym;
2354 
2355         if (kind.contains(KindSelector.VAL)) {
2356             sym = findVar(env, name);
2357             if (sym.exists()) return sym;
2358             else bestSoFar = bestOf(bestSoFar, sym);
2359         }
2360 
2361         if (kind.contains(KindSelector.TYP)) {
2362             sym = findType(env, name);
2363 
2364             if (sym.exists()) return sym;
2365             else bestSoFar = bestOf(bestSoFar, sym);
2366         }
2367 
2368         if (kind.contains(KindSelector.PCK))
2369             return lookupPackage(env, name);
2370         else return bestSoFar;
2371     }
2372 
2373     /** Find an identifier in a package which matches a specified kind set.
2374      *  @param pos       position on which report warnings, if any;
2375      *                   null warnings should not be reported
2376      *  @param env       The current environment.
2377      *  @param name      The identifier's name.
2378      *  @param kind      Indicates the possible symbol kinds
2379      *                   (a nonempty subset of TYP, PCK).
2380      */
2381     Symbol findIdentInPackage(DiagnosticPosition pos,
2382                               Env<AttrContext> env, TypeSymbol pck,
2383                               Name name, KindSelector kind) {
2384         return checkRestrictedType(pos, findIdentInPackageInternal(env, pck, name, kind), name);
2385     }
2386 
2387     Symbol findIdentInPackageInternal(Env<AttrContext> env, TypeSymbol pck,
2388                               Name name, KindSelector kind) {
2389         Name fullname = TypeSymbol.formFullName(name, pck);
2390         Symbol bestSoFar = typeNotFound;
2391         if (kind.contains(KindSelector.TYP)) {
2392             RecoveryLoadClass recoveryLoadClass =
2393                     allowModules && !kind.contains(KindSelector.PCK) &&
2394                     !pck.exists() && !env.info.attributionMode.isSpeculative ?
2395                         doRecoveryLoadClass : noRecovery;
2396             Symbol sym = loadClass(env, fullname, recoveryLoadClass);
2397             if (sym.exists()) {
2398                 // don't allow programs to use flatnames
2399                 if (name == sym.name) return sym;
2400             }
2401             else bestSoFar = bestOf(bestSoFar, sym);
2402         }
2403         if (kind.contains(KindSelector.PCK)) {
2404             return lookupPackage(env, fullname);
2405         }
2406         return bestSoFar;
2407     }
2408 
2409     /** Find an identifier among the members of a given type `site'.
2410      *  @param pos       position on which report warnings, if any;
2411      *                   null warnings should not be reported
2412      *  @param env       The current environment.
2413      *  @param site      The type containing the symbol to be found.
2414      *  @param name      The identifier's name.
2415      *  @param kind      Indicates the possible symbol kinds
2416      *                   (a subset of VAL, TYP).
2417      */
2418     Symbol findIdentInType(DiagnosticPosition pos,
2419                            Env<AttrContext> env, Type site,
2420                            Name name, KindSelector kind) {
2421         return checkRestrictedType(pos, findIdentInTypeInternal(env, site, name, kind), name);
2422     }
2423 
2424     Symbol findIdentInTypeInternal(Env<AttrContext> env, Type site,
2425                            Name name, KindSelector kind) {
2426         Symbol bestSoFar = typeNotFound;
2427         Symbol sym;
2428         if (kind.contains(KindSelector.VAL)) {
2429             sym = findField(env, site, name, site.tsym);
2430             if (sym.exists()) return sym;
2431             else bestSoFar = bestOf(bestSoFar, sym);
2432         }
2433 
2434         if (kind.contains(KindSelector.TYP)) {
2435             sym = findMemberType(env, site, name, site.tsym);
2436             if (sym.exists()) return sym;
2437             else bestSoFar = bestOf(bestSoFar, sym);
2438         }
2439         return bestSoFar;
2440     }
2441 
2442     private Symbol checkRestrictedType(DiagnosticPosition pos, Symbol bestSoFar, Name name) {
2443         if (bestSoFar.kind == TYP || bestSoFar.kind == ABSENT_TYP) {
2444             if (allowLocalVariableTypeInference && name.equals(names.var)) {
2445                 bestSoFar = new BadRestrictedTypeError(names.var);
2446             } else if (name.equals(names.yield)) {
2447                 if (allowYieldStatement) {
2448                     bestSoFar = new BadRestrictedTypeError(names.yield);
2449                 } else if (pos != null) {
2450                     log.warning(pos, Warnings.IllegalRefToRestrictedType(names.yield));
2451                 }
2452             }
2453         }
2454         return bestSoFar;
2455     }
2456 
2457 /* ***************************************************************************
2458  *  Access checking
2459  *  The following methods convert ResolveErrors to ErrorSymbols, issuing
2460  *  an error message in the process
2461  ****************************************************************************/
2462 
2463     /** If `sym' is a bad symbol: report error and return errSymbol
2464      *  else pass through unchanged,
2465      *  additional arguments duplicate what has been used in trying to find the
2466      *  symbol {@literal (--> flyweight pattern)}. This improves performance since we
2467      *  expect misses to happen frequently.
2468      *
2469      *  @param sym       The symbol that was found, or a ResolveError.
2470      *  @param pos       The position to use for error reporting.
2471      *  @param location  The symbol the served as a context for this lookup
2472      *  @param site      The original type from where the selection took place.
2473      *  @param name      The symbol's name.
2474      *  @param qualified Did we get here through a qualified expression resolution?
2475      *  @param argtypes  The invocation's value arguments,
2476      *                   if we looked for a method.
2477      *  @param typeargtypes  The invocation's type arguments,
2478      *                   if we looked for a method.
2479      *  @param logResolveHelper helper class used to log resolve errors
2480      */
2481     Symbol accessInternal(Symbol sym,
2482                   DiagnosticPosition pos,
2483                   Symbol location,
2484                   Type site,
2485                   Name name,
2486                   boolean qualified,
2487                   List<Type> argtypes,
2488                   List<Type> typeargtypes,
2489                   LogResolveHelper logResolveHelper) {
2490         if (sym.kind.isResolutionError()) {
2491             ResolveError errSym = (ResolveError)sym.baseSymbol();
2492             sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
2493             argtypes = logResolveHelper.getArgumentTypes(errSym, sym, name, argtypes);
2494             if (logResolveHelper.resolveDiagnosticNeeded(site, argtypes, typeargtypes)) {
2495                 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
2496             }
2497         }
2498         return sym;
2499     }
2500 
2501     /**
2502      * Variant of the generalized access routine, to be used for generating method
2503      * resolution diagnostics
2504      */
2505     Symbol accessMethod(Symbol sym,
2506                   DiagnosticPosition pos,
2507                   Symbol location,
2508                   Type site,
2509                   Name name,
2510                   boolean qualified,
2511                   List<Type> argtypes,
2512                   List<Type> typeargtypes) {
2513         return accessInternal(sym, pos, location, site, name, qualified, argtypes, typeargtypes, methodLogResolveHelper);
2514     }
2515 
2516     /** Same as original accessMethod(), but without location.
2517      */
2518     Symbol accessMethod(Symbol sym,
2519                   DiagnosticPosition pos,
2520                   Type site,
2521                   Name name,
2522                   boolean qualified,
2523                   List<Type> argtypes,
2524                   List<Type> typeargtypes) {
2525         return accessMethod(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
2526     }
2527 
2528     /**
2529      * Variant of the generalized access routine, to be used for generating variable,
2530      * type resolution diagnostics
2531      */
2532     Symbol accessBase(Symbol sym,
2533                   DiagnosticPosition pos,
2534                   Symbol location,
2535                   Type site,
2536                   Name name,
2537                   boolean qualified) {
2538         return accessInternal(sym, pos, location, site, name, qualified, List.nil(), null, basicLogResolveHelper);
2539     }
2540 
2541     /** Same as original accessBase(), but without location.
2542      */
2543     Symbol accessBase(Symbol sym,
2544                   DiagnosticPosition pos,
2545                   Type site,
2546                   Name name,
2547                   boolean qualified) {
2548         return accessBase(sym, pos, site.tsym, site, name, qualified);
2549     }
2550 
2551     interface LogResolveHelper {
2552         boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes);
2553         List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes);
2554     }
2555 
2556     LogResolveHelper basicLogResolveHelper = new LogResolveHelper() {
2557         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2558             return !site.isErroneous();
2559         }
2560         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2561             return argtypes;
2562         }
2563     };
2564 
2565     LogResolveHelper methodLogResolveHelper = new LogResolveHelper() {
2566         public boolean resolveDiagnosticNeeded(Type site, List<Type> argtypes, List<Type> typeargtypes) {
2567             return !site.isErroneous() &&
2568                         !Type.isErroneous(argtypes) &&
2569                         (typeargtypes == null || !Type.isErroneous(typeargtypes));
2570         }
2571         public List<Type> getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List<Type> argtypes) {
2572             return argtypes.map(new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step));
2573         }
2574     };
2575 
2576     class ResolveDeferredRecoveryMap extends DeferredAttr.RecoveryDeferredTypeMap {
2577 
2578         public ResolveDeferredRecoveryMap(AttrMode mode, Symbol msym, MethodResolutionPhase step) {
2579             deferredAttr.super(mode, msym, step);
2580         }
2581 
2582         @Override
2583         protected Type typeOf(DeferredType dt, Type pt) {
2584             Type res = super.typeOf(dt, pt);
2585             if (!res.isErroneous()) {
2586                 switch (TreeInfo.skipParens(dt.tree).getTag()) {
2587                     case LAMBDA:
2588                     case REFERENCE:
2589                         return dt;
2590                     case CONDEXPR:
2591                         return res == Type.recoveryType ?
2592                                 dt : res;
2593                 }
2594             }
2595             return res;
2596         }
2597     }
2598 
2599     /** Check that sym is not an abstract method.
2600      */
2601     void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
2602         if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
2603             log.error(pos,
2604                       Errors.AbstractCantBeAccessedDirectly(kindName(sym),sym, sym.location()));
2605     }
2606 
2607 /* ***************************************************************************
2608  *  Name resolution
2609  *  Naming conventions are as for symbol lookup
2610  *  Unlike the find... methods these methods will report access errors
2611  ****************************************************************************/
2612 
2613     /** Resolve an unqualified (non-method) identifier.
2614      *  @param pos       The position to use for error reporting.
2615      *  @param env       The environment current at the identifier use.
2616      *  @param name      The identifier's name.
2617      *  @param kind      The set of admissible symbol kinds for the identifier.
2618      */
2619     Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
2620                         Name name, KindSelector kind) {
2621         return accessBase(
2622             findIdent(pos, env, name, kind),
2623             pos, env.enclClass.sym.type, name, false);
2624     }
2625 
2626     /** Resolve an unqualified method identifier.
2627      *  @param pos       The position to use for error reporting.
2628      *  @param env       The environment current at the method invocation.
2629      *  @param name      The identifier's name.
2630      *  @param argtypes  The types of the invocation's value arguments.
2631      *  @param typeargtypes  The types of the invocation's type arguments.
2632      */
2633     Symbol resolveMethod(DiagnosticPosition pos,
2634                          Env<AttrContext> env,
2635                          Name name,
2636                          List<Type> argtypes,
2637                          List<Type> typeargtypes) {
2638         return lookupMethod(env, pos, env.enclClass.sym, resolveMethodCheck,
2639                 new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
2640                     @Override
2641                     Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2642                         return findFun(env, name, argtypes, typeargtypes,
2643                                 phase.isBoxingRequired(),
2644                                 phase.isVarargsRequired());
2645                     }});
2646     }
2647 
2648     /** Resolve a qualified method identifier
2649      *  @param pos       The position to use for error reporting.
2650      *  @param env       The environment current at the method invocation.
2651      *  @param site      The type of the qualifying expression, in which
2652      *                   identifier is searched.
2653      *  @param name      The identifier's name.
2654      *  @param argtypes  The types of the invocation's value arguments.
2655      *  @param typeargtypes  The types of the invocation's type arguments.
2656      */
2657     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2658                                   Type site, Name name, List<Type> argtypes,
2659                                   List<Type> typeargtypes) {
2660         return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
2661     }
2662     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
2663                                   Symbol location, Type site, Name name, List<Type> argtypes,
2664                                   List<Type> typeargtypes) {
2665         return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
2666     }
2667     private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
2668                                   DiagnosticPosition pos, Env<AttrContext> env,
2669                                   Symbol location, Type site, Name name, List<Type> argtypes,
2670                                   List<Type> typeargtypes) {
2671         return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
2672             @Override
2673             Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2674                 return findMethod(env, site, name, argtypes, typeargtypes,
2675                         phase.isBoxingRequired(),
2676                         phase.isVarargsRequired());
2677             }
2678             @Override
2679             Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2680                 if (sym.kind.isResolutionError()) {
2681                     sym = super.access(env, pos, location, sym);
2682                 } else {
2683                     MethodSymbol msym = (MethodSymbol)sym;
2684                     if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
2685                         env.info.pendingResolutionPhase = BASIC;
2686                         return findPolymorphicSignatureInstance(env, sym, argtypes);
2687                     }
2688                 }
2689                 return sym;
2690             }
2691         });
2692     }
2693 
2694     /** Find or create an implicit method of exactly the given type (after erasure).
2695      *  Searches in a side table, not the main scope of the site.
2696      *  This emulates the lookup process required by JSR 292 in JVM.
2697      *  @param env       Attribution environment
2698      *  @param spMethod  signature polymorphic method - i.e. MH.invokeExact
2699      *  @param argtypes  The required argument types
2700      */
2701     Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
2702                                             final Symbol spMethod,
2703                                             List<Type> argtypes) {
2704         Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
2705                 (MethodSymbol)spMethod, currentResolutionContext, argtypes);
2706         return findPolymorphicSignatureInstance(spMethod, mtype);
2707     }
2708 
2709     Symbol findPolymorphicSignatureInstance(final Symbol spMethod,
2710                                             Type mtype) {
2711         for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
2712             // Check that there is already a method symbol for the method
2713             // type and owner
2714             if (types.isSameType(mtype, sym.type) &&
2715                 spMethod.owner == sym.owner) {
2716                 return sym;
2717             }
2718         }
2719 
2720         // Create the desired method
2721         // Retain static modifier is to support invocations to
2722         // MethodHandle.linkTo* methods
2723         long flags = ABSTRACT | HYPOTHETICAL |
2724                      spMethod.flags() & (Flags.AccessFlags | Flags.STATIC);
2725         Symbol msym = new MethodSymbol(flags, spMethod.name, mtype, spMethod.owner) {
2726             @Override
2727             public Symbol baseSymbol() {
2728                 return spMethod;
2729             }
2730         };
2731         if (!mtype.isErroneous()) { // Cache only if kosher.
2732             polymorphicSignatureScope.enter(msym);
2733         }
2734         return msym;
2735     }
2736 
2737     /** Resolve a qualified method identifier, throw a fatal error if not
2738      *  found.
2739      *  @param pos       The position to use for error reporting.
2740      *  @param env       The environment current at the method invocation.
2741      *  @param site      The type of the qualifying expression, in which
2742      *                   identifier is searched.
2743      *  @param name      The identifier's name.
2744      *  @param argtypes  The types of the invocation's value arguments.
2745      *  @param typeargtypes  The types of the invocation's type arguments.
2746      */
2747     public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
2748                                         Type site, Name name,
2749                                         List<Type> argtypes,
2750                                         List<Type> typeargtypes) {
2751         MethodResolutionContext resolveContext = new MethodResolutionContext();
2752         resolveContext.internalResolution = true;
2753         Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
2754                 site, name, argtypes, typeargtypes);
2755         if (sym.kind == MTH) return (MethodSymbol)sym;
2756         else throw new FatalError(
2757                  diags.fragment(Fragments.FatalErrCantLocateMeth(name)));
2758     }
2759 
2760     /** Resolve constructor.
2761      *  @param pos       The position to use for error reporting.
2762      *  @param env       The environment current at the constructor invocation.
2763      *  @param site      The type of class for which a constructor is searched.
2764      *  @param argtypes  The types of the constructor invocation's value
2765      *                   arguments.
2766      *  @param typeargtypes  The types of the constructor invocation's type
2767      *                   arguments.
2768      */
2769     Symbol resolveConstructor(DiagnosticPosition pos,
2770                               Env<AttrContext> env,
2771                               Type site,
2772                               List<Type> argtypes,
2773                               List<Type> typeargtypes) {
2774         return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
2775     }
2776 
2777     private Symbol resolveConstructor(MethodResolutionContext resolveContext,
2778                               final DiagnosticPosition pos,
2779                               Env<AttrContext> env,
2780                               Type site,
2781                               List<Type> argtypes,
2782                               List<Type> typeargtypes) {
2783         return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2784             @Override
2785             Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2786                 return findConstructor(pos, env, site, argtypes, typeargtypes,
2787                         phase.isBoxingRequired(),
2788                         phase.isVarargsRequired());
2789             }
2790         });
2791     }
2792 
2793     /** Resolve a constructor, throw a fatal error if not found.
2794      *  @param pos       The position to use for error reporting.
2795      *  @param env       The environment current at the method invocation.
2796      *  @param site      The type to be constructed.
2797      *  @param argtypes  The types of the invocation's value arguments.
2798      *  @param typeargtypes  The types of the invocation's type arguments.
2799      */
2800     public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2801                                         Type site,
2802                                         List<Type> argtypes,
2803                                         List<Type> typeargtypes) {
2804         MethodResolutionContext resolveContext = new MethodResolutionContext();
2805         resolveContext.internalResolution = true;
2806         Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
2807         if (sym.kind == MTH) return (MethodSymbol)sym;
2808         else throw new FatalError(
2809                  diags.fragment(Fragments.FatalErrCantLocateCtor(site)));
2810     }
2811 
2812     Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
2813                               Type site, List<Type> argtypes,
2814                               List<Type> typeargtypes,
2815                               boolean allowBoxing,
2816                               boolean useVarargs) {
2817         Symbol sym = findMethod(env, site,
2818                                     names.init, argtypes,
2819                                     typeargtypes, allowBoxing,
2820                                     useVarargs);
2821         chk.checkDeprecated(pos, env.info.scope.owner, sym);
2822         chk.checkPreview(pos, sym);
2823         return sym;
2824     }
2825 
2826     /** Resolve constructor using diamond inference.
2827      *  @param pos       The position to use for error reporting.
2828      *  @param env       The environment current at the constructor invocation.
2829      *  @param site      The type of class for which a constructor is searched.
2830      *                   The scope of this class has been touched in attribution.
2831      *  @param argtypes  The types of the constructor invocation's value
2832      *                   arguments.
2833      *  @param typeargtypes  The types of the constructor invocation's type
2834      *                   arguments.
2835      */
2836     Symbol resolveDiamond(DiagnosticPosition pos,
2837                               Env<AttrContext> env,
2838                               Type site,
2839                               List<Type> argtypes,
2840                               List<Type> typeargtypes) {
2841         return lookupMethod(env, pos, site.tsym, resolveMethodCheck,
2842                 new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
2843                     @Override
2844                     Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase) {
2845                         return findDiamond(env, site, argtypes, typeargtypes,
2846                                 phase.isBoxingRequired(),
2847                                 phase.isVarargsRequired());
2848                     }
2849                     @Override
2850                     Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
2851                         if (sym.kind.isResolutionError()) {
2852                             if (sym.kind != WRONG_MTH &&
2853                                 sym.kind != WRONG_MTHS) {
2854                                 sym = super.access(env, pos, location, sym);
2855                             } else {
2856                                 final JCDiagnostic details = sym.kind == WRONG_MTH ?
2857                                                 ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
2858                                                 null;
2859                                 sym = new DiamondError(sym, currentResolutionContext);
2860                                 sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
2861                                 env.info.pendingResolutionPhase = currentResolutionContext.step;
2862                             }
2863                         }
2864                         return sym;
2865                     }});
2866     }
2867 
2868     /** This method scans all the constructor symbol in a given class scope -
2869      *  assuming that the original scope contains a constructor of the kind:
2870      *  {@code Foo(X x, Y y)}, where X,Y are class type-variables declared in Foo,
2871      *  a method check is executed against the modified constructor type:
2872      *  {@code <X,Y>Foo<X,Y>(X x, Y y)}. This is crucial in order to enable diamond
2873      *  inference. The inferred return type of the synthetic constructor IS
2874      *  the inferred type for the diamond operator.
2875      */
2876     private Symbol findDiamond(Env<AttrContext> env,
2877                               Type site,
2878                               List<Type> argtypes,
2879                               List<Type> typeargtypes,
2880                               boolean allowBoxing,
2881                               boolean useVarargs) {
2882         Symbol bestSoFar = methodNotFound;
2883         TypeSymbol tsym = site.tsym.isInterface() ? syms.objectType.tsym : site.tsym;
2884         for (final Symbol sym : tsym.members().getSymbolsByName(names.init)) {
2885             //- System.out.println(" e " + e.sym);
2886             if (sym.kind == MTH &&
2887                 (sym.flags_field & SYNTHETIC) == 0) {
2888                     List<Type> oldParams = sym.type.hasTag(FORALL) ?
2889                             ((ForAll)sym.type).tvars :
2890                             List.nil();
2891                     Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
2892                                                  types.createMethodTypeWithReturn(sym.type.asMethodType(), site));
2893                     MethodSymbol newConstr = new MethodSymbol(sym.flags(), names.init, constrType, site.tsym) {
2894                         @Override
2895                         public Symbol baseSymbol() {
2896                             return sym;
2897                         }
2898                     };
2899                     bestSoFar = selectBest(env, site, argtypes, typeargtypes,
2900                             newConstr,
2901                             bestSoFar,
2902                             allowBoxing,
2903                             useVarargs);
2904             }
2905         }
2906         return bestSoFar;
2907     }
2908 
2909     Symbol getMemberReference(DiagnosticPosition pos,
2910             Env<AttrContext> env,
2911             JCMemberReference referenceTree,
2912             Type site,
2913             Name name) {
2914 
2915         site = types.capture(site);
2916 
2917         ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
2918                 referenceTree, site, name, List.nil(), null, VARARITY);
2919 
2920         Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup());
2921         Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym,
2922                 nilMethodCheck, lookupHelper);
2923 
2924         env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase;
2925 
2926         return sym;
2927     }
2928 
2929     ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree,
2930                                   Type site,
2931                                   Name name,
2932                                   List<Type> argtypes,
2933                                   List<Type> typeargtypes,
2934                                   MethodResolutionPhase maxPhase) {
2935         if (!name.equals(names.init)) {
2936             //method reference
2937             return new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
2938         } else if (site.hasTag(ARRAY)) {
2939             //array constructor reference
2940             return new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2941         } else {
2942             //class constructor reference
2943             return new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
2944         }
2945     }
2946 
2947     /**
2948      * Resolution of member references is typically done as a single
2949      * overload resolution step, where the argument types A are inferred from
2950      * the target functional descriptor.
2951      *
2952      * If the member reference is a method reference with a type qualifier,
2953      * a two-step lookup process is performed. The first step uses the
2954      * expected argument list A, while the second step discards the first
2955      * type from A (which is treated as a receiver type).
2956      *
2957      * There are two cases in which inference is performed: (i) if the member
2958      * reference is a constructor reference and the qualifier type is raw - in
2959      * which case diamond inference is used to infer a parameterization for the
2960      * type qualifier; (ii) if the member reference is an unbound reference
2961      * where the type qualifier is raw - in that case, during the unbound lookup
2962      * the receiver argument type is used to infer an instantiation for the raw
2963      * qualifier type.
2964      *
2965      * When a multi-step resolution process is exploited, the process of picking
2966      * the resulting symbol is delegated to an helper class {@link com.sun.tools.javac.comp.Resolve.ReferenceChooser}.
2967      *
2968      * This routine returns a pair (T,S), where S is the member reference symbol,
2969      * and T is the type of the class in which S is defined. This is necessary as
2970      * the type T might be dynamically inferred (i.e. if constructor reference
2971      * has a raw qualifier).
2972      */
2973     Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env,
2974                                   JCMemberReference referenceTree,
2975                                   Type site,
2976                                   Name name,
2977                                   List<Type> argtypes,
2978                                   List<Type> typeargtypes,
2979                                   Type descriptor,
2980                                   MethodCheck methodCheck,
2981                                   InferenceContext inferenceContext,
2982                                   ReferenceChooser referenceChooser) {
2983 
2984         //step 1 - bound lookup
2985         ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
2986                 referenceTree, site, name, argtypes, typeargtypes, VARARITY);
2987         Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
2988         MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
2989         boundSearchResolveContext.methodCheck = methodCheck;
2990         Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(),
2991                 site.tsym, boundSearchResolveContext, boundLookupHelper);
2992         ReferenceLookupResult boundRes = new ReferenceLookupResult(boundSym, boundSearchResolveContext);
2993 
2994         //step 2 - unbound lookup
2995         Symbol unboundSym = methodNotFound;
2996         Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
2997         ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
2998         ReferenceLookupResult unboundRes = referenceNotFound;
2999         if (unboundLookupHelper != null) {
3000             MethodResolutionContext unboundSearchResolveContext =
3001                     new MethodResolutionContext();
3002             unboundSearchResolveContext.methodCheck = methodCheck;
3003             unboundSym = lookupMethod(unboundEnv, env.tree.pos(),
3004                     site.tsym, unboundSearchResolveContext, unboundLookupHelper);
3005             unboundRes = new ReferenceLookupResult(unboundSym, unboundSearchResolveContext);
3006         }
3007 
3008         //merge results
3009         Pair<Symbol, ReferenceLookupHelper> res;
3010         ReferenceLookupResult bestRes = referenceChooser.result(boundRes, unboundRes);
3011         res = new Pair<>(bestRes.sym,
3012                 bestRes == unboundRes ? unboundLookupHelper : boundLookupHelper);
3013         env.info.pendingResolutionPhase = bestRes == unboundRes ?
3014                 unboundEnv.info.pendingResolutionPhase :
3015                 boundEnv.info.pendingResolutionPhase;
3016 
3017         if (!res.fst.kind.isResolutionError()) {
3018             //handle sigpoly method references
3019             MethodSymbol msym = (MethodSymbol)res.fst;
3020             if ((msym.flags() & SIGNATURE_POLYMORPHIC) != 0) {
3021                 env.info.pendingResolutionPhase = BASIC;
3022                 res = new Pair<>(findPolymorphicSignatureInstance(msym, descriptor), res.snd);
3023             }
3024         }
3025 
3026         return res;
3027     }
3028 
3029     /**
3030      * This class is used to represent a method reference lookup result. It keeps track of two
3031      * things: (i) the symbol found during a method reference lookup and (ii) the static kind
3032      * of the lookup (see {@link com.sun.tools.javac.comp.Resolve.ReferenceLookupResult.StaticKind}).
3033      */
3034     static class ReferenceLookupResult {
3035 
3036         /**
3037          * Static kind associated with a method reference lookup. Erroneous lookups end up with
3038          * the UNDEFINED kind; successful lookups will end up with either STATIC, NON_STATIC,
3039          * depending on whether all applicable candidates are static or non-static methods,
3040          * respectively. If a successful lookup has both static and non-static applicable methods,
3041          * its kind is set to BOTH.
3042          */
3043         enum StaticKind {
3044             STATIC,
3045             NON_STATIC,
3046             BOTH,
3047             UNDEFINED;
3048 
3049             /**
3050              * Retrieve the static kind associated with a given (method) symbol.
3051              */
3052             static StaticKind from(Symbol s) {
3053                 return s.isStatic() ?
3054                         STATIC : NON_STATIC;
3055             }
3056 
3057             /**
3058              * Merge two static kinds together.
3059              */
3060             static StaticKind reduce(StaticKind sk1, StaticKind sk2) {
3061                 if (sk1 == UNDEFINED) {
3062                     return sk2;
3063                 } else if (sk2 == UNDEFINED) {
3064                     return sk1;
3065                 } else {
3066                     return sk1 == sk2 ? sk1 : BOTH;
3067                 }
3068             }
3069         }
3070 
3071         /** The static kind. */
3072         StaticKind staticKind;
3073 
3074         /** The lookup result. */
3075         Symbol sym;
3076 
3077         ReferenceLookupResult(Symbol sym, MethodResolutionContext resolutionContext) {
3078             this(sym, staticKind(sym, resolutionContext));
3079         }
3080 
3081         private ReferenceLookupResult(Symbol sym, StaticKind staticKind) {
3082             this.staticKind = staticKind;
3083             this.sym = sym;
3084         }
3085 
3086         private static StaticKind staticKind(Symbol sym, MethodResolutionContext resolutionContext) {
3087             switch (sym.kind) {
3088                 case MTH:
3089                 case AMBIGUOUS:
3090                     return resolutionContext.candidates.stream()
3091                             .filter(c -> c.isApplicable() && c.step == resolutionContext.step)
3092                             .map(c -> StaticKind.from(c.sym))
3093                             .reduce(StaticKind::reduce)
3094                             .orElse(StaticKind.UNDEFINED);
3095                 default:
3096                     return StaticKind.UNDEFINED;
3097             }
3098         }
3099 
3100         /**
3101          * Does this result corresponds to a successful lookup (i.e. one where a method has been found?)
3102          */
3103         boolean isSuccess() {
3104             return staticKind != StaticKind.UNDEFINED;
3105         }
3106 
3107         /**
3108          * Does this result have given static kind?
3109          */
3110         boolean hasKind(StaticKind sk) {
3111             return this.staticKind == sk;
3112         }
3113 
3114         /**
3115          * Error recovery helper: can this lookup result be ignored (for the purpose of returning
3116          * some 'better' result) ?
3117          */
3118         boolean canIgnore() {
3119             switch (sym.kind) {
3120                 case ABSENT_MTH:
3121                     return true;
3122                 case WRONG_MTH:
3123                     InapplicableSymbolError errSym =
3124                             (InapplicableSymbolError)sym.baseSymbol();
3125                     return new Template(MethodCheckDiag.ARITY_MISMATCH.regex())
3126                             .matches(errSym.errCandidate().snd);
3127                 case WRONG_MTHS:
3128                     InapplicableSymbolsError errSyms =
3129                             (InapplicableSymbolsError)sym.baseSymbol();
3130                     return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty();
3131                 default:
3132                     return false;
3133             }
3134         }
3135 
3136         static ReferenceLookupResult error(Symbol sym) {
3137             return new ReferenceLookupResult(sym, StaticKind.UNDEFINED);
3138         }
3139     }
3140 
3141     /**
3142      * This abstract class embodies the logic that converts one (bound lookup) or two (unbound lookup)
3143      * {@code ReferenceLookupResult} objects into a (@code Symbol), which is then regarded as the
3144      * result of method reference resolution.
3145      */
3146     abstract class ReferenceChooser {
3147         /**
3148          * Generate a result from a pair of lookup result objects. This method delegates to the
3149          * appropriate result generation routine.
3150          */
3151         ReferenceLookupResult result(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3152             return unboundRes != referenceNotFound ?
3153                     unboundResult(boundRes, unboundRes) :
3154                     boundResult(boundRes);
3155         }
3156 
3157         /**
3158          * Generate a symbol from a given bound lookup result.
3159          */
3160         abstract ReferenceLookupResult boundResult(ReferenceLookupResult boundRes);
3161 
3162         /**
3163          * Generate a symbol from a pair of bound/unbound lookup results.
3164          */
3165         abstract ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes);
3166     }
3167 
3168     /**
3169      * This chooser implements the selection strategy used during a full lookup; this logic
3170      * is described in JLS SE 8 (15.3.2).
3171      */
3172     ReferenceChooser basicReferenceChooser = new ReferenceChooser() {
3173 
3174         @Override
3175         ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
3176             return !boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC) ?
3177                     boundRes : //the search produces a non-static method
3178                     ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
3179         }
3180 
3181         @Override
3182         ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3183             if (boundRes.hasKind(StaticKind.STATIC) &&
3184                     (!unboundRes.isSuccess() || unboundRes.hasKind(StaticKind.STATIC))) {
3185                 //the first search produces a static method and no non-static method is applicable
3186                 //during the second search
3187                 return boundRes;
3188             } else if (unboundRes.hasKind(StaticKind.NON_STATIC) &&
3189                     (!boundRes.isSuccess() || boundRes.hasKind(StaticKind.NON_STATIC))) {
3190                 //the second search produces a non-static method and no static method is applicable
3191                 //during the first search
3192                 return unboundRes;
3193             } else if (boundRes.isSuccess() && unboundRes.isSuccess()) {
3194                 //both searches produce some result; ambiguity (error recovery)
3195                 return ReferenceLookupResult.error(ambiguityError(boundRes.sym, unboundRes.sym));
3196             } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
3197                 //Both searches failed to produce a result with correct staticness (i.e. first search
3198                 //produces an non-static method). Alternatively, a given search produced a result
3199                 //with the right staticness, but the other search has applicable methods with wrong
3200                 //staticness (error recovery)
3201                 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
3202                         boundRes.sym : unboundRes.sym, true));
3203             } else {
3204                 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
3205                 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
3206                         unboundRes : boundRes;
3207             }
3208         }
3209     };
3210 
3211     /**
3212      * This chooser implements the selection strategy used during an arity-based lookup; this logic
3213      * is described in JLS SE 8 (15.12.2.1).
3214      */
3215     ReferenceChooser structuralReferenceChooser = new ReferenceChooser() {
3216 
3217         @Override
3218         ReferenceLookupResult boundResult(ReferenceLookupResult boundRes) {
3219             return (!boundRes.isSuccess() || !boundRes.hasKind(StaticKind.STATIC)) ?
3220                     boundRes : //the search has at least one applicable non-static method
3221                     ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.sym, false));
3222         }
3223 
3224         @Override
3225         ReferenceLookupResult unboundResult(ReferenceLookupResult boundRes, ReferenceLookupResult unboundRes) {
3226             if (boundRes.isSuccess() && !boundRes.hasKind(StaticKind.NON_STATIC)) {
3227                 //the first search has at least one applicable static method
3228                 return boundRes;
3229             } else if (unboundRes.isSuccess() && !unboundRes.hasKind(StaticKind.STATIC)) {
3230                 //the second search has at least one applicable non-static method
3231                 return unboundRes;
3232             } else if (boundRes.isSuccess() || unboundRes.isSuccess()) {
3233                 //either the first search produces a non-static method, or second search produces
3234                 //a non-static method (error recovery)
3235                 return ReferenceLookupResult.error(new BadMethodReferenceError(boundRes.isSuccess() ?
3236                         boundRes.sym : unboundRes.sym, true));
3237             } else {
3238                 //both searches fail to produce a result - pick 'better' error using heuristics (error recovery)
3239                 return (boundRes.canIgnore() && !unboundRes.canIgnore()) ?
3240                         unboundRes : boundRes;
3241             }
3242         }
3243     };
3244 
3245     /**
3246      * Helper for defining custom method-like lookup logic; a lookup helper
3247      * provides hooks for (i) the actual lookup logic and (ii) accessing the
3248      * lookup result (this step might result in compiler diagnostics to be generated)
3249      */
3250     abstract class LookupHelper {
3251 
3252         /** name of the symbol to lookup */
3253         Name name;
3254 
3255         /** location in which the lookup takes place */
3256         Type site;
3257 
3258         /** actual types used during the lookup */
3259         List<Type> argtypes;
3260 
3261         /** type arguments used during the lookup */
3262         List<Type> typeargtypes;
3263 
3264         /** Max overload resolution phase handled by this helper */
3265         MethodResolutionPhase maxPhase;
3266 
3267         LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3268             this.name = name;
3269             this.site = site;
3270             this.argtypes = argtypes;
3271             this.typeargtypes = typeargtypes;
3272             this.maxPhase = maxPhase;
3273         }
3274 
3275         /**
3276          * Should lookup stop at given phase with given result
3277          */
3278         final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
3279             return phase.ordinal() > maxPhase.ordinal() ||
3280                 !sym.kind.isResolutionError() || sym.kind == AMBIGUOUS;
3281         }
3282 
3283         /**
3284          * Search for a symbol under a given overload resolution phase - this method
3285          * is usually called several times, once per each overload resolution phase
3286          */
3287         abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
3288 
3289         /**
3290          * Dump overload resolution info
3291          */
3292         void debug(DiagnosticPosition pos, Symbol sym) {
3293             //do nothing
3294         }
3295 
3296         /**
3297          * Validate the result of the lookup
3298          */
3299         abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym);
3300     }
3301 
3302     abstract class BasicLookupHelper extends LookupHelper {
3303 
3304         BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
3305             this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
3306         }
3307 
3308         BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3309             super(name, site, argtypes, typeargtypes, maxPhase);
3310         }
3311 
3312         @Override
3313         final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3314             Symbol sym = doLookup(env, phase);
3315             if (sym.kind == AMBIGUOUS) {
3316                 AmbiguityError a_err = (AmbiguityError)sym.baseSymbol();
3317                 sym = a_err.mergeAbstracts(site);
3318             }
3319             return sym;
3320         }
3321 
3322         abstract Symbol doLookup(Env<AttrContext> env, MethodResolutionPhase phase);
3323 
3324         @Override
3325         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3326             if (sym.kind.isResolutionError()) {
3327                 //if nothing is found return the 'first' error
3328                 sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
3329             }
3330             return sym;
3331         }
3332 
3333         @Override
3334         void debug(DiagnosticPosition pos, Symbol sym) {
3335             reportVerboseResolutionDiagnostic(pos, name, site, argtypes, typeargtypes, sym);
3336         }
3337     }
3338 
3339     /**
3340      * Helper class for member reference lookup. A reference lookup helper
3341      * defines the basic logic for member reference lookup; a method gives
3342      * access to an 'unbound' helper used to perform an unbound member
3343      * reference lookup.
3344      */
3345     abstract class ReferenceLookupHelper extends LookupHelper {
3346 
3347         /** The member reference tree */
3348         JCMemberReference referenceTree;
3349 
3350         ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3351                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3352             super(name, site, argtypes, typeargtypes, maxPhase);
3353             this.referenceTree = referenceTree;
3354         }
3355 
3356         /**
3357          * Returns an unbound version of this lookup helper. By default, this
3358          * method returns an dummy lookup helper.
3359          */
3360         ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3361             return null;
3362         }
3363 
3364         /**
3365          * Get the kind of the member reference
3366          */
3367         abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
3368 
3369         Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
3370             if (sym.kind == AMBIGUOUS) {
3371                 AmbiguityError a_err = (AmbiguityError)sym.baseSymbol();
3372                 sym = a_err.mergeAbstracts(site);
3373             }
3374             //skip error reporting
3375             return sym;
3376         }
3377     }
3378 
3379     /**
3380      * Helper class for method reference lookup. The lookup logic is based
3381      * upon Resolve.findMethod; in certain cases, this helper class has a
3382      * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
3383      * In such cases, non-static lookup results are thrown away.
3384      */
3385     class MethodReferenceLookupHelper extends ReferenceLookupHelper {
3386 
3387         /** The original method reference lookup site. */
3388         Type originalSite;
3389 
3390         MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3391                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3392             super(referenceTree, name, types.skipTypeVars(site, true), argtypes, typeargtypes, maxPhase);
3393             this.originalSite = site;
3394         }
3395 
3396         @Override
3397         final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3398             return findMethod(env, site, name, argtypes, typeargtypes,
3399                     phase.isBoxingRequired(), phase.isVarargsRequired());
3400         }
3401 
3402         @Override
3403         ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3404             if (TreeInfo.isStaticSelector(referenceTree.expr, names)) {
3405                 if (argtypes.nonEmpty() &&
3406                         (argtypes.head.hasTag(NONE) ||
3407                         types.isSubtypeUnchecked(inferenceContext.asUndetVar(argtypes.head), originalSite))) {
3408                     return new UnboundMethodReferenceLookupHelper(referenceTree, name,
3409                             originalSite, argtypes, typeargtypes, maxPhase);
3410                 } else {
3411                     return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
3412                         @Override
3413                         ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3414                             return this;
3415                         }
3416 
3417                         @Override
3418                         Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3419                             return methodNotFound;
3420                         }
3421 
3422                         @Override
3423                         ReferenceKind referenceKind(Symbol sym) {
3424                             Assert.error();
3425                             return null;
3426                         }
3427                     };
3428                 }
3429             } else {
3430                 return super.unboundLookup(inferenceContext);
3431             }
3432         }
3433 
3434         @Override
3435         ReferenceKind referenceKind(Symbol sym) {
3436             if (sym.isStatic()) {
3437                 return ReferenceKind.STATIC;
3438             } else {
3439                 Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
3440                 return selName != null && selName == names._super ?
3441                         ReferenceKind.SUPER :
3442                         ReferenceKind.BOUND;
3443             }
3444         }
3445     }
3446 
3447     /**
3448      * Helper class for unbound method reference lookup. Essentially the same
3449      * as the basic method reference lookup helper; main difference is that static
3450      * lookup results are thrown away. If qualifier type is raw, an attempt to
3451      * infer a parameterized type is made using the first actual argument (that
3452      * would otherwise be ignored during the lookup).
3453      */
3454     class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
3455 
3456         UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
3457                 List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3458             super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
3459             if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
3460                 Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
3461                 this.site = types.skipTypeVars(asSuperSite, true);
3462             }
3463         }
3464 
3465         @Override
3466         ReferenceLookupHelper unboundLookup(InferenceContext inferenceContext) {
3467             return this;
3468         }
3469 
3470         @Override
3471         ReferenceKind referenceKind(Symbol sym) {
3472             return ReferenceKind.UNBOUND;
3473         }
3474     }
3475 
3476     /**
3477      * Helper class for array constructor lookup; an array constructor lookup
3478      * is simulated by looking up a method that returns the array type specified
3479      * as qualifier, and that accepts a single int parameter (size of the array).
3480      */
3481     class ArrayConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3482 
3483         ArrayConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3484                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3485             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3486         }
3487 
3488         @Override
3489         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3490             WriteableScope sc = WriteableScope.create(syms.arrayClass);
3491             MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
3492             arrayConstr.type = new MethodType(List.of(syms.intType), site, List.nil(), syms.methodClass);
3493             sc.enter(arrayConstr);
3494             return findMethodInScope(env, site, name, argtypes, typeargtypes, sc, methodNotFound, phase.isBoxingRequired(), phase.isVarargsRequired(), false);
3495         }
3496 
3497         @Override
3498         ReferenceKind referenceKind(Symbol sym) {
3499             return ReferenceKind.ARRAY_CTOR;
3500         }
3501     }
3502 
3503     /**
3504      * Helper class for constructor reference lookup. The lookup logic is based
3505      * upon either Resolve.findMethod or Resolve.findDiamond - depending on
3506      * whether the constructor reference needs diamond inference (this is the case
3507      * if the qualifier type is raw). A special erroneous symbol is returned
3508      * if the lookup returns the constructor of an inner class and there's no
3509      * enclosing instance in scope.
3510      */
3511     class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
3512 
3513         boolean needsInference;
3514 
3515         ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
3516                 List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
3517             super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
3518             if (site.isRaw()) {
3519                 this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym, site.getMetadata());
3520                 needsInference = true;
3521             }
3522         }
3523 
3524         @Override
3525         protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
3526             Symbol sym = needsInference ?
3527                 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
3528                 findMethod(env, site, name, argtypes, typeargtypes,
3529                         phase.isBoxingRequired(), phase.isVarargsRequired());
3530             return enclosingInstanceMissing(env, site) ? new BadConstructorReferenceError(sym) : sym;
3531         }
3532 
3533         @Override
3534         ReferenceKind referenceKind(Symbol sym) {
3535             return site.getEnclosingType().hasTag(NONE) ?
3536                     ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
3537         }
3538     }
3539 
3540     /**
3541      * Main overload resolution routine. On each overload resolution step, a
3542      * lookup helper class is used to perform the method/constructor lookup;
3543      * at the end of the lookup, the helper is used to validate the results
3544      * (this last step might trigger overload resolution diagnostics).
3545      */
3546     Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, MethodCheck methodCheck, LookupHelper lookupHelper) {
3547         MethodResolutionContext resolveContext = new MethodResolutionContext();
3548         resolveContext.methodCheck = methodCheck;
3549         return lookupMethod(env, pos, location, resolveContext, lookupHelper);
3550     }
3551 
3552     Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location,
3553             MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
3554         MethodResolutionContext prevResolutionContext = currentResolutionContext;
3555         try {
3556             Symbol bestSoFar = methodNotFound;
3557             currentResolutionContext = resolveContext;
3558             for (MethodResolutionPhase phase : methodResolutionSteps) {
3559                 if (lookupHelper.shouldStop(bestSoFar, phase))
3560                     break;
3561                 MethodResolutionPhase prevPhase = currentResolutionContext.step;
3562                 Symbol prevBest = bestSoFar;
3563                 currentResolutionContext.step = phase;
3564                 Symbol sym = lookupHelper.lookup(env, phase);
3565                 lookupHelper.debug(pos, sym);
3566                 bestSoFar = phase.mergeResults(bestSoFar, sym);
3567                 env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
3568             }
3569             return lookupHelper.access(env, pos, location, bestSoFar);
3570         } finally {
3571             currentResolutionContext = prevResolutionContext;
3572         }
3573     }
3574 
3575     /**
3576      * Resolve `c.name' where name == this or name == super.
3577      * @param pos           The position to use for error reporting.
3578      * @param env           The environment current at the expression.
3579      * @param c             The qualifier.
3580      * @param name          The identifier's name.
3581      */
3582     Symbol resolveSelf(DiagnosticPosition pos,
3583                        Env<AttrContext> env,
3584                        TypeSymbol c,
3585                        Name name) {
3586         Env<AttrContext> env1 = env;
3587         boolean staticOnly = false;
3588         while (env1.outer != null) {
3589             if (isStatic(env1)) staticOnly = true;
3590             if (env1.enclClass.sym == c) {
3591                 Symbol sym = env1.info.scope.findFirst(name);
3592                 if (sym != null) {
3593                     if (staticOnly) sym = new StaticError(sym);
3594                     return accessBase(sym, pos, env.enclClass.sym.type,
3595                                   name, true);
3596                 }
3597             }
3598             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
3599             env1 = env1.outer;
3600         }
3601         if (c.isInterface() &&
3602             name == names._super && !isStatic(env) &&
3603             types.isDirectSuperInterface(c, env.enclClass.sym)) {
3604             //this might be a default super call if one of the superinterfaces is 'c'
3605             for (Type t : pruneInterfaces(env.enclClass.type)) {
3606                 if (t.tsym == c) {
3607                     env.info.defaultSuperCallSite = t;
3608                     return new VarSymbol(0, names._super,
3609                             types.asSuper(env.enclClass.type, c), env.enclClass.sym);
3610                 }
3611             }
3612             //find a direct super type that is a subtype of 'c'
3613             for (Type i : types.directSupertypes(env.enclClass.type)) {
3614                 if (i.tsym.isSubClass(c, types) && i.tsym != c) {
3615                     log.error(pos,
3616                               Errors.IllegalDefaultSuperCall(c,
3617                                                              Fragments.RedundantSupertype(c, i)));
3618                     return syms.errSymbol;
3619                 }
3620             }
3621             Assert.error();
3622         }
3623         log.error(pos, Errors.NotEnclClass(c));
3624         return syms.errSymbol;
3625     }
3626     //where
3627     private List<Type> pruneInterfaces(Type t) {
3628         ListBuffer<Type> result = new ListBuffer<>();
3629         for (Type t1 : types.interfaces(t)) {
3630             boolean shouldAdd = true;
3631             for (Type t2 : types.directSupertypes(t)) {
3632                 if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) {
3633                     shouldAdd = false;
3634                 }
3635             }
3636             if (shouldAdd) {
3637                 result.append(t1);
3638             }
3639         }
3640         return result.toList();
3641     }
3642 
3643 
3644     /**
3645      * Resolve `c.this' for an enclosing class c that contains the
3646      * named member.
3647      * @param pos           The position to use for error reporting.
3648      * @param env           The environment current at the expression.
3649      * @param member        The member that must be contained in the result.
3650      */
3651     Symbol resolveSelfContaining(DiagnosticPosition pos,
3652                                  Env<AttrContext> env,
3653                                  Symbol member,
3654                                  boolean isSuperCall) {
3655         Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall);
3656         if (sym == null) {
3657             log.error(pos, Errors.EnclClassRequired(member));
3658             return syms.errSymbol;
3659         } else {
3660             return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true);
3661         }
3662     }
3663 
3664     boolean enclosingInstanceMissing(Env<AttrContext> env, Type type) {
3665         if (type.hasTag(CLASS) && type.getEnclosingType().hasTag(CLASS)) {
3666             Symbol encl = resolveSelfContainingInternal(env, type.tsym, false);
3667             return encl == null || encl.kind.isResolutionError();
3668         }
3669         return false;
3670     }
3671 
3672     private Symbol resolveSelfContainingInternal(Env<AttrContext> env,
3673                                  Symbol member,
3674                                  boolean isSuperCall) {
3675         Name name = names._this;
3676         Env<AttrContext> env1 = isSuperCall ? env.outer : env;
3677         boolean staticOnly = false;
3678         if (env1 != null) {
3679             while (env1 != null && env1.outer != null) {
3680                 if (isStatic(env1)) staticOnly = true;
3681                 if (env1.enclClass.sym.isSubClass(member.owner.enclClass(), types)) {
3682                     Symbol sym = env1.info.scope.findFirst(name);
3683                     if (sym != null) {
3684                         if (staticOnly) sym = new StaticError(sym);
3685                         return sym;
3686                     }
3687                 }
3688                 if ((env1.enclClass.sym.flags() & STATIC) != 0)
3689                     staticOnly = true;
3690                 env1 = env1.outer;
3691             }
3692         }
3693         return null;
3694     }
3695 
3696     /**
3697      * Resolve an appropriate implicit this instance for t's container.
3698      * JLS 8.8.5.1 and 15.9.2
3699      */
3700     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
3701         return resolveImplicitThis(pos, env, t, false);
3702     }
3703 
3704     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
3705         Type thisType = (t.tsym.owner.kind.matches(KindSelector.VAL_MTH)
3706                          ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
3707                          : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
3708         if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym) {
3709             log.error(pos, Errors.CantRefBeforeCtorCalled("this"));
3710         }
3711         return thisType;
3712     }
3713 
3714 /* ***************************************************************************
3715  *  ResolveError classes, indicating error situations when accessing symbols
3716  ****************************************************************************/
3717 
3718     //used by TransTypes when checking target type of synthetic cast
3719     public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
3720         AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
3721         logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
3722     }
3723     //where
3724     private void logResolveError(ResolveError error,
3725             DiagnosticPosition pos,
3726             Symbol location,
3727             Type site,
3728             Name name,
3729             List<Type> argtypes,
3730             List<Type> typeargtypes) {
3731         JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
3732                 pos, location, site, name, argtypes, typeargtypes);
3733         if (d != null) {
3734             d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
3735             log.report(d);
3736         }
3737     }
3738 
3739     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
3740 
3741     public Object methodArguments(List<Type> argtypes) {
3742         if (argtypes == null || argtypes.isEmpty()) {
3743             return noArgs;
3744         } else {
3745             ListBuffer<Object> diagArgs = new ListBuffer<>();
3746             for (Type t : argtypes) {
3747                 if (t.hasTag(DEFERRED)) {
3748                     diagArgs.append(((DeferredAttr.DeferredType)t).tree);
3749                 } else {
3750                     diagArgs.append(t);
3751                 }
3752             }
3753             return diagArgs;
3754         }
3755     }
3756 
3757     /**
3758      * Root class for resolution errors. Subclass of ResolveError
3759      * represent a different kinds of resolution error - as such they must
3760      * specify how they map into concrete compiler diagnostics.
3761      */
3762     abstract class ResolveError extends Symbol {
3763 
3764         /** The name of the kind of error, for debugging only. */
3765         final String debugName;
3766 
3767         ResolveError(Kind kind, String debugName) {
3768             super(kind, 0, null, null, null);
3769             this.debugName = debugName;
3770         }
3771 
3772         @Override @DefinedBy(Api.LANGUAGE_MODEL)
3773         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
3774             throw new AssertionError();
3775         }
3776 
3777         @Override
3778         public String toString() {
3779             return debugName;
3780         }
3781 
3782         @Override
3783         public boolean exists() {
3784             return false;
3785         }
3786 
3787         @Override
3788         public boolean isStatic() {
3789             return false;
3790         }
3791 
3792         /**
3793          * Create an external representation for this erroneous symbol to be
3794          * used during attribution - by default this returns the symbol of a
3795          * brand new error type which stores the original type found
3796          * during resolution.
3797          *
3798          * @param name     the name used during resolution
3799          * @param location the location from which the symbol is accessed
3800          */
3801         protected Symbol access(Name name, TypeSymbol location) {
3802             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
3803         }
3804 
3805         /**
3806          * Create a diagnostic representing this resolution error.
3807          *
3808          * @param dkind     The kind of the diagnostic to be created (e.g error).
3809          * @param pos       The position to be used for error reporting.
3810          * @param site      The original type from where the selection took place.
3811          * @param name      The name of the symbol to be resolved.
3812          * @param argtypes  The invocation's value arguments,
3813          *                  if we looked for a method.
3814          * @param typeargtypes  The invocation's type arguments,
3815          *                      if we looked for a method.
3816          */
3817         abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3818                 DiagnosticPosition pos,
3819                 Symbol location,
3820                 Type site,
3821                 Name name,
3822                 List<Type> argtypes,
3823                 List<Type> typeargtypes);
3824     }
3825 
3826     /**
3827      * This class is the root class of all resolution errors caused by
3828      * an invalid symbol being found during resolution.
3829      */
3830     abstract class InvalidSymbolError extends ResolveError {
3831 
3832         /** The invalid symbol found during resolution */
3833         Symbol sym;
3834 
3835         InvalidSymbolError(Kind kind, Symbol sym, String debugName) {
3836             super(kind, debugName);
3837             this.sym = sym;
3838         }
3839 
3840         @Override
3841         public boolean exists() {
3842             return true;
3843         }
3844 
3845         @Override
3846         public String toString() {
3847              return super.toString() + " wrongSym=" + sym;
3848         }
3849 
3850         @Override
3851         public Symbol access(Name name, TypeSymbol location) {
3852             if (!sym.kind.isResolutionError() && sym.kind.matches(KindSelector.TYP))
3853                 return types.createErrorType(name, location, sym.type).tsym;
3854             else
3855                 return sym;
3856         }
3857     }
3858 
3859     class BadRestrictedTypeError extends ResolveError {
3860         private final Name typeName;
3861         BadRestrictedTypeError(Name typeName) {
3862             super(Kind.BAD_RESTRICTED_TYPE, "bad var use");
3863             this.typeName = typeName;
3864         }
3865 
3866         @Override
3867         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
3868             return diags.create(dkind, log.currentSource(), pos, "illegal.ref.to.restricted.type", typeName);
3869         }
3870     }
3871 
3872     /**
3873      * InvalidSymbolError error class indicating that a symbol matching a
3874      * given name does not exists in a given site.
3875      */
3876     class SymbolNotFoundError extends ResolveError {
3877 
3878         SymbolNotFoundError(Kind kind) {
3879             this(kind, "symbol not found error");
3880         }
3881 
3882         SymbolNotFoundError(Kind kind, String debugName) {
3883             super(kind, debugName);
3884         }
3885 
3886         @Override
3887         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3888                 DiagnosticPosition pos,
3889                 Symbol location,
3890                 Type site,
3891                 Name name,
3892                 List<Type> argtypes,
3893                 List<Type> typeargtypes) {
3894             argtypes = argtypes == null ? List.nil() : argtypes;
3895             typeargtypes = typeargtypes == null ? List.nil() : typeargtypes;
3896             if (name == names.error)
3897                 return null;
3898 
3899             boolean hasLocation = false;
3900             if (location == null) {
3901                 location = site.tsym;
3902             }
3903             if (!location.name.isEmpty()) {
3904                 if (location.kind == PCK && !site.tsym.exists()) {
3905                     return diags.create(dkind, log.currentSource(), pos,
3906                         "doesnt.exist", location);
3907                 }
3908                 hasLocation = !location.name.equals(names._this) &&
3909                         !location.name.equals(names._super);
3910             }
3911             boolean isConstructor = name == names.init;
3912             KindName kindname = isConstructor ? KindName.CONSTRUCTOR : kind.absentKind();
3913             Name idname = isConstructor ? site.tsym.name : name;
3914             String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
3915             if (hasLocation) {
3916                 return diags.create(dkind, log.currentSource(), pos,
3917                         errKey, kindname, idname, //symbol kindname, name
3918                         typeargtypes, args(argtypes), //type parameters and arguments (if any)
3919                         getLocationDiag(location, site)); //location kindname, type
3920             }
3921             else {
3922                 return diags.create(dkind, log.currentSource(), pos,
3923                         errKey, kindname, idname, //symbol kindname, name
3924                         typeargtypes, args(argtypes)); //type parameters and arguments (if any)
3925             }
3926         }
3927         //where
3928         private Object args(List<Type> args) {
3929             return args.isEmpty() ? args : methodArguments(args);
3930         }
3931 
3932         private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
3933             String key = "cant.resolve";
3934             String suffix = hasLocation ? ".location" : "";
3935             switch (kindname) {
3936                 case METHOD:
3937                 case CONSTRUCTOR: {
3938                     suffix += ".args";
3939                     suffix += hasTypeArgs ? ".params" : "";
3940                 }
3941             }
3942             return key + suffix;
3943         }
3944         private JCDiagnostic getLocationDiag(Symbol location, Type site) {
3945             if (location.kind == VAR) {
3946                 return diags.fragment(Fragments.Location1(kindName(location),
3947                                                           location,
3948                                                           location.type));
3949             } else {
3950                 return diags.fragment(Fragments.Location(typeKindName(site),
3951                                       site,
3952                                       null));
3953             }
3954         }
3955     }
3956 
3957     /**
3958      * InvalidSymbolError error class indicating that a given symbol
3959      * (either a method, a constructor or an operand) is not applicable
3960      * given an actual arguments/type argument list.
3961      */
3962     class InapplicableSymbolError extends ResolveError {
3963 
3964         protected MethodResolutionContext resolveContext;
3965 
3966         InapplicableSymbolError(MethodResolutionContext context) {
3967             this(WRONG_MTH, "inapplicable symbol error", context);
3968         }
3969 
3970         protected InapplicableSymbolError(Kind kind, String debugName, MethodResolutionContext context) {
3971             super(kind, debugName);
3972             this.resolveContext = context;
3973         }
3974 
3975         @Override
3976         public String toString() {
3977             return super.toString();
3978         }
3979 
3980         @Override
3981         public boolean exists() {
3982             return true;
3983         }
3984 
3985         @Override
3986         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
3987                 DiagnosticPosition pos,
3988                 Symbol location,
3989                 Type site,
3990                 Name name,
3991                 List<Type> argtypes,
3992                 List<Type> typeargtypes) {
3993             if (name == names.error)
3994                 return null;
3995 
3996             Pair<Symbol, JCDiagnostic> c = errCandidate();
3997             if (compactMethodDiags) {
3998                 JCDiagnostic simpleDiag =
3999                     MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, c.snd);
4000                 if (simpleDiag != null) {
4001                     return simpleDiag;
4002                 }
4003             }
4004             Symbol ws = c.fst.asMemberOf(site, types);
4005             return diags.create(dkind, log.currentSource(), pos,
4006                       "cant.apply.symbol",
4007                       kindName(ws),
4008                       ws.name == names.init ? ws.owner.name : ws.name,
4009                       methodArguments(ws.type.getParameterTypes()),
4010                       methodArguments(argtypes),
4011                       kindName(ws.owner),
4012                       ws.owner.type,
4013                       c.snd);
4014         }
4015 
4016         @Override
4017         public Symbol access(Name name, TypeSymbol location) {
4018             Symbol sym = bestCandidate();
4019             return types.createErrorType(name, location, sym != null ? sym.type : syms.errSymbol.type).tsym;
4020         }
4021 
4022         protected Symbol bestCandidate() {
4023             return errCandidate().fst;
4024         }
4025 
4026         protected Pair<Symbol, JCDiagnostic> errCandidate() {
4027             Candidate bestSoFar = null;
4028             for (Candidate c : resolveContext.candidates) {
4029                 if (c.isApplicable()) continue;
4030                 bestSoFar = c;
4031             }
4032             Assert.checkNonNull(bestSoFar);
4033             return new Pair<>(bestSoFar.sym, bestSoFar.details);
4034         }
4035     }
4036 
4037     /**
4038      * ResolveError error class indicating that a symbol (either methods, constructors or operand)
4039      * is not applicable given an actual arguments/type argument list.
4040      */
4041     class InapplicableSymbolsError extends InapplicableSymbolError {
4042 
4043         InapplicableSymbolsError(MethodResolutionContext context) {
4044             super(WRONG_MTHS, "inapplicable symbols", context);
4045         }
4046 
4047         @Override
4048         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4049                 DiagnosticPosition pos,
4050                 Symbol location,
4051                 Type site,
4052                 Name name,
4053                 List<Type> argtypes,
4054                 List<Type> typeargtypes) {
4055             Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
4056             Map<Symbol, JCDiagnostic> filteredCandidates = compactMethodDiags ?
4057                     filterCandidates(candidatesMap) :
4058                     mapCandidates();
4059             if (filteredCandidates.isEmpty()) {
4060                 filteredCandidates = candidatesMap;
4061             }
4062             boolean truncatedDiag = candidatesMap.size() != filteredCandidates.size();
4063             if (filteredCandidates.size() > 1) {
4064                 JCDiagnostic err = diags.create(dkind,
4065                         null,
4066                         truncatedDiag ?
4067                             EnumSet.of(DiagnosticFlag.COMPRESSED) :
4068                             EnumSet.noneOf(DiagnosticFlag.class),
4069                         log.currentSource(),
4070                         pos,
4071                         "cant.apply.symbols",
4072                         name == names.init ? KindName.CONSTRUCTOR : kind.absentKind(),
4073                         name == names.init ? site.tsym.name : name,
4074                         methodArguments(argtypes));
4075                 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(filteredCandidates, site));
4076             } else if (filteredCandidates.size() == 1) {
4077                 Map.Entry<Symbol, JCDiagnostic> _e =
4078                                 filteredCandidates.entrySet().iterator().next();
4079                 final Pair<Symbol, JCDiagnostic> p = new Pair<>(_e.getKey(), _e.getValue());
4080                 JCDiagnostic d = new InapplicableSymbolError(resolveContext) {
4081                     @Override
4082                     protected Pair<Symbol, JCDiagnostic> errCandidate() {
4083                         return p;
4084                     }
4085                 }.getDiagnostic(dkind, pos,
4086                     location, site, name, argtypes, typeargtypes);
4087                 if (truncatedDiag) {
4088                     d.setFlag(DiagnosticFlag.COMPRESSED);
4089                 }
4090                 return d;
4091             } else {
4092                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
4093                     location, site, name, argtypes, typeargtypes);
4094             }
4095         }
4096         //where
4097             private Map<Symbol, JCDiagnostic> mapCandidates() {
4098                 MostSpecificMap candidates = new MostSpecificMap();
4099                 for (Candidate c : resolveContext.candidates) {
4100                     if (c.isApplicable()) continue;
4101                     candidates.put(c);
4102                 }
4103                 return candidates;
4104             }
4105 
4106             @SuppressWarnings("serial")
4107             private class MostSpecificMap extends LinkedHashMap<Symbol, JCDiagnostic> {
4108                 private void put(Candidate c) {
4109                     ListBuffer<Symbol> overridden = new ListBuffer<>();
4110                     for (Symbol s : keySet()) {
4111                         if (s == c.sym) {
4112                             continue;
4113                         }
4114                         if (c.sym.overrides(s, (TypeSymbol)s.owner, types, false)) {
4115                             overridden.add(s);
4116                         } else if (s.overrides(c.sym, (TypeSymbol)c.sym.owner, types, false)) {
4117                             return;
4118                         }
4119                     }
4120                     for (Symbol s : overridden) {
4121                         remove(s);
4122                     }
4123                     put(c.sym, c.details);
4124                 }
4125             }
4126 
4127             Map<Symbol, JCDiagnostic> filterCandidates(Map<Symbol, JCDiagnostic> candidatesMap) {
4128                 Map<Symbol, JCDiagnostic> candidates = new LinkedHashMap<>();
4129                 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
4130                     JCDiagnostic d = _entry.getValue();
4131                     if (!new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) {
4132                         candidates.put(_entry.getKey(), d);
4133                     }
4134                 }
4135                 return candidates;
4136             }
4137 
4138             private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidatesMap, Type site) {
4139                 List<JCDiagnostic> details = List.nil();
4140                 for (Map.Entry<Symbol, JCDiagnostic> _entry : candidatesMap.entrySet()) {
4141                     Symbol sym = _entry.getKey();
4142                     JCDiagnostic detailDiag =
4143                             diags.fragment(Fragments.InapplicableMethod(Kinds.kindName(sym),
4144                                                                         sym.location(site, types),
4145                                                                         sym.asMemberOf(site, types),
4146                                                                         _entry.getValue()));
4147                     details = details.prepend(detailDiag);
4148                 }
4149                 //typically members are visited in reverse order (see Scope)
4150                 //so we need to reverse the candidate list so that candidates
4151                 //conform to source order
4152                 return details;
4153             }
4154 
4155         @Override
4156         protected Symbol bestCandidate() {
4157             Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
4158             Map<Symbol, JCDiagnostic> filteredCandidates = filterCandidates(candidatesMap);
4159             if (filteredCandidates.size() == 1) {
4160                 return filteredCandidates.keySet().iterator().next();
4161             }
4162             return null;
4163         }
4164     }
4165 
4166     /**
4167      * DiamondError error class indicating that a constructor symbol is not applicable
4168      * given an actual arguments/type argument list using diamond inference.
4169      */
4170     class DiamondError extends InapplicableSymbolError {
4171 
4172         Symbol sym;
4173 
4174         public DiamondError(Symbol sym, MethodResolutionContext context) {
4175             super(sym.kind, "diamondError", context);
4176             this.sym = sym;
4177         }
4178 
4179         JCDiagnostic getDetails() {
4180             return (sym.kind == WRONG_MTH) ?
4181                     ((InapplicableSymbolError)sym.baseSymbol()).errCandidate().snd :
4182                     null;
4183         }
4184 
4185         @Override
4186         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
4187                 Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4188             JCDiagnostic details = getDetails();
4189             if (details != null && compactMethodDiags) {
4190                 JCDiagnostic simpleDiag =
4191                         MethodResolutionDiagHelper.rewrite(diags, pos, log.currentSource(), dkind, details);
4192                 if (simpleDiag != null) {
4193                     return simpleDiag;
4194                 }
4195             }
4196             String key = details == null ?
4197                 "cant.apply.diamond" :
4198                 "cant.apply.diamond.1";
4199             return diags.create(dkind, log.currentSource(), pos, key,
4200                     Fragments.Diamond(site.tsym), details);
4201         }
4202     }
4203 
4204     /**
4205      * An InvalidSymbolError error class indicating that a symbol is not
4206      * accessible from a given site
4207      */
4208     class AccessError extends InvalidSymbolError {
4209 
4210         private Env<AttrContext> env;
4211         private Type site;
4212 
4213         AccessError(Env<AttrContext> env, Type site, Symbol sym) {
4214             super(HIDDEN, sym, "access error");
4215             this.env = env;
4216             this.site = site;
4217         }
4218 
4219         @Override
4220         public boolean exists() {
4221             return false;
4222         }
4223 
4224         @Override
4225         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4226                 DiagnosticPosition pos,
4227                 Symbol location,
4228                 Type site,
4229                 Name name,
4230                 List<Type> argtypes,
4231                 List<Type> typeargtypes) {
4232             if (sym.name == names.init && sym.owner != site.tsym) {
4233                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
4234                         pos, location, site, name, argtypes, typeargtypes);
4235             }
4236             else if ((sym.flags() & PUBLIC) != 0
4237                 || (env != null && this.site != null
4238                     && !isAccessible(env, this.site))) {
4239                 if (sym.owner.kind == PCK) {
4240                     return diags.create(dkind, log.currentSource(),
4241                             pos, "not.def.access.package.cant.access",
4242                         sym, sym.location(), inaccessiblePackageReason(env, sym.packge()));
4243                 } else if (   sym.packge() != syms.rootPackage
4244                            && !symbolPackageVisible(env, sym)) {
4245                     return diags.create(dkind, log.currentSource(),
4246                             pos, "not.def.access.class.intf.cant.access.reason",
4247                             sym, sym.location(), sym.location().packge(),
4248                             inaccessiblePackageReason(env, sym.packge()));
4249                 } else {
4250                     return diags.create(dkind, log.currentSource(),
4251                             pos, "not.def.access.class.intf.cant.access",
4252                         sym, sym.location());
4253                 }
4254             }
4255             else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
4256                 return diags.create(dkind, log.currentSource(),
4257                         pos, "report.access", sym,
4258                         asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
4259                         sym.location());
4260             }
4261             else {
4262                 return diags.create(dkind, log.currentSource(),
4263                         pos, "not.def.public.cant.access", sym, sym.location());
4264             }
4265         }
4266 
4267         private String toString(Type type) {
4268             StringBuilder sb = new StringBuilder();
4269             sb.append(type);
4270             if (type != null) {
4271                 sb.append("[tsym:").append(type.tsym);
4272                 if (type.tsym != null)
4273                     sb.append("packge:").append(type.tsym.packge());
4274                 sb.append("]");
4275             }
4276             return sb.toString();
4277         }
4278     }
4279 
4280     class InvisibleSymbolError extends InvalidSymbolError {
4281 
4282         private final Env<AttrContext> env;
4283         private final boolean suppressError;
4284 
4285         InvisibleSymbolError(Env<AttrContext> env, boolean suppressError, Symbol sym) {
4286             super(HIDDEN, sym, "invisible class error");
4287             this.env = env;
4288             this.suppressError = suppressError;
4289             this.name = sym.name;
4290         }
4291 
4292         @Override
4293         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4294                 DiagnosticPosition pos,
4295                 Symbol location,
4296                 Type site,
4297                 Name name,
4298                 List<Type> argtypes,
4299                 List<Type> typeargtypes) {
4300             if (suppressError)
4301                 return null;
4302 
4303             if (sym.kind == PCK) {
4304                 JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
4305                 return diags.create(dkind, log.currentSource(),
4306                         pos, "package.not.visible", sym, details);
4307             }
4308 
4309             JCDiagnostic details = inaccessiblePackageReason(env, sym.packge());
4310 
4311             if (pos.getTree() != null) {
4312                 Symbol o = sym;
4313                 JCTree tree = pos.getTree();
4314 
4315                 while (o.kind != PCK && tree.hasTag(SELECT)) {
4316                     o = o.owner;
4317                     tree = ((JCFieldAccess) tree).selected;
4318                 }
4319 
4320                 if (o.kind == PCK) {
4321                     pos = tree.pos();
4322 
4323                     return diags.create(dkind, log.currentSource(),
4324                             pos, "package.not.visible", o, details);
4325                 }
4326             }
4327 
4328             return diags.create(dkind, log.currentSource(),
4329                     pos, "not.def.access.package.cant.access", sym, sym.packge(), details);
4330         }
4331     }
4332 
4333     JCDiagnostic inaccessiblePackageReason(Env<AttrContext> env, PackageSymbol sym) {
4334         //no dependency:
4335         if (!env.toplevel.modle.readModules.contains(sym.modle)) {
4336             //does not read:
4337             if (sym.modle != syms.unnamedModule) {
4338                 if (env.toplevel.modle != syms.unnamedModule) {
4339                     return diags.fragment(Fragments.NotDefAccessDoesNotRead(env.toplevel.modle,
4340                                                                             sym,
4341                                                                             sym.modle));
4342                 } else {
4343                     return diags.fragment(Fragments.NotDefAccessDoesNotReadFromUnnamed(sym,
4344                                                                                        sym.modle));
4345                 }
4346             } else {
4347                 return diags.fragment(Fragments.NotDefAccessDoesNotReadUnnamed(sym,
4348                                                                                env.toplevel.modle));
4349             }
4350         } else {
4351             if (sym.packge().modle.exports.stream().anyMatch(e -> e.packge == sym)) {
4352                 //not exported to this module:
4353                 if (env.toplevel.modle != syms.unnamedModule) {
4354                     return diags.fragment(Fragments.NotDefAccessNotExportedToModule(sym,
4355                                                                                     sym.modle,
4356                                                                                     env.toplevel.modle));
4357                 } else {
4358                     return diags.fragment(Fragments.NotDefAccessNotExportedToModuleFromUnnamed(sym,
4359                                                                                                sym.modle));
4360                 }
4361             } else {
4362                 //not exported:
4363                 if (env.toplevel.modle != syms.unnamedModule) {
4364                     return diags.fragment(Fragments.NotDefAccessNotExported(sym,
4365                                                                             sym.modle));
4366                 } else {
4367                     return diags.fragment(Fragments.NotDefAccessNotExportedFromUnnamed(sym,
4368                                                                                        sym.modle));
4369                 }
4370             }
4371         }
4372     }
4373 
4374     /**
4375      * InvalidSymbolError error class indicating that an instance member
4376      * has erroneously been accessed from a static context.
4377      */
4378     class StaticError extends InvalidSymbolError {
4379 
4380         StaticError(Symbol sym) {
4381             super(STATICERR, sym, "static error");
4382         }
4383 
4384         @Override
4385         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4386                 DiagnosticPosition pos,
4387                 Symbol location,
4388                 Type site,
4389                 Name name,
4390                 List<Type> argtypes,
4391                 List<Type> typeargtypes) {
4392             Symbol errSym = ((sym.kind == TYP && sym.type.hasTag(CLASS))
4393                 ? types.erasure(sym.type).tsym
4394                 : sym);
4395             return diags.create(dkind, log.currentSource(), pos,
4396                     "non-static.cant.be.ref", kindName(sym), errSym);
4397         }
4398     }
4399 
4400     /**
4401      * InvalidSymbolError error class indicating that a pair of symbols
4402      * (either methods, constructors or operands) are ambiguous
4403      * given an actual arguments/type argument list.
4404      */
4405     class AmbiguityError extends ResolveError {
4406 
4407         /** The other maximally specific symbol */
4408         List<Symbol> ambiguousSyms = List.nil();
4409 
4410         @Override
4411         public boolean exists() {
4412             return true;
4413         }
4414 
4415         AmbiguityError(Symbol sym1, Symbol sym2) {
4416             super(AMBIGUOUS, "ambiguity error");
4417             ambiguousSyms = flatten(sym2).appendList(flatten(sym1));
4418         }
4419 
4420         private List<Symbol> flatten(Symbol sym) {
4421             if (sym.kind == AMBIGUOUS) {
4422                 return ((AmbiguityError)sym.baseSymbol()).ambiguousSyms;
4423             } else {
4424                 return List.of(sym);
4425             }
4426         }
4427 
4428         AmbiguityError addAmbiguousSymbol(Symbol s) {
4429             ambiguousSyms = ambiguousSyms.prepend(s);
4430             return this;
4431         }
4432 
4433         @Override
4434         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
4435                 DiagnosticPosition pos,
4436                 Symbol location,
4437                 Type site,
4438                 Name name,
4439                 List<Type> argtypes,
4440                 List<Type> typeargtypes) {
4441             List<Symbol> diagSyms = ambiguousSyms.reverse();
4442             Symbol s1 = diagSyms.head;
4443             Symbol s2 = diagSyms.tail.head;
4444             Name sname = s1.name;
4445             if (sname == names.init) sname = s1.owner.name;
4446             return diags.create(dkind, log.currentSource(),
4447                     pos, "ref.ambiguous", sname,
4448                     kindName(s1),
4449                     s1,
4450                     s1.location(site, types),
4451                     kindName(s2),
4452                     s2,
4453                     s2.location(site, types));
4454         }
4455 
4456         /**
4457          * If multiple applicable methods are found during overload and none of them
4458          * is more specific than the others, attempt to merge their signatures.
4459          */
4460         Symbol mergeAbstracts(Type site) {
4461             List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
4462             return types.mergeAbstracts(ambiguousInOrder, site, true).orElse(this);
4463         }
4464 
4465         @Override
4466         protected Symbol access(Name name, TypeSymbol location) {
4467             Symbol firstAmbiguity = ambiguousSyms.last();
4468             return firstAmbiguity.kind == TYP ?
4469                     types.createErrorType(name, location, firstAmbiguity.type).tsym :
4470                     firstAmbiguity;
4471         }
4472     }
4473 
4474     class BadVarargsMethod extends ResolveError {
4475 
4476         ResolveError delegatedError;
4477 
4478         BadVarargsMethod(ResolveError delegatedError) {
4479             super(delegatedError.kind, "badVarargs");
4480             this.delegatedError = delegatedError;
4481         }
4482 
4483         @Override
4484         public Symbol baseSymbol() {
4485             return delegatedError.baseSymbol();
4486         }
4487 
4488         @Override
4489         protected Symbol access(Name name, TypeSymbol location) {
4490             return delegatedError.access(name, location);
4491         }
4492 
4493         @Override
4494         public boolean exists() {
4495             return true;
4496         }
4497 
4498         @Override
4499         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4500             return delegatedError.getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes);
4501         }
4502     }
4503 
4504     /**
4505      * BadMethodReferenceError error class indicating that a method reference symbol has been found,
4506      * but with the wrong staticness.
4507      */
4508     class BadMethodReferenceError extends StaticError {
4509 
4510         boolean unboundLookup;
4511 
4512         public BadMethodReferenceError(Symbol sym, boolean unboundLookup) {
4513             super(sym);
4514             this.unboundLookup = unboundLookup;
4515         }
4516 
4517         @Override
4518         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4519             final String key;
4520             if (!unboundLookup) {
4521                 key = "bad.static.method.in.bound.lookup";
4522             } else if (sym.isStatic()) {
4523                 key = "bad.static.method.in.unbound.lookup";
4524             } else {
4525                 key = "bad.instance.method.in.unbound.lookup";
4526             }
4527             return sym.kind.isResolutionError() ?
4528                     ((ResolveError)sym).getDiagnostic(dkind, pos, location, site, name, argtypes, typeargtypes) :
4529                     diags.create(dkind, log.currentSource(), pos, key, Kinds.kindName(sym), sym);
4530         }
4531     }
4532 
4533     /**
4534      * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found,
4535      * but pointing to a class for which an enclosing instance is not available.
4536      */
4537     class BadConstructorReferenceError extends InvalidSymbolError {
4538 
4539         public BadConstructorReferenceError(Symbol sym) {
4540             super(MISSING_ENCL, sym, "BadConstructorReferenceError");
4541         }
4542 
4543         @Override
4544         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4545            return diags.create(dkind, log.currentSource(), pos,
4546                 "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
4547         }
4548     }
4549 
4550     class BadClassFileError extends InvalidSymbolError {
4551 
4552         private final CompletionFailure ex;
4553 
4554         public BadClassFileError(CompletionFailure ex) {
4555             super(HIDDEN, ex.sym, "BadClassFileError");
4556             this.name = sym.name;
4557             this.ex = ex;
4558         }
4559 
4560         @Override
4561         JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
4562             JCDiagnostic d = diags.create(dkind, log.currentSource(), pos,
4563                 "cant.access", ex.sym, ex.getDetailValue());
4564 
4565             d.setFlag(DiagnosticFlag.NON_DEFERRABLE);
4566             return d;
4567         }
4568 
4569     }
4570 
4571     /**
4572      * Helper class for method resolution diagnostic simplification.
4573      * Certain resolution diagnostic are rewritten as simpler diagnostic
4574      * where the enclosing resolution diagnostic (i.e. 'inapplicable method')
4575      * is stripped away, as it doesn't carry additional info. The logic
4576      * for matching a given diagnostic is given in terms of a template
4577      * hierarchy: a diagnostic template can be specified programmatically,
4578      * so that only certain diagnostics are matched. Each templete is then
4579      * associated with a rewriter object that carries out the task of rewtiting
4580      * the diagnostic to a simpler one.
4581      */
4582     static class MethodResolutionDiagHelper {
4583 
4584         /**
4585          * A diagnostic rewriter transforms a method resolution diagnostic
4586          * into a simpler one
4587          */
4588         interface DiagnosticRewriter {
4589             JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4590                     DiagnosticPosition preferredPos, DiagnosticSource preferredSource,
4591                     DiagnosticType preferredKind, JCDiagnostic d);
4592         }
4593 
4594         /**
4595          * A diagnostic template is made up of two ingredients: (i) a regular
4596          * expression for matching a diagnostic key and (ii) a list of sub-templates
4597          * for matching diagnostic arguments.
4598          */
4599         static class Template {
4600 
4601             /** regex used to match diag key */
4602             String regex;
4603 
4604             /** templates used to match diagnostic args */
4605             Template[] subTemplates;
4606 
4607             Template(String key, Template... subTemplates) {
4608                 this.regex = key;
4609                 this.subTemplates = subTemplates;
4610             }
4611 
4612             /**
4613              * Returns true if the regex matches the diagnostic key and if
4614              * all diagnostic arguments are matches by corresponding sub-templates.
4615              */
4616             boolean matches(Object o) {
4617                 JCDiagnostic d = (JCDiagnostic)o;
4618                 Object[] args = d.getArgs();
4619                 if (!d.getCode().matches(regex) ||
4620                         subTemplates.length != d.getArgs().length) {
4621                     return false;
4622                 }
4623                 for (int i = 0; i < args.length ; i++) {
4624                     if (!subTemplates[i].matches(args[i])) {
4625                         return false;
4626                     }
4627                 }
4628                 return true;
4629             }
4630         }
4631 
4632         /**
4633          * Common rewriter for all argument mismatch simplifications.
4634          */
4635         static class ArgMismatchRewriter implements DiagnosticRewriter {
4636 
4637             /** the index of the subdiagnostic to be used as primary. */
4638             int causeIndex;
4639 
4640             public ArgMismatchRewriter(int causeIndex) {
4641                 this.causeIndex = causeIndex;
4642             }
4643 
4644             @Override
4645             public JCDiagnostic rewriteDiagnostic(JCDiagnostic.Factory diags,
4646                     DiagnosticPosition preferredPos, DiagnosticSource preferredSource,
4647                     DiagnosticType preferredKind, JCDiagnostic d) {
4648                 JCDiagnostic cause = (JCDiagnostic)d.getArgs()[causeIndex];
4649                 DiagnosticPosition pos = d.getDiagnosticPosition();
4650                 if (pos == null) {
4651                     pos = preferredPos;
4652                 }
4653                 return diags.create(preferredKind, preferredSource, pos,
4654                         "prob.found.req", cause);
4655             }
4656         }
4657 
4658         /** a dummy template that match any diagnostic argument */
4659         static final Template skip = new Template("") {
4660             @Override
4661             boolean matches(Object d) {
4662                 return true;
4663             }
4664         };
4665 
4666         /** template for matching inference-free arguments mismatch failures */
4667         static final Template argMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip);
4668 
4669         /** template for matching inference related arguments mismatch failures */
4670         static final Template inferArgMismatchTemplate = new Template(MethodCheckDiag.ARG_MISMATCH.regex(), skip, skip) {
4671             @Override
4672             boolean matches(Object o) {
4673                 if (!super.matches(o)) {
4674                     return false;
4675                 }
4676                 JCDiagnostic d = (JCDiagnostic)o;
4677                 @SuppressWarnings("unchecked")
4678                 List<Type> tvars = (List<Type>)d.getArgs()[0];
4679                 return !containsAny(d, tvars);
4680             }
4681 
4682             BiPredicate<Object, List<Type>> containsPredicate = (o, ts) -> {
4683                 if (o instanceof Type) {
4684                     return ((Type)o).containsAny(ts);
4685                 } else if (o instanceof JCDiagnostic) {
4686                     return containsAny((JCDiagnostic)o, ts);
4687                 } else {
4688                     return false;
4689                 }
4690             };
4691 
4692             boolean containsAny(JCDiagnostic d, List<Type> ts) {
4693                 return Stream.of(d.getArgs())
4694                         .anyMatch(o -> containsPredicate.test(o, ts));
4695             }
4696         };
4697 
4698         /** rewriter map used for method resolution simplification */
4699         static final Map<Template, DiagnosticRewriter> rewriters = new LinkedHashMap<>();
4700 
4701         static {
4702             rewriters.put(argMismatchTemplate, new ArgMismatchRewriter(0));
4703             rewriters.put(inferArgMismatchTemplate, new ArgMismatchRewriter(1));
4704         }
4705 
4706         /**
4707          * Main entry point for diagnostic rewriting - given a diagnostic, see if any templates matches it,
4708          * and rewrite it accordingly.
4709          */
4710         static JCDiagnostic rewrite(JCDiagnostic.Factory diags, DiagnosticPosition pos, DiagnosticSource source,
4711                                     DiagnosticType dkind, JCDiagnostic d) {
4712             for (Map.Entry<Template, DiagnosticRewriter> _entry : rewriters.entrySet()) {
4713                 if (_entry.getKey().matches(d)) {
4714                     JCDiagnostic simpleDiag =
4715                             _entry.getValue().rewriteDiagnostic(diags, pos, source, dkind, d);
4716                     simpleDiag.setFlag(DiagnosticFlag.COMPRESSED);
4717                     return simpleDiag;
4718                 }
4719             }
4720             return null;
4721         }
4722     }
4723 
4724     enum MethodResolutionPhase {
4725         BASIC(false, false),
4726         BOX(true, false),
4727         VARARITY(true, true) {
4728             @Override
4729             public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
4730                 //Check invariants (see {@code LookupHelper.shouldStop})
4731                 Assert.check(bestSoFar.kind.isResolutionError() && bestSoFar.kind != AMBIGUOUS);
4732                 if (!sym.kind.isResolutionError()) {
4733                     //varargs resolution successful
4734                     return sym;
4735                 } else {
4736                     //pick best error
4737                     switch (bestSoFar.kind) {
4738                         case WRONG_MTH:
4739                         case WRONG_MTHS:
4740                             //Override previous errors if they were caused by argument mismatch.
4741                             //This generally means preferring current symbols - but we need to pay
4742                             //attention to the fact that the varargs lookup returns 'less' candidates
4743                             //than the previous rounds, and adjust that accordingly.
4744                             switch (sym.kind) {
4745                                 case WRONG_MTH:
4746                                     //if the previous round matched more than one method, return that
4747                                     //result instead
4748                                     return bestSoFar.kind == WRONG_MTHS ?
4749                                             bestSoFar : sym;
4750                                 case ABSENT_MTH:
4751                                     //do not override erroneous symbol if the arity lookup did not
4752                                     //match any method
4753                                     return bestSoFar;
4754                                 case WRONG_MTHS:
4755                                 default:
4756                                     //safe to override
4757                                     return sym;
4758                             }
4759                         default:
4760                             //otherwise, return first error
4761                             return bestSoFar;
4762                     }
4763                 }
4764             }
4765         };
4766 
4767         final boolean isBoxingRequired;
4768         final boolean isVarargsRequired;
4769 
4770         MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
4771            this.isBoxingRequired = isBoxingRequired;
4772            this.isVarargsRequired = isVarargsRequired;
4773         }
4774 
4775         public boolean isBoxingRequired() {
4776             return isBoxingRequired;
4777         }
4778 
4779         public boolean isVarargsRequired() {
4780             return isVarargsRequired;
4781         }
4782 
4783         public Symbol mergeResults(Symbol prev, Symbol sym) {
4784             return sym;
4785         }
4786     }
4787 
4788     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
4789 
4790     /**
4791      * A resolution context is used to keep track of intermediate results of
4792      * overload resolution, such as list of method that are not applicable
4793      * (used to generate more precise diagnostics) and so on. Resolution contexts
4794      * can be nested - this means that when each overload resolution routine should
4795      * work within the resolution context it created.
4796      */
4797     class MethodResolutionContext {
4798 
4799         private List<Candidate> candidates = List.nil();
4800 
4801         MethodResolutionPhase step = null;
4802 
4803         MethodCheck methodCheck = resolveMethodCheck;
4804 
4805         private boolean internalResolution = false;
4806         private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
4807 
4808         void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
4809             Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
4810             candidates = candidates.append(c);
4811         }
4812 
4813         void addApplicableCandidate(Symbol sym, Type mtype) {
4814             Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
4815             candidates = candidates.append(c);
4816         }
4817 
4818         DeferredAttrContext deferredAttrContext(Symbol sym, InferenceContext inferenceContext, ResultInfo pendingResult, Warner warn) {
4819             DeferredAttrContext parent = (pendingResult == null)
4820                 ? deferredAttr.emptyDeferredAttrContext
4821                 : pendingResult.checkContext.deferredAttrContext();
4822             return deferredAttr.new DeferredAttrContext(attrMode, sym, step,
4823                     inferenceContext, parent, warn);
4824         }
4825 
4826         /**
4827          * This class represents an overload resolution candidate. There are two
4828          * kinds of candidates: applicable methods and inapplicable methods;
4829          * applicable methods have a pointer to the instantiated method type,
4830          * while inapplicable candidates contain further details about the
4831          * reason why the method has been considered inapplicable.
4832          */
4833         @SuppressWarnings("overrides")
4834         class Candidate {
4835 
4836             final MethodResolutionPhase step;
4837             final Symbol sym;
4838             final JCDiagnostic details;
4839             final Type mtype;
4840 
4841             private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
4842                 this.step = step;
4843                 this.sym = sym;
4844                 this.details = details;
4845                 this.mtype = mtype;
4846             }
4847 
4848             boolean isApplicable() {
4849                 return mtype != null;
4850             }
4851         }
4852 
4853         DeferredAttr.AttrMode attrMode() {
4854             return attrMode;
4855         }
4856 
4857         boolean internal() {
4858             return internalResolution;
4859         }
4860     }
4861 
4862     MethodResolutionContext currentResolutionContext = null;
4863 }