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