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