1 /*
   2  * Copyright (c) 1999, 2012, 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.Type.*;
  31 import com.sun.tools.javac.code.Symbol.*;
  32 import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate;
  33 import com.sun.tools.javac.jvm.*;
  34 import com.sun.tools.javac.tree.*;
  35 import com.sun.tools.javac.tree.JCTree.*;
  36 import com.sun.tools.javac.util.*;
  37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  38 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  39 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
  40 
  41 import java.util.Arrays;
  42 import java.util.Collection;
  43 import java.util.EnumMap;
  44 import java.util.EnumSet;
  45 import java.util.HashSet;
  46 import java.util.Map;
  47 import java.util.Set;
  48 
  49 import javax.lang.model.element.ElementVisitor;
  50 
  51 import static com.sun.tools.javac.code.Flags.*;
  52 import static com.sun.tools.javac.code.Flags.BLOCK;
  53 import static com.sun.tools.javac.code.Kinds.*;
  54 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
  55 import static com.sun.tools.javac.code.TypeTags.*;
  56 import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
  57 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  58 
  59 /** Helper class for name resolution, used mostly by the attribution phase.
  60  *
  61  *  <p><b>This is NOT part of any supported API.
  62  *  If you write code that depends on this, you do so at your own risk.
  63  *  This code and its internal interfaces are subject to change or
  64  *  deletion without notice.</b>
  65  */
  66 public class Resolve {
  67     protected static final Context.Key<Resolve> resolveKey =
  68         new Context.Key<Resolve>();
  69 
  70     Names names;
  71     Log log;
  72     Symtab syms;
  73     Check chk;
  74     Infer infer;
  75     ClassReader reader;
  76     TreeInfo treeinfo;
  77     Types types;
  78     JCDiagnostic.Factory diags;
  79     public final boolean boxingEnabled; // = source.allowBoxing();
  80     public final boolean varargsEnabled; // = source.allowVarargs();
  81     public final boolean allowMethodHandles;
  82     private final boolean debugResolve;
  83     final EnumSet<VerboseResolutionMode> verboseResolutionMode;
  84 
  85     Scope polymorphicSignatureScope;
  86 
  87     protected Resolve(Context context) {
  88         context.put(resolveKey, this);
  89         syms = Symtab.instance(context);
  90 
  91         varNotFound = new
  92             SymbolNotFoundError(ABSENT_VAR);
  93         wrongMethod = new
  94             InapplicableSymbolError();
  95         wrongMethods = new
  96             InapplicableSymbolsError();
  97         methodNotFound = new
  98             SymbolNotFoundError(ABSENT_MTH);
  99         typeNotFound = new
 100             SymbolNotFoundError(ABSENT_TYP);
 101 
 102         names = Names.instance(context);
 103         log = Log.instance(context);
 104         chk = Check.instance(context);
 105         infer = Infer.instance(context);
 106         reader = ClassReader.instance(context);
 107         treeinfo = TreeInfo.instance(context);
 108         types = Types.instance(context);
 109         diags = JCDiagnostic.Factory.instance(context);
 110         Source source = Source.instance(context);
 111         boxingEnabled = source.allowBoxing();
 112         varargsEnabled = source.allowVarargs();
 113         Options options = Options.instance(context);
 114         debugResolve = options.isSet("debugresolve");
 115         verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
 116         Target target = Target.instance(context);
 117         allowMethodHandles = target.hasMethodHandles();
 118         polymorphicSignatureScope = new Scope(syms.noSymbol);
 119 
 120         inapplicableMethodException = new InapplicableMethodException(diags);
 121     }
 122 
 123     /** error symbols, which are returned when resolution fails
 124      */
 125     private final SymbolNotFoundError varNotFound;
 126     private final InapplicableSymbolError wrongMethod;
 127     private final InapplicableSymbolsError wrongMethods;
 128     private final SymbolNotFoundError methodNotFound;
 129     private final SymbolNotFoundError typeNotFound;
 130 
 131     public static Resolve instance(Context context) {
 132         Resolve instance = context.get(resolveKey);
 133         if (instance == null)
 134             instance = new Resolve(context);
 135         return instance;
 136     }
 137 
 138     // <editor-fold defaultstate="collapsed" desc="Verbose resolution diagnostics support">
 139     enum VerboseResolutionMode {
 140         SUCCESS("success"),
 141         FAILURE("failure"),
 142         APPLICABLE("applicable"),
 143         INAPPLICABLE("inapplicable"),
 144         DEFERRED_INST("deferred-inference"),
 145         PREDEF("predef"),
 146         OBJECT_INIT("object-init"),
 147         INTERNAL("internal");
 148 
 149         String opt;
 150 
 151         private VerboseResolutionMode(String opt) {
 152             this.opt = opt;
 153         }
 154 
 155         static EnumSet<VerboseResolutionMode> getVerboseResolutionMode(Options opts) {
 156             String s = opts.get("verboseResolution");
 157             EnumSet<VerboseResolutionMode> res = EnumSet.noneOf(VerboseResolutionMode.class);
 158             if (s == null) return res;
 159             if (s.contains("all")) {
 160                 res = EnumSet.allOf(VerboseResolutionMode.class);
 161             }
 162             Collection<String> args = Arrays.asList(s.split(","));
 163             for (VerboseResolutionMode mode : values()) {
 164                 if (args.contains(mode.opt)) {
 165                     res.add(mode);
 166                 } else if (args.contains("-" + mode.opt)) {
 167                     res.remove(mode);
 168                 }
 169             }
 170             return res;
 171         }
 172     }
 173 
 174     void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site,
 175             List<Type> argtypes, List<Type> typeargtypes, Symbol bestSoFar) {
 176         boolean success = bestSoFar.kind < ERRONEOUS;
 177 
 178         if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) {
 179             return;
 180         } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) {
 181             return;
 182         }
 183 
 184         if (bestSoFar.name == names.init &&
 185                 bestSoFar.owner == syms.objectType.tsym &&
 186                 !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) {
 187             return; //skip diags for Object constructor resolution
 188         } else if (site == syms.predefClass.type &&
 189                 !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) {
 190             return; //skip spurious diags for predef symbols (i.e. operators)
 191         } else if (currentResolutionContext.internalResolution &&
 192                 !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) {
 193             return;
 194         }
 195 
 196         int pos = 0;
 197         int mostSpecificPos = -1;
 198         ListBuffer<JCDiagnostic> subDiags = ListBuffer.lb();
 199         for (Candidate c : currentResolutionContext.candidates) {
 200             if (currentResolutionContext.step != c.step ||
 201                     (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) ||
 202                     (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) {
 203                 continue;
 204             } else {
 205                 subDiags.append(c.isApplicable() ?
 206                         getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) :
 207                         getVerboseInapplicableCandidateDiag(pos, c.sym, c.details));
 208                 if (c.sym == bestSoFar)
 209                     mostSpecificPos = pos;
 210                 pos++;
 211             }
 212         }
 213         String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1";
 214         JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name,
 215                 site.tsym, mostSpecificPos, currentResolutionContext.step,
 216                 methodArguments(argtypes), methodArguments(typeargtypes));
 217         JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList());
 218         log.report(d);
 219     }
 220 
 221     JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) {
 222         JCDiagnostic subDiag = null;
 223         if (inst.getReturnType().tag == FORALL) {
 224             Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(),
 225                                                             ((ForAll)inst.getReturnType()).qtype);
 226             subDiag = diags.fragment("partial.inst.sig", diagType);
 227         } else if (sym.type.tag == FORALL) {
 228             subDiag = diags.fragment("full.inst.sig", inst.asMethodType());
 229         }
 230 
 231         String key = subDiag == null ?
 232                 "applicable.method.found" :
 233                 "applicable.method.found.1";
 234 
 235         return diags.fragment(key, pos, sym, subDiag);
 236     }
 237 
 238     JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) {
 239         return diags.fragment("not.applicable.method.found", pos, sym, subDiag);
 240     }
 241     // </editor-fold>
 242 
 243 /* ************************************************************************
 244  * Identifier resolution
 245  *************************************************************************/
 246 
 247     /** An environment is "static" if its static level is greater than
 248      *  the one of its outer environment
 249      */
 250     static boolean isStatic(Env<AttrContext> env) {
 251         return env.info.staticLevel > env.outer.info.staticLevel;
 252     }
 253 
 254     /** An environment is an "initializer" if it is a constructor or
 255      *  an instance initializer.
 256      */
 257     static boolean isInitializer(Env<AttrContext> env) {
 258         Symbol owner = env.info.scope.owner;
 259         return owner.isConstructor() ||
 260             owner.owner.kind == TYP &&
 261             (owner.kind == VAR ||
 262              owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
 263             (owner.flags() & STATIC) == 0;
 264     }
 265 
 266     /** Is class accessible in given evironment?
 267      *  @param env    The current environment.
 268      *  @param c      The class whose accessibility is checked.
 269      */
 270     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
 271         return isAccessible(env, c, false);
 272     }
 273 
 274     public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
 275         boolean isAccessible = false;
 276         switch ((short)(c.flags() & AccessFlags)) {
 277             case PRIVATE:
 278                 isAccessible =
 279                     env.enclClass.sym.outermostClass() ==
 280                     c.owner.outermostClass();
 281                 break;
 282             case 0:
 283                 isAccessible =
 284                     env.toplevel.packge == c.owner // fast special case
 285                     ||
 286                     env.toplevel.packge == c.packge()
 287                     ||
 288                     // Hack: this case is added since synthesized default constructors
 289                     // of anonymous classes should be allowed to access
 290                     // classes which would be inaccessible otherwise.
 291                     env.enclMethod != null &&
 292                     (env.enclMethod.mods.flags & ANONCONSTR) != 0;
 293                 break;
 294             default: // error recovery
 295             case PUBLIC:
 296                 isAccessible = true;
 297                 break;
 298             case PROTECTED:
 299                 isAccessible =
 300                     env.toplevel.packge == c.owner // fast special case
 301                     ||
 302                     env.toplevel.packge == c.packge()
 303                     ||
 304                     isInnerSubClass(env.enclClass.sym, c.owner);
 305                 break;
 306         }
 307         return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
 308             isAccessible :
 309             isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
 310     }
 311     //where
 312         /** Is given class a subclass of given base class, or an inner class
 313          *  of a subclass?
 314          *  Return null if no such class exists.
 315          *  @param c     The class which is the subclass or is contained in it.
 316          *  @param base  The base class
 317          */
 318         private boolean isInnerSubClass(ClassSymbol c, Symbol base) {
 319             while (c != null && !c.isSubClass(base, types)) {
 320                 c = c.owner.enclClass();
 321             }
 322             return c != null;
 323         }
 324 
 325     boolean isAccessible(Env<AttrContext> env, Type t) {
 326         return isAccessible(env, t, false);
 327     }
 328 
 329     boolean isAccessible(Env<AttrContext> env, Type t, boolean checkInner) {
 330         return (t.tag == ARRAY)
 331             ? isAccessible(env, types.elemtype(t))
 332             : isAccessible(env, t.tsym, checkInner);
 333     }
 334 
 335     /** Is symbol accessible as a member of given type in given evironment?
 336      *  @param env    The current environment.
 337      *  @param site   The type of which the tested symbol is regarded
 338      *                as a member.
 339      *  @param sym    The symbol.
 340      */
 341     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym) {
 342         return isAccessible(env, site, sym, false);
 343     }
 344     public boolean isAccessible(Env<AttrContext> env, Type site, Symbol sym, boolean checkInner) {
 345         if (sym.name == names.init && sym.owner != site.tsym) return false;
 346         switch ((short)(sym.flags() & AccessFlags)) {
 347         case PRIVATE:
 348             return
 349                 (env.enclClass.sym == sym.owner // fast special case
 350                  ||
 351                  env.enclClass.sym.outermostClass() ==
 352                  sym.owner.outermostClass())
 353                 &&
 354                 sym.isInheritedIn(site.tsym, types);
 355         case 0:
 356             return
 357                 (env.toplevel.packge == sym.owner.owner // fast special case
 358                  ||
 359                  env.toplevel.packge == sym.packge())
 360                 &&
 361                 isAccessible(env, site, checkInner)
 362                 &&
 363                 sym.isInheritedIn(site.tsym, types)
 364                 &&
 365                 notOverriddenIn(site, sym);
 366         case PROTECTED:
 367             return
 368                 (env.toplevel.packge == sym.owner.owner // fast special case
 369                  ||
 370                  env.toplevel.packge == sym.packge()
 371                  ||
 372                  isProtectedAccessible(sym, env.enclClass.sym, site)
 373                  ||
 374                  // OK to select instance method or field from 'super' or type name
 375                  // (but type names should be disallowed elsewhere!)
 376                  env.info.selectSuper && (sym.flags() & STATIC) == 0 && sym.kind != TYP)
 377                 &&
 378                 isAccessible(env, site, checkInner)
 379                 &&
 380                 notOverriddenIn(site, sym);
 381         default: // this case includes erroneous combinations as well
 382             return isAccessible(env, site, checkInner) && notOverriddenIn(site, sym);
 383         }
 384     }
 385     //where
 386     /* `sym' is accessible only if not overridden by
 387      * another symbol which is a member of `site'
 388      * (because, if it is overridden, `sym' is not strictly
 389      * speaking a member of `site'). A polymorphic signature method
 390      * cannot be overridden (e.g. MH.invokeExact(Object[])).
 391      */
 392     private boolean notOverriddenIn(Type site, Symbol sym) {
 393         if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
 394             return true;
 395         else {
 396             Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
 397             return (s2 == null || s2 == sym || sym.owner == s2.owner ||
 398                     s2.isPolymorphicSignatureGeneric() ||
 399                     !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
 400         }
 401     }
 402     //where
 403         /** Is given protected symbol accessible if it is selected from given site
 404          *  and the selection takes place in given class?
 405          *  @param sym     The symbol with protected access
 406          *  @param c       The class where the access takes place
 407          *  @site          The type of the qualifier
 408          */
 409         private
 410         boolean isProtectedAccessible(Symbol sym, ClassSymbol c, Type site) {
 411             while (c != null &&
 412                    !(c.isSubClass(sym.owner, types) &&
 413                      (c.flags() & INTERFACE) == 0 &&
 414                      // In JLS 2e 6.6.2.1, the subclass restriction applies
 415                      // only to instance fields and methods -- types are excluded
 416                      // regardless of whether they are declared 'static' or not.
 417                      ((sym.flags() & STATIC) != 0 || sym.kind == TYP || site.tsym.isSubClass(c, types))))
 418                 c = c.owner.enclClass();
 419             return c != null;
 420         }
 421 
 422     /** Try to instantiate the type of a method so that it fits
 423      *  given type arguments and argument types. If succesful, return
 424      *  the method's instantiated type, else return null.
 425      *  The instantiation will take into account an additional leading
 426      *  formal parameter if the method is an instance method seen as a member
 427      *  of un underdetermined site In this case, we treat site as an additional
 428      *  parameter and the parameters of the class containing the method as
 429      *  additional type variables that get instantiated.
 430      *
 431      *  @param env         The current environment
 432      *  @param site        The type of which the method is a member.
 433      *  @param m           The method symbol.
 434      *  @param argtypes    The invocation's given value arguments.
 435      *  @param typeargtypes    The invocation's given type arguments.
 436      *  @param allowBoxing Allow boxing conversions of arguments.
 437      *  @param useVarargs Box trailing arguments into an array for varargs.
 438      */
 439     Type rawInstantiate(Env<AttrContext> env,
 440                         Type site,
 441                         Symbol m,
 442                         List<Type> argtypes,
 443                         List<Type> typeargtypes,
 444                         boolean allowBoxing,
 445                         boolean useVarargs,
 446                         Warner warn)
 447         throws Infer.InferenceException {
 448         boolean polymorphicSignature = m.isPolymorphicSignatureGeneric() && allowMethodHandles;
 449         if (useVarargs && (m.flags() & VARARGS) == 0)
 450             throw inapplicableMethodException.setMessage();
 451         Type mt = types.memberType(site, m);
 452 
 453         // tvars is the list of formal type variables for which type arguments
 454         // need to inferred.
 455         List<Type> tvars = null;
 456         if (env.info.tvars != null) {
 457             tvars = types.newInstances(env.info.tvars);
 458             mt = types.subst(mt, env.info.tvars, tvars);
 459         }
 460         if (typeargtypes == null) typeargtypes = List.nil();
 461         if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
 462             // This is not a polymorphic method, but typeargs are supplied
 463             // which is fine, see JLS 15.12.2.1
 464         } else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
 465             ForAll pmt = (ForAll) mt;
 466             if (typeargtypes.length() != pmt.tvars.length())
 467                 throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
 468             // Check type arguments are within bounds
 469             List<Type> formals = pmt.tvars;
 470             List<Type> actuals = typeargtypes;
 471             while (formals.nonEmpty() && actuals.nonEmpty()) {
 472                 List<Type> bounds = types.subst(types.getBounds((TypeVar)formals.head),
 473                                                 pmt.tvars, typeargtypes);
 474                 for (; bounds.nonEmpty(); bounds = bounds.tail)
 475                     if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn))
 476                         throw inapplicableMethodException.setMessage("explicit.param.do.not.conform.to.bounds",actuals.head, bounds);
 477                 formals = formals.tail;
 478                 actuals = actuals.tail;
 479             }
 480             mt = types.subst(pmt.qtype, pmt.tvars, typeargtypes);
 481         } else if (mt.tag == FORALL) {
 482             ForAll pmt = (ForAll) mt;
 483             List<Type> tvars1 = types.newInstances(pmt.tvars);
 484             tvars = tvars.appendList(tvars1);
 485             mt = types.subst(pmt.qtype, pmt.tvars, tvars1);
 486         }
 487 
 488         // find out whether we need to go the slow route via infer
 489         boolean instNeeded = tvars.tail != null || /*inlined: tvars.nonEmpty()*/
 490                 polymorphicSignature;
 491         for (List<Type> l = argtypes;
 492              l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
 493              l = l.tail) {
 494             if (l.head.tag == FORALL) instNeeded = true;
 495         }
 496 
 497         if (instNeeded)
 498             return polymorphicSignature ?
 499                 infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes) :
 500                 infer.instantiateMethod(env,
 501                                     tvars,
 502                                     (MethodType)mt,
 503                                     m,
 504                                     argtypes,
 505                                     allowBoxing,
 506                                     useVarargs,
 507                                     warn);
 508 
 509         checkRawArgumentsAcceptable(env, argtypes, mt.getParameterTypes(),
 510                                 allowBoxing, useVarargs, warn);
 511         return mt;
 512     }
 513 
 514     /** Same but returns null instead throwing a NoInstanceException
 515      */
 516     Type instantiate(Env<AttrContext> env,
 517                      Type site,
 518                      Symbol m,
 519                      List<Type> argtypes,
 520                      List<Type> typeargtypes,
 521                      boolean allowBoxing,
 522                      boolean useVarargs,
 523                      Warner warn) {
 524         try {
 525             return rawInstantiate(env, site, m, argtypes, typeargtypes,
 526                                   allowBoxing, useVarargs, warn);
 527         } catch (InapplicableMethodException ex) {
 528             return null;
 529         }
 530     }
 531 
 532     /** Check if a parameter list accepts a list of args.
 533      */
 534     boolean argumentsAcceptable(Env<AttrContext> env,
 535                                 List<Type> argtypes,
 536                                 List<Type> formals,
 537                                 boolean allowBoxing,
 538                                 boolean useVarargs,
 539                                 Warner warn) {
 540         try {
 541             checkRawArgumentsAcceptable(env, argtypes, formals, allowBoxing, useVarargs, warn);
 542             return true;
 543         } catch (InapplicableMethodException ex) {
 544             return false;
 545         }
 546     }
 547     /**
 548      * A check handler is used by the main method applicability routine in order
 549      * to handle specific method applicability failures. It is assumed that a class
 550      * implementing this interface should throw exceptions that are a subtype of
 551      * InapplicableMethodException (see below). Such exception will terminate the
 552      * method applicability check and propagate important info outwards (for the
 553      * purpose of generating better diagnostics).
 554      */
 555     interface MethodCheckHandler {
 556         /* The number of actuals and formals differ */
 557         InapplicableMethodException arityMismatch();
 558         /* An actual argument type does not conform to the corresponding formal type */
 559         InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected);
 560         /* The element type of a varargs is not accessible in the current context */
 561         InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected);
 562     }
 563 
 564     /**
 565      * Basic method check handler used within Resolve - all methods end up
 566      * throwing InapplicableMethodException; a diagnostic fragment that describes
 567      * the cause as to why the method is not applicable is set on the exception
 568      * before it is thrown.
 569      */
 570     MethodCheckHandler resolveHandler = new MethodCheckHandler() {
 571             public InapplicableMethodException arityMismatch() {
 572                 return inapplicableMethodException.setMessage("arg.length.mismatch");
 573             }
 574             public InapplicableMethodException argumentMismatch(boolean varargs, Type found, Type expected) {
 575                 String key = varargs ?
 576                         "varargs.argument.mismatch" :
 577                         "no.conforming.assignment.exists";
 578                 return inapplicableMethodException.setMessage(key,
 579                         found, expected);
 580             }
 581             public InapplicableMethodException inaccessibleVarargs(Symbol location, Type expected) {
 582                 return inapplicableMethodException.setMessage("inaccessible.varargs.type",
 583                         expected, Kinds.kindName(location), location);
 584             }
 585     };
 586 
 587     void checkRawArgumentsAcceptable(Env<AttrContext> env,
 588                                 List<Type> argtypes,
 589                                 List<Type> formals,
 590                                 boolean allowBoxing,
 591                                 boolean useVarargs,
 592                                 Warner warn) {
 593         checkRawArgumentsAcceptable(env, List.<Type>nil(), argtypes, formals,
 594                 allowBoxing, useVarargs, warn, resolveHandler);
 595     }
 596 
 597     /**
 598      * Main method applicability routine. Given a list of actual types A,
 599      * a list of formal types F, determines whether the types in A are
 600      * compatible (by method invocation conversion) with the types in F.
 601      *
 602      * Since this routine is shared between overload resolution and method
 603      * type-inference, it is crucial that actual types are converted to the
 604      * corresponding 'undet' form (i.e. where inference variables are replaced
 605      * with undetvars) so that constraints can be propagated and collected.
 606      *
 607      * Moreover, if one or more types in A is a poly type, this routine calls
 608      * Infer.instantiateArg in order to complete the poly type (this might involve
 609      * deferred attribution).
 610      *
 611      * A method check handler (see above) is used in order to report errors.
 612      */
 613     List<Type> checkRawArgumentsAcceptable(Env<AttrContext> env,
 614                                 List<Type> undetvars,
 615                                 List<Type> argtypes,
 616                                 List<Type> formals,
 617                                 boolean allowBoxing,
 618                                 boolean useVarargs,
 619                                 Warner warn,
 620                                 MethodCheckHandler handler) {
 621         Type varargsFormal = useVarargs ? formals.last() : null;
 622         ListBuffer<Type> checkedArgs = ListBuffer.lb();
 623 
 624         if (varargsFormal == null &&
 625                 argtypes.size() != formals.size()) {
 626             throw handler.arityMismatch(); // not enough args
 627         }
 628 
 629         while (argtypes.nonEmpty() && formals.head != varargsFormal) {
 630             Type undetFormal = infer.asUndetType(formals.head, undetvars);
 631             Type capturedActual = types.capture(argtypes.head);
 632             boolean works = allowBoxing ?
 633                     types.isConvertible(capturedActual, undetFormal, warn) :
 634                     types.isSubtypeUnchecked(capturedActual, undetFormal, warn);
 635             if (!works) {
 636                 throw handler.argumentMismatch(false, argtypes.head, formals.head);
 637             }
 638             checkedArgs.append(capturedActual);
 639             argtypes = argtypes.tail;
 640             formals = formals.tail;
 641         }
 642 
 643         if (formals.head != varargsFormal) {
 644             throw handler.arityMismatch(); // not enough args
 645         }
 646 
 647         if (useVarargs) {
 648             //note: if applicability check is triggered by most specific test,
 649             //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
 650             Type elt = types.elemtype(varargsFormal);
 651             Type eltUndet = infer.asUndetType(elt, undetvars);
 652             while (argtypes.nonEmpty()) {
 653                 Type capturedActual = types.capture(argtypes.head);
 654                 if (!types.isConvertible(capturedActual, eltUndet, warn)) {
 655                     throw handler.argumentMismatch(true, argtypes.head, elt);
 656                 }
 657                 checkedArgs.append(capturedActual);
 658                 argtypes = argtypes.tail;
 659             }
 660             //check varargs element type accessibility
 661             if (undetvars.isEmpty() && !isAccessible(env, elt)) {
 662                 Symbol location = env.enclClass.sym;
 663                 throw handler.inaccessibleVarargs(location, elt);
 664             }
 665         }
 666         return checkedArgs.toList();
 667     }
 668     // where
 669         public static class InapplicableMethodException extends RuntimeException {
 670             private static final long serialVersionUID = 0;
 671 
 672             JCDiagnostic diagnostic;
 673             JCDiagnostic.Factory diags;
 674 
 675             InapplicableMethodException(JCDiagnostic.Factory diags) {
 676                 this.diagnostic = null;
 677                 this.diags = diags;
 678             }
 679             InapplicableMethodException setMessage() {
 680                 this.diagnostic = null;
 681                 return this;
 682             }
 683             InapplicableMethodException setMessage(String key) {
 684                 this.diagnostic = key != null ? diags.fragment(key) : null;
 685                 return this;
 686             }
 687             InapplicableMethodException setMessage(String key, Object... args) {
 688                 this.diagnostic = key != null ? diags.fragment(key, args) : null;
 689                 return this;
 690             }
 691             InapplicableMethodException setMessage(JCDiagnostic diag) {
 692                 this.diagnostic = diag;
 693                 return this;
 694             }
 695 
 696             public JCDiagnostic getDiagnostic() {
 697                 return diagnostic;
 698             }
 699         }
 700         private final InapplicableMethodException inapplicableMethodException;
 701 
 702 /* ***************************************************************************
 703  *  Symbol lookup
 704  *  the following naming conventions for arguments are used
 705  *
 706  *       env      is the environment where the symbol was mentioned
 707  *       site     is the type of which the symbol is a member
 708  *       name     is the symbol's name
 709  *                if no arguments are given
 710  *       argtypes are the value arguments, if we search for a method
 711  *
 712  *  If no symbol was found, a ResolveError detailing the problem is returned.
 713  ****************************************************************************/
 714 
 715     /** Find field. Synthetic fields are always skipped.
 716      *  @param env     The current environment.
 717      *  @param site    The original type from where the selection takes place.
 718      *  @param name    The name of the field.
 719      *  @param c       The class to search for the field. This is always
 720      *                 a superclass or implemented interface of site's class.
 721      */
 722     Symbol findField(Env<AttrContext> env,
 723                      Type site,
 724                      Name name,
 725                      TypeSymbol c) {
 726         while (c.type.tag == TYPEVAR)
 727             c = c.type.getUpperBound().tsym;
 728         Symbol bestSoFar = varNotFound;
 729         Symbol sym;
 730         Scope.Entry e = c.members().lookup(name);
 731         while (e.scope != null) {
 732             if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
 733                 return isAccessible(env, site, e.sym)
 734                     ? e.sym : new AccessError(env, site, e.sym);
 735             }
 736             e = e.next();
 737         }
 738         Type st = types.supertype(c.type);
 739         if (st != null && (st.tag == CLASS || st.tag == TYPEVAR)) {
 740             sym = findField(env, site, name, st.tsym);
 741             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
 742         }
 743         for (List<Type> l = types.interfaces(c.type);
 744              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
 745              l = l.tail) {
 746             sym = findField(env, site, name, l.head.tsym);
 747             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
 748                 sym.owner != bestSoFar.owner)
 749                 bestSoFar = new AmbiguityError(bestSoFar, sym);
 750             else if (sym.kind < bestSoFar.kind)
 751                 bestSoFar = sym;
 752         }
 753         return bestSoFar;
 754     }
 755 
 756     /** Resolve a field identifier, throw a fatal error if not found.
 757      *  @param pos       The position to use for error reporting.
 758      *  @param env       The environment current at the method invocation.
 759      *  @param site      The type of the qualifying expression, in which
 760      *                   identifier is searched.
 761      *  @param name      The identifier's name.
 762      */
 763     public VarSymbol resolveInternalField(DiagnosticPosition pos, Env<AttrContext> env,
 764                                           Type site, Name name) {
 765         Symbol sym = findField(env, site, name, site.tsym);
 766         if (sym.kind == VAR) return (VarSymbol)sym;
 767         else throw new FatalError(
 768                  diags.fragment("fatal.err.cant.locate.field",
 769                                 name));
 770     }
 771 
 772     /** Find unqualified variable or field with given name.
 773      *  Synthetic fields always skipped.
 774      *  @param env     The current environment.
 775      *  @param name    The name of the variable or field.
 776      */
 777     Symbol findVar(Env<AttrContext> env, Name name) {
 778         Symbol bestSoFar = varNotFound;
 779         Symbol sym;
 780         Env<AttrContext> env1 = env;
 781         boolean staticOnly = false;
 782         while (env1.outer != null) {
 783             if (isStatic(env1)) staticOnly = true;
 784             Scope.Entry e = env1.info.scope.lookup(name);
 785             while (e.scope != null &&
 786                    (e.sym.kind != VAR ||
 787                     (e.sym.flags_field & SYNTHETIC) != 0))
 788                 e = e.next();
 789             sym = (e.scope != null)
 790                 ? e.sym
 791                 : findField(
 792                     env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
 793             if (sym.exists()) {
 794                 if (staticOnly &&
 795                     sym.kind == VAR &&
 796                     sym.owner.kind == TYP &&
 797                     (sym.flags() & STATIC) == 0)
 798                     return new StaticError(sym);
 799                 else
 800                     return sym;
 801             } else if (sym.kind < bestSoFar.kind) {
 802                 bestSoFar = sym;
 803             }
 804 
 805             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
 806             env1 = env1.outer;
 807         }
 808 
 809         sym = findField(env, syms.predefClass.type, name, syms.predefClass);
 810         if (sym.exists())
 811             return sym;
 812         if (bestSoFar.exists())
 813             return bestSoFar;
 814 
 815         Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
 816         for (; e.scope != null; e = e.next()) {
 817             sym = e.sym;
 818             Type origin = e.getOrigin().owner.type;
 819             if (sym.kind == VAR) {
 820                 if (e.sym.owner.type != origin)
 821                     sym = sym.clone(e.getOrigin().owner);
 822                 return isAccessible(env, origin, sym)
 823                     ? sym : new AccessError(env, origin, sym);
 824             }
 825         }
 826 
 827         Symbol origin = null;
 828         e = env.toplevel.starImportScope.lookup(name);
 829         for (; e.scope != null; e = e.next()) {
 830             sym = e.sym;
 831             if (sym.kind != VAR)
 832                 continue;
 833             // invariant: sym.kind == VAR
 834             if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
 835                 return new AmbiguityError(bestSoFar, sym);
 836             else if (bestSoFar.kind >= VAR) {
 837                 origin = e.getOrigin().owner;
 838                 bestSoFar = isAccessible(env, origin.type, sym)
 839                     ? sym : new AccessError(env, origin.type, sym);
 840             }
 841         }
 842         if (bestSoFar.kind == VAR && bestSoFar.owner.type != origin.type)
 843             return bestSoFar.clone(origin);
 844         else
 845             return bestSoFar;
 846     }
 847 
 848     Warner noteWarner = new Warner();
 849 
 850     /** Select the best method for a call site among two choices.
 851      *  @param env              The current environment.
 852      *  @param site             The original type from where the
 853      *                          selection takes place.
 854      *  @param argtypes         The invocation's value arguments,
 855      *  @param typeargtypes     The invocation's type arguments,
 856      *  @param sym              Proposed new best match.
 857      *  @param bestSoFar        Previously found best match.
 858      *  @param allowBoxing Allow boxing conversions of arguments.
 859      *  @param useVarargs Box trailing arguments into an array for varargs.
 860      */
 861     @SuppressWarnings("fallthrough")
 862     Symbol selectBest(Env<AttrContext> env,
 863                       Type site,
 864                       List<Type> argtypes,
 865                       List<Type> typeargtypes,
 866                       Symbol sym,
 867                       Symbol bestSoFar,
 868                       boolean allowBoxing,
 869                       boolean useVarargs,
 870                       boolean operator) {
 871         if (sym.kind == ERR) return bestSoFar;
 872         if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
 873         Assert.check(sym.kind < AMBIGUOUS);
 874         try {
 875             Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes,
 876                                allowBoxing, useVarargs, Warner.noWarnings);
 877             if (!operator)
 878                 currentResolutionContext.addApplicableCandidate(sym, mt);
 879         } catch (InapplicableMethodException ex) {
 880             if (!operator)
 881                 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
 882             switch (bestSoFar.kind) {
 883             case ABSENT_MTH:
 884                 return wrongMethod;
 885             case WRONG_MTH:
 886                 if (operator) return bestSoFar;
 887             case WRONG_MTHS:
 888                 return wrongMethods;
 889             default:
 890                 return bestSoFar;
 891             }
 892         }
 893         if (!isAccessible(env, site, sym)) {
 894             return (bestSoFar.kind == ABSENT_MTH)
 895                 ? new AccessError(env, site, sym)
 896                 : bestSoFar;
 897         }
 898         return (bestSoFar.kind > AMBIGUOUS)
 899             ? sym
 900             : mostSpecific(sym, bestSoFar, env, site,
 901                            allowBoxing && operator, useVarargs);
 902     }
 903 
 904     /* Return the most specific of the two methods for a call,
 905      *  given that both are accessible and applicable.
 906      *  @param m1               A new candidate for most specific.
 907      *  @param m2               The previous most specific candidate.
 908      *  @param env              The current environment.
 909      *  @param site             The original type from where the selection
 910      *                          takes place.
 911      *  @param allowBoxing Allow boxing conversions of arguments.
 912      *  @param useVarargs Box trailing arguments into an array for varargs.
 913      */
 914     Symbol mostSpecific(Symbol m1,
 915                         Symbol m2,
 916                         Env<AttrContext> env,
 917                         final Type site,
 918                         boolean allowBoxing,
 919                         boolean useVarargs) {
 920         switch (m2.kind) {
 921         case MTH:
 922             if (m1 == m2) return m1;
 923             boolean m1SignatureMoreSpecific = signatureMoreSpecific(env, site, m1, m2, allowBoxing, useVarargs);
 924             boolean m2SignatureMoreSpecific = signatureMoreSpecific(env, site, m2, m1, allowBoxing, useVarargs);
 925             if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) {
 926                 Type mt1 = types.memberType(site, m1);
 927                 Type mt2 = types.memberType(site, m2);
 928                 if (!types.overrideEquivalent(mt1, mt2))
 929                     return ambiguityError(m1, m2);
 930 
 931                 // same signature; select (a) the non-bridge method, or
 932                 // (b) the one that overrides the other, or (c) the concrete
 933                 // one, or (d) merge both abstract signatures
 934                 if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE))
 935                     return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
 936 
 937                 // if one overrides or hides the other, use it
 938                 TypeSymbol m1Owner = (TypeSymbol)m1.owner;
 939                 TypeSymbol m2Owner = (TypeSymbol)m2.owner;
 940                 if (types.asSuper(m1Owner.type, m2Owner) != null &&
 941                     ((m1.owner.flags_field & INTERFACE) == 0 ||
 942                      (m2.owner.flags_field & INTERFACE) != 0) &&
 943                     m1.overrides(m2, m1Owner, types, false))
 944                     return m1;
 945                 if (types.asSuper(m2Owner.type, m1Owner) != null &&
 946                     ((m2.owner.flags_field & INTERFACE) == 0 ||
 947                      (m1.owner.flags_field & INTERFACE) != 0) &&
 948                     m2.overrides(m1, m2Owner, types, false))
 949                     return m2;
 950                 boolean m1Abstract = (m1.flags() & ABSTRACT) != 0;
 951                 boolean m2Abstract = (m2.flags() & ABSTRACT) != 0;
 952                 if (m1Abstract && !m2Abstract) return m2;
 953                 if (m2Abstract && !m1Abstract) return m1;
 954                 // both abstract or both concrete
 955                 if (!m1Abstract && !m2Abstract)
 956                     return ambiguityError(m1, m2);
 957                 // check that both signatures have the same erasure
 958                 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(),
 959                                        m2.erasure(types).getParameterTypes()))
 960                     return ambiguityError(m1, m2);
 961                 // both abstract, neither overridden; merge throws clause and result type
 962                 Type mst = mostSpecificReturnType(mt1, mt2);
 963                 if (mst == null) {
 964                     // Theoretically, this can't happen, but it is possible
 965                     // due to error recovery or mixing incompatible class files
 966                     return ambiguityError(m1, m2);
 967                 }
 968                 Symbol mostSpecific = mst == mt1 ? m1 : m2;
 969                 List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
 970                 Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
 971                 MethodSymbol result = new MethodSymbol(
 972                         mostSpecific.flags(),
 973                         mostSpecific.name,
 974                         newSig,
 975                         mostSpecific.owner) {
 976                     @Override
 977                     public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
 978                         if (origin == site.tsym)
 979                             return this;
 980                         else
 981                             return super.implementation(origin, types, checkResult);
 982                     }
 983                 };
 984                 return result;
 985             }
 986             if (m1SignatureMoreSpecific) return m1;
 987             if (m2SignatureMoreSpecific) return m2;
 988             return ambiguityError(m1, m2);
 989         case AMBIGUOUS:
 990             AmbiguityError e = (AmbiguityError)m2;
 991             Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs);
 992             Symbol err2 = mostSpecific(m1, e.sym2, env, site, allowBoxing, useVarargs);
 993             if (err1 == err2) return err1;
 994             if (err1 == e.sym && err2 == e.sym2) return m2;
 995             if (err1 instanceof AmbiguityError &&
 996                 err2 instanceof AmbiguityError &&
 997                 ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym)
 998                 return ambiguityError(m1, m2);
 999             else
1000                 return ambiguityError(err1, err2);
1001         default:
1002             throw new AssertionError();
1003         }
1004     }
1005     //where
1006     private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
1007         noteWarner.clear();
1008         Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs));
1009         Type mtype2 = instantiate(env, site, adjustVarargs(m2, m1, useVarargs),
1010                 types.lowerBoundArgtypes(mtype1), null,
1011                 allowBoxing, false, noteWarner);
1012         return mtype2 != null &&
1013                 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
1014     }
1015     //where
1016     private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) {
1017         List<Type> fromArgs = from.type.getParameterTypes();
1018         List<Type> toArgs = to.type.getParameterTypes();
1019         if (useVarargs &&
1020                 (from.flags() & VARARGS) != 0 &&
1021                 (to.flags() & VARARGS) != 0) {
1022             Type varargsTypeFrom = fromArgs.last();
1023             Type varargsTypeTo = toArgs.last();
1024             ListBuffer<Type> args = ListBuffer.lb();
1025             if (toArgs.length() < fromArgs.length()) {
1026                 //if we are checking a varargs method 'from' against another varargs
1027                 //method 'to' (where arity of 'to' < arity of 'from') then expand signature
1028                 //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to'
1029                 //until 'to' signature has the same arity as 'from')
1030                 while (fromArgs.head != varargsTypeFrom) {
1031                     args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head);
1032                     fromArgs = fromArgs.tail;
1033                     toArgs = toArgs.head == varargsTypeTo ?
1034                         toArgs :
1035                         toArgs.tail;
1036                 }
1037             } else {
1038                 //formal argument list is same as original list where last
1039                 //argument (array type) is removed
1040                 args.appendList(toArgs.reverse().tail.reverse());
1041             }
1042             //append varargs element type as last synthetic formal
1043             args.append(types.elemtype(varargsTypeTo));
1044             Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
1045             return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner);
1046         } else {
1047             return to;
1048         }
1049     }
1050     //where
1051     Type mostSpecificReturnType(Type mt1, Type mt2) {
1052         Type rt1 = mt1.getReturnType();
1053         Type rt2 = mt2.getReturnType();
1054 
1055         if (mt1.tag == FORALL && mt2.tag == FORALL) {
1056             //if both are generic methods, adjust return type ahead of subtyping check
1057             rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
1058         }
1059         //first use subtyping, then return type substitutability
1060         if (types.isSubtype(rt1, rt2)) {
1061             return mt1;
1062         } else if (types.isSubtype(rt2, rt1)) {
1063             return mt2;
1064         } else if (types.returnTypeSubstitutable(mt1, mt2)) {
1065             return mt1;
1066         } else if (types.returnTypeSubstitutable(mt2, mt1)) {
1067             return mt2;
1068         } else {
1069             return null;
1070         }
1071     }
1072     //where
1073     Symbol ambiguityError(Symbol m1, Symbol m2) {
1074         if (((m1.flags() | m2.flags()) & CLASH) != 0) {
1075             return (m1.flags() & CLASH) == 0 ? m1 : m2;
1076         } else {
1077             return new AmbiguityError(m1, m2);
1078         }
1079     }
1080 
1081     /** Find best qualified method matching given name, type and value
1082      *  arguments.
1083      *  @param env       The current environment.
1084      *  @param site      The original type from where the selection
1085      *                   takes place.
1086      *  @param name      The method's name.
1087      *  @param argtypes  The method's value arguments.
1088      *  @param typeargtypes The method's type arguments
1089      *  @param allowBoxing Allow boxing conversions of arguments.
1090      *  @param useVarargs Box trailing arguments into an array for varargs.
1091      */
1092     Symbol findMethod(Env<AttrContext> env,
1093                       Type site,
1094                       Name name,
1095                       List<Type> argtypes,
1096                       List<Type> typeargtypes,
1097                       boolean allowBoxing,
1098                       boolean useVarargs,
1099                       boolean operator) {
1100         Symbol bestSoFar = methodNotFound;
1101         bestSoFar = findMethod(env,
1102                           site,
1103                           name,
1104                           argtypes,
1105                           typeargtypes,
1106                           site.tsym.type,
1107                           true,
1108                           bestSoFar,
1109                           allowBoxing,
1110                           useVarargs,
1111                           operator,
1112                           new HashSet<TypeSymbol>());
1113         reportVerboseResolutionDiagnostic(env.tree.pos(), name, site, argtypes, typeargtypes, bestSoFar);
1114         return bestSoFar;
1115     }
1116     // where
1117     private Symbol findMethod(Env<AttrContext> env,
1118                               Type site,
1119                               Name name,
1120                               List<Type> argtypes,
1121                               List<Type> typeargtypes,
1122                               Type intype,
1123                               boolean abstractok,
1124                               Symbol bestSoFar,
1125                               boolean allowBoxing,
1126                               boolean useVarargs,
1127                               boolean operator,
1128                               Set<TypeSymbol> seen) {
1129         for (Type ct = intype; ct.tag == CLASS || ct.tag == TYPEVAR; ct = types.supertype(ct)) {
1130             while (ct.tag == TYPEVAR)
1131                 ct = ct.getUpperBound();
1132             ClassSymbol c = (ClassSymbol)ct.tsym;
1133             if (!seen.add(c)) return bestSoFar;
1134             if ((c.flags() & (ABSTRACT | INTERFACE | ENUM)) == 0)
1135                 abstractok = false;
1136             for (Scope.Entry e = c.members().lookup(name);
1137                  e.scope != null;
1138                  e = e.next()) {
1139                 //- System.out.println(" e " + e.sym);
1140                 if (e.sym.kind == MTH &&
1141                     (e.sym.flags_field & SYNTHETIC) == 0) {
1142                     bestSoFar = selectBest(env, site, argtypes, typeargtypes,
1143                                            e.sym, bestSoFar,
1144                                            allowBoxing,
1145                                            useVarargs,
1146                                            operator);
1147                 }
1148             }
1149             if (name == names.init)
1150                 break;
1151             //- System.out.println(" - " + bestSoFar);
1152             if (abstractok) {
1153                 Symbol concrete = methodNotFound;
1154                 if ((bestSoFar.flags() & ABSTRACT) == 0)
1155                     concrete = bestSoFar;
1156                 for (List<Type> l = types.interfaces(c.type);
1157                      l.nonEmpty();
1158                      l = l.tail) {
1159                     bestSoFar = findMethod(env, site, name, argtypes,
1160                                            typeargtypes,
1161                                            l.head, abstractok, bestSoFar,
1162                                            allowBoxing, useVarargs, operator, seen);
1163                 }
1164                 if (concrete != bestSoFar &&
1165                     concrete.kind < ERR  && bestSoFar.kind < ERR &&
1166                     types.isSubSignature(concrete.type, bestSoFar.type))
1167                     bestSoFar = concrete;
1168             }
1169         }
1170         return bestSoFar;
1171     }
1172 
1173     /** Find unqualified method matching given name, type and value arguments.
1174      *  @param env       The current environment.
1175      *  @param name      The method's name.
1176      *  @param argtypes  The method's value arguments.
1177      *  @param typeargtypes  The method's type arguments.
1178      *  @param allowBoxing Allow boxing conversions of arguments.
1179      *  @param useVarargs Box trailing arguments into an array for varargs.
1180      */
1181     Symbol findFun(Env<AttrContext> env, Name name,
1182                    List<Type> argtypes, List<Type> typeargtypes,
1183                    boolean allowBoxing, boolean useVarargs) {
1184         Symbol bestSoFar = methodNotFound;
1185         Symbol sym;
1186         Env<AttrContext> env1 = env;
1187         boolean staticOnly = false;
1188         while (env1.outer != null) {
1189             if (isStatic(env1)) staticOnly = true;
1190             sym = findMethod(
1191                 env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
1192                 allowBoxing, useVarargs, false);
1193             if (sym.exists()) {
1194                 if (staticOnly &&
1195                     sym.kind == MTH &&
1196                     sym.owner.kind == TYP &&
1197                     (sym.flags() & STATIC) == 0) return new StaticError(sym);
1198                 else return sym;
1199             } else if (sym.kind < bestSoFar.kind) {
1200                 bestSoFar = sym;
1201             }
1202             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
1203             env1 = env1.outer;
1204         }
1205 
1206         sym = findMethod(env, syms.predefClass.type, name, argtypes,
1207                          typeargtypes, allowBoxing, useVarargs, false);
1208         if (sym.exists())
1209             return sym;
1210 
1211         Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
1212         for (; e.scope != null; e = e.next()) {
1213             sym = e.sym;
1214             Type origin = e.getOrigin().owner.type;
1215             if (sym.kind == MTH) {
1216                 if (e.sym.owner.type != origin)
1217                     sym = sym.clone(e.getOrigin().owner);
1218                 if (!isAccessible(env, origin, sym))
1219                     sym = new AccessError(env, origin, sym);
1220                 bestSoFar = selectBest(env, origin,
1221                                        argtypes, typeargtypes,
1222                                        sym, bestSoFar,
1223                                        allowBoxing, useVarargs, false);
1224             }
1225         }
1226         if (bestSoFar.exists())
1227             return bestSoFar;
1228 
1229         e = env.toplevel.starImportScope.lookup(name);
1230         for (; e.scope != null; e = e.next()) {
1231             sym = e.sym;
1232             Type origin = e.getOrigin().owner.type;
1233             if (sym.kind == MTH) {
1234                 if (e.sym.owner.type != origin)
1235                     sym = sym.clone(e.getOrigin().owner);
1236                 if (!isAccessible(env, origin, sym))
1237                     sym = new AccessError(env, origin, sym);
1238                 bestSoFar = selectBest(env, origin,
1239                                        argtypes, typeargtypes,
1240                                        sym, bestSoFar,
1241                                        allowBoxing, useVarargs, false);
1242             }
1243         }
1244         return bestSoFar;
1245     }
1246 
1247     /** Load toplevel or member class with given fully qualified name and
1248      *  verify that it is accessible.
1249      *  @param env       The current environment.
1250      *  @param name      The fully qualified name of the class to be loaded.
1251      */
1252     Symbol loadClass(Env<AttrContext> env, Name name) {
1253         try {
1254             ClassSymbol c = reader.loadClass(name);
1255             return isAccessible(env, c) ? c : new AccessError(c);
1256         } catch (ClassReader.BadClassFile err) {
1257             throw err;
1258         } catch (CompletionFailure ex) {
1259             return typeNotFound;
1260         }
1261     }
1262 
1263     /** Find qualified member type.
1264      *  @param env       The current environment.
1265      *  @param site      The original type from where the selection takes
1266      *                   place.
1267      *  @param name      The type's name.
1268      *  @param c         The class to search for the member type. This is
1269      *                   always a superclass or implemented interface of
1270      *                   site's class.
1271      */
1272     Symbol findMemberType(Env<AttrContext> env,
1273                           Type site,
1274                           Name name,
1275                           TypeSymbol c) {
1276         Symbol bestSoFar = typeNotFound;
1277         Symbol sym;
1278         Scope.Entry e = c.members().lookup(name);
1279         while (e.scope != null) {
1280             if (e.sym.kind == TYP) {
1281                 return isAccessible(env, site, e.sym)
1282                     ? e.sym
1283                     : new AccessError(env, site, e.sym);
1284             }
1285             e = e.next();
1286         }
1287         Type st = types.supertype(c.type);
1288         if (st != null && st.tag == CLASS) {
1289             sym = findMemberType(env, site, name, st.tsym);
1290             if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1291         }
1292         for (List<Type> l = types.interfaces(c.type);
1293              bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
1294              l = l.tail) {
1295             sym = findMemberType(env, site, name, l.head.tsym);
1296             if (bestSoFar.kind < AMBIGUOUS && sym.kind < AMBIGUOUS &&
1297                 sym.owner != bestSoFar.owner)
1298                 bestSoFar = new AmbiguityError(bestSoFar, sym);
1299             else if (sym.kind < bestSoFar.kind)
1300                 bestSoFar = sym;
1301         }
1302         return bestSoFar;
1303     }
1304 
1305     /** Find a global type in given scope and load corresponding class.
1306      *  @param env       The current environment.
1307      *  @param scope     The scope in which to look for the type.
1308      *  @param name      The type's name.
1309      */
1310     Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
1311         Symbol bestSoFar = typeNotFound;
1312         for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
1313             Symbol sym = loadClass(env, e.sym.flatName());
1314             if (bestSoFar.kind == TYP && sym.kind == TYP &&
1315                 bestSoFar != sym)
1316                 return new AmbiguityError(bestSoFar, sym);
1317             else if (sym.kind < bestSoFar.kind)
1318                 bestSoFar = sym;
1319         }
1320         return bestSoFar;
1321     }
1322 
1323     /** Find an unqualified type symbol.
1324      *  @param env       The current environment.
1325      *  @param name      The type's name.
1326      */
1327     Symbol findType(Env<AttrContext> env, Name name) {
1328         Symbol bestSoFar = typeNotFound;
1329         Symbol sym;
1330         boolean staticOnly = false;
1331         for (Env<AttrContext> env1 = env; env1.outer != null; env1 = env1.outer) {
1332             if (isStatic(env1)) staticOnly = true;
1333             for (Scope.Entry e = env1.info.scope.lookup(name);
1334                  e.scope != null;
1335                  e = e.next()) {
1336                 if (e.sym.kind == TYP) {
1337                     if (staticOnly &&
1338                         e.sym.type.tag == TYPEVAR &&
1339                         e.sym.owner.kind == TYP) return new StaticError(e.sym);
1340                     return e.sym;
1341                 }
1342             }
1343 
1344             sym = findMemberType(env1, env1.enclClass.sym.type, name,
1345                                  env1.enclClass.sym);
1346             if (staticOnly && sym.kind == TYP &&
1347                 sym.type.tag == CLASS &&
1348                 sym.type.getEnclosingType().tag == CLASS &&
1349                 env1.enclClass.sym.type.isParameterized() &&
1350                 sym.type.getEnclosingType().isParameterized())
1351                 return new StaticError(sym);
1352             else if (sym.exists()) return sym;
1353             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1354 
1355             JCClassDecl encl = env1.baseClause ? (JCClassDecl)env1.tree : env1.enclClass;
1356             if ((encl.sym.flags() & STATIC) != 0)
1357                 staticOnly = true;
1358         }
1359 
1360         if (!env.tree.hasTag(IMPORT)) {
1361             sym = findGlobalType(env, env.toplevel.namedImportScope, name);
1362             if (sym.exists()) return sym;
1363             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1364 
1365             sym = findGlobalType(env, env.toplevel.packge.members(), name);
1366             if (sym.exists()) return sym;
1367             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1368 
1369             sym = findGlobalType(env, env.toplevel.starImportScope, name);
1370             if (sym.exists()) return sym;
1371             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1372         }
1373 
1374         return bestSoFar;
1375     }
1376 
1377     /** Find an unqualified identifier which matches a specified kind set.
1378      *  @param env       The current environment.
1379      *  @param name      The indentifier's name.
1380      *  @param kind      Indicates the possible symbol kinds
1381      *                   (a subset of VAL, TYP, PCK).
1382      */
1383     Symbol findIdent(Env<AttrContext> env, Name name, int kind) {
1384         Symbol bestSoFar = typeNotFound;
1385         Symbol sym;
1386 
1387         if ((kind & VAR) != 0) {
1388             sym = findVar(env, name);
1389             if (sym.exists()) return sym;
1390             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1391         }
1392 
1393         if ((kind & TYP) != 0) {
1394             sym = findType(env, name);
1395             if (sym.exists()) return sym;
1396             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1397         }
1398 
1399         if ((kind & PCK) != 0) return reader.enterPackage(name);
1400         else return bestSoFar;
1401     }
1402 
1403     /** Find an identifier in a package which matches a specified kind set.
1404      *  @param env       The current environment.
1405      *  @param name      The identifier's name.
1406      *  @param kind      Indicates the possible symbol kinds
1407      *                   (a nonempty subset of TYP, PCK).
1408      */
1409     Symbol findIdentInPackage(Env<AttrContext> env, TypeSymbol pck,
1410                               Name name, int kind) {
1411         Name fullname = TypeSymbol.formFullName(name, pck);
1412         Symbol bestSoFar = typeNotFound;
1413         PackageSymbol pack = null;
1414         if ((kind & PCK) != 0) {
1415             pack = reader.enterPackage(fullname);
1416             if (pack.exists()) return pack;
1417         }
1418         if ((kind & TYP) != 0) {
1419             Symbol sym = loadClass(env, fullname);
1420             if (sym.exists()) {
1421                 // don't allow programs to use flatnames
1422                 if (name == sym.name) return sym;
1423             }
1424             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1425         }
1426         return (pack != null) ? pack : bestSoFar;
1427     }
1428 
1429     /** Find an identifier among the members of a given type `site'.
1430      *  @param env       The current environment.
1431      *  @param site      The type containing the symbol to be found.
1432      *  @param name      The identifier's name.
1433      *  @param kind      Indicates the possible symbol kinds
1434      *                   (a subset of VAL, TYP).
1435      */
1436     Symbol findIdentInType(Env<AttrContext> env, Type site,
1437                            Name name, int kind) {
1438         Symbol bestSoFar = typeNotFound;
1439         Symbol sym;
1440         if ((kind & VAR) != 0) {
1441             sym = findField(env, site, name, site.tsym);
1442             if (sym.exists()) return sym;
1443             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1444         }
1445 
1446         if ((kind & TYP) != 0) {
1447             sym = findMemberType(env, site, name, site.tsym);
1448             if (sym.exists()) return sym;
1449             else if (sym.kind < bestSoFar.kind) bestSoFar = sym;
1450         }
1451         return bestSoFar;
1452     }
1453 
1454 /* ***************************************************************************
1455  *  Access checking
1456  *  The following methods convert ResolveErrors to ErrorSymbols, issuing
1457  *  an error message in the process
1458  ****************************************************************************/
1459 
1460     /** If `sym' is a bad symbol: report error and return errSymbol
1461      *  else pass through unchanged,
1462      *  additional arguments duplicate what has been used in trying to find the
1463      *  symbol (--> flyweight pattern). This improves performance since we
1464      *  expect misses to happen frequently.
1465      *
1466      *  @param sym       The symbol that was found, or a ResolveError.
1467      *  @param pos       The position to use for error reporting.
1468      *  @param site      The original type from where the selection took place.
1469      *  @param name      The symbol's name.
1470      *  @param argtypes  The invocation's value arguments,
1471      *                   if we looked for a method.
1472      *  @param typeargtypes  The invocation's type arguments,
1473      *                   if we looked for a method.
1474      */
1475     Symbol access(Symbol sym,
1476                   DiagnosticPosition pos,
1477                   Symbol location,
1478                   Type site,
1479                   Name name,
1480                   boolean qualified,
1481                   List<Type> argtypes,
1482                   List<Type> typeargtypes) {
1483         if (sym.kind >= AMBIGUOUS) {
1484             ResolveError errSym = (ResolveError)sym;
1485             if (!site.isErroneous() &&
1486                 !Type.isErroneous(argtypes) &&
1487                 (typeargtypes==null || !Type.isErroneous(typeargtypes)))
1488                 logResolveError(errSym, pos, location, site, name, argtypes, typeargtypes);
1489             sym = errSym.access(name, qualified ? site.tsym : syms.noSymbol);
1490         }
1491         return sym;
1492     }
1493 
1494     /** Same as original access(), but without location.
1495      */
1496     Symbol access(Symbol sym,
1497                   DiagnosticPosition pos,
1498                   Type site,
1499                   Name name,
1500                   boolean qualified,
1501                   List<Type> argtypes,
1502                   List<Type> typeargtypes) {
1503         return access(sym, pos, site.tsym, site, name, qualified, argtypes, typeargtypes);
1504     }
1505 
1506     /** Same as original access(), but without type arguments and arguments.
1507      */
1508     Symbol access(Symbol sym,
1509                   DiagnosticPosition pos,
1510                   Symbol location,
1511                   Type site,
1512                   Name name,
1513                   boolean qualified) {
1514         if (sym.kind >= AMBIGUOUS)
1515             return access(sym, pos, location, site, name, qualified, List.<Type>nil(), null);
1516         else
1517             return sym;
1518     }
1519 
1520     /** Same as original access(), but without location, type arguments and arguments.
1521      */
1522     Symbol access(Symbol sym,
1523                   DiagnosticPosition pos,
1524                   Type site,
1525                   Name name,
1526                   boolean qualified) {
1527         return access(sym, pos, site.tsym, site, name, qualified);
1528     }
1529 
1530     /** Check that sym is not an abstract method.
1531      */
1532     void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
1533         if ((sym.flags() & ABSTRACT) != 0)
1534             log.error(pos, "abstract.cant.be.accessed.directly",
1535                       kindName(sym), sym, sym.location());
1536     }
1537 
1538 /* ***************************************************************************
1539  *  Debugging
1540  ****************************************************************************/
1541 
1542     /** print all scopes starting with scope s and proceeding outwards.
1543      *  used for debugging.
1544      */
1545     public void printscopes(Scope s) {
1546         while (s != null) {
1547             if (s.owner != null)
1548                 System.err.print(s.owner + ": ");
1549             for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
1550                 if ((e.sym.flags() & ABSTRACT) != 0)
1551                     System.err.print("abstract ");
1552                 System.err.print(e.sym + " ");
1553             }
1554             System.err.println();
1555             s = s.next;
1556         }
1557     }
1558 
1559     void printscopes(Env<AttrContext> env) {
1560         while (env.outer != null) {
1561             System.err.println("------------------------------");
1562             printscopes(env.info.scope);
1563             env = env.outer;
1564         }
1565     }
1566 
1567     public void printscopes(Type t) {
1568         while (t.tag == CLASS) {
1569             printscopes(t.tsym.members());
1570             t = types.supertype(t);
1571         }
1572     }
1573 
1574 /* ***************************************************************************
1575  *  Name resolution
1576  *  Naming conventions are as for symbol lookup
1577  *  Unlike the find... methods these methods will report access errors
1578  ****************************************************************************/
1579 
1580     /** Resolve an unqualified (non-method) identifier.
1581      *  @param pos       The position to use for error reporting.
1582      *  @param env       The environment current at the identifier use.
1583      *  @param name      The identifier's name.
1584      *  @param kind      The set of admissible symbol kinds for the identifier.
1585      */
1586     Symbol resolveIdent(DiagnosticPosition pos, Env<AttrContext> env,
1587                         Name name, int kind) {
1588         return access(
1589             findIdent(env, name, kind),
1590             pos, env.enclClass.sym.type, name, false);
1591     }
1592 
1593     /** Resolve an unqualified method identifier.
1594      *  @param pos       The position to use for error reporting.
1595      *  @param env       The environment current at the method invocation.
1596      *  @param name      The identifier's name.
1597      *  @param argtypes  The types of the invocation's value arguments.
1598      *  @param typeargtypes  The types of the invocation's type arguments.
1599      */
1600     Symbol resolveMethod(DiagnosticPosition pos,
1601                          Env<AttrContext> env,
1602                          Name name,
1603                          List<Type> argtypes,
1604                          List<Type> typeargtypes) {
1605         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1606         try {
1607             currentResolutionContext = new MethodResolutionContext();
1608             Symbol sym = methodNotFound;
1609             List<MethodResolutionPhase> steps = methodResolutionSteps;
1610             while (steps.nonEmpty() &&
1611                    steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1612                    sym.kind >= ERRONEOUS) {
1613                 currentResolutionContext.step = steps.head;
1614                 sym = findFun(env, name, argtypes, typeargtypes,
1615                         steps.head.isBoxingRequired,
1616                         env.info.varArgs = steps.head.isVarargsRequired);
1617                 currentResolutionContext.resolutionCache.put(steps.head, sym);
1618                 steps = steps.tail;
1619             }
1620             if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
1621                 MethodResolutionPhase errPhase =
1622                         currentResolutionContext.firstErroneousResolutionPhase();
1623                 sym = access(currentResolutionContext.resolutionCache.get(errPhase),
1624                         pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
1625                 env.info.varArgs = errPhase.isVarargsRequired;
1626             }
1627             return sym;
1628         }
1629         finally {
1630             currentResolutionContext = prevResolutionContext;
1631         }
1632     }
1633 
1634     /** Resolve a qualified method identifier
1635      *  @param pos       The position to use for error reporting.
1636      *  @param env       The environment current at the method invocation.
1637      *  @param site      The type of the qualifying expression, in which
1638      *                   identifier is searched.
1639      *  @param name      The identifier's name.
1640      *  @param argtypes  The types of the invocation's value arguments.
1641      *  @param typeargtypes  The types of the invocation's type arguments.
1642      */
1643     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
1644                                   Type site, Name name, List<Type> argtypes,
1645                                   List<Type> typeargtypes) {
1646         return resolveQualifiedMethod(pos, env, site.tsym, site, name, argtypes, typeargtypes);
1647     }
1648     Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env<AttrContext> env,
1649                                   Symbol location, Type site, Name name, List<Type> argtypes,
1650                                   List<Type> typeargtypes) {
1651         return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes);
1652     }
1653     private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext,
1654                                   DiagnosticPosition pos, Env<AttrContext> env,
1655                                   Symbol location, Type site, Name name, List<Type> argtypes,
1656                                   List<Type> typeargtypes) {
1657         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1658         try {
1659             currentResolutionContext = resolveContext;
1660             Symbol sym = methodNotFound;
1661             List<MethodResolutionPhase> steps = methodResolutionSteps;
1662             while (steps.nonEmpty() &&
1663                    steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1664                    sym.kind >= ERRONEOUS) {
1665                 currentResolutionContext.step = steps.head;
1666                 sym = findMethod(env, site, name, argtypes, typeargtypes,
1667                         steps.head.isBoxingRequired(),
1668                         env.info.varArgs = steps.head.isVarargsRequired(), false);
1669                 currentResolutionContext.resolutionCache.put(steps.head, sym);
1670                 steps = steps.tail;
1671             }
1672             if (sym.kind >= AMBIGUOUS) {
1673                 if (site.tsym.isPolymorphicSignatureGeneric()) {
1674                     //polymorphic receiver - synthesize new method symbol
1675                     env.info.varArgs = false;
1676                     sym = findPolymorphicSignatureInstance(env,
1677                             site, name, null, argtypes);
1678                 }
1679                 else {
1680                     //if nothing is found return the 'first' error
1681                     MethodResolutionPhase errPhase =
1682                             currentResolutionContext.firstErroneousResolutionPhase();
1683                     sym = access(currentResolutionContext.resolutionCache.get(errPhase),
1684                             pos, location, site, name, true, argtypes, typeargtypes);
1685                     env.info.varArgs = errPhase.isVarargsRequired;
1686                 }
1687             } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
1688                 //non-instantiated polymorphic signature - synthesize new method symbol
1689                 env.info.varArgs = false;
1690                 sym = findPolymorphicSignatureInstance(env,
1691                         site, name, (MethodSymbol)sym, argtypes);
1692             }
1693             return sym;
1694         }
1695         finally {
1696             currentResolutionContext = prevResolutionContext;
1697         }
1698     }
1699 
1700     /** Find or create an implicit method of exactly the given type (after erasure).
1701      *  Searches in a side table, not the main scope of the site.
1702      *  This emulates the lookup process required by JSR 292 in JVM.
1703      *  @param env       Attribution environment
1704      *  @param site      The original type from where the selection takes place.
1705      *  @param name      The method's name.
1706      *  @param spMethod  A template for the implicit method, or null.
1707      *  @param argtypes  The required argument types.
1708      *  @param typeargtypes  The required type arguments.
1709      */
1710     Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, Type site,
1711                                             Name name,
1712                                             MethodSymbol spMethod,  // sig. poly. method or null if none
1713                                             List<Type> argtypes) {
1714         Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
1715                 site, name, spMethod, argtypes);
1716         long flags = ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE |
1717                     (spMethod != null ?
1718                         spMethod.flags() & Flags.AccessFlags :
1719                         Flags.PUBLIC | Flags.STATIC);
1720         Symbol m = null;
1721         for (Scope.Entry e = polymorphicSignatureScope.lookup(name);
1722              e.scope != null;
1723              e = e.next()) {
1724             Symbol sym = e.sym;
1725             if (types.isSameType(mtype, sym.type) &&
1726                 (sym.flags() & Flags.STATIC) == (flags & Flags.STATIC) &&
1727                 types.isSameType(sym.owner.type, site)) {
1728                m = sym;
1729                break;
1730             }
1731         }
1732         if (m == null) {
1733             // create the desired method
1734             m = new MethodSymbol(flags, name, mtype, site.tsym);
1735             polymorphicSignatureScope.enter(m);
1736         }
1737         return m;
1738     }
1739 
1740     /** Resolve a qualified method identifier, throw a fatal error if not
1741      *  found.
1742      *  @param pos       The position to use for error reporting.
1743      *  @param env       The environment current at the method invocation.
1744      *  @param site      The type of the qualifying expression, in which
1745      *                   identifier is searched.
1746      *  @param name      The identifier's name.
1747      *  @param argtypes  The types of the invocation's value arguments.
1748      *  @param typeargtypes  The types of the invocation's type arguments.
1749      */
1750     public MethodSymbol resolveInternalMethod(DiagnosticPosition pos, Env<AttrContext> env,
1751                                         Type site, Name name,
1752                                         List<Type> argtypes,
1753                                         List<Type> typeargtypes) {
1754         MethodResolutionContext resolveContext = new MethodResolutionContext();
1755         resolveContext.internalResolution = true;
1756         Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym,
1757                 site, name, argtypes, typeargtypes);
1758         if (sym.kind == MTH) return (MethodSymbol)sym;
1759         else throw new FatalError(
1760                  diags.fragment("fatal.err.cant.locate.meth",
1761                                 name));
1762     }
1763 
1764     /** Resolve constructor.
1765      *  @param pos       The position to use for error reporting.
1766      *  @param env       The environment current at the constructor invocation.
1767      *  @param site      The type of class for which a constructor is searched.
1768      *  @param argtypes  The types of the constructor invocation's value
1769      *                   arguments.
1770      *  @param typeargtypes  The types of the constructor invocation's type
1771      *                   arguments.
1772      */
1773     Symbol resolveConstructor(DiagnosticPosition pos,
1774                               Env<AttrContext> env,
1775                               Type site,
1776                               List<Type> argtypes,
1777                               List<Type> typeargtypes) {
1778         return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
1779     }
1780     private Symbol resolveConstructor(MethodResolutionContext resolveContext,
1781                               DiagnosticPosition pos,
1782                               Env<AttrContext> env,
1783                               Type site,
1784                               List<Type> argtypes,
1785                               List<Type> typeargtypes) {
1786         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1787         try {
1788             currentResolutionContext = resolveContext;
1789             Symbol sym = methodNotFound;
1790             List<MethodResolutionPhase> steps = methodResolutionSteps;
1791             while (steps.nonEmpty() &&
1792                    steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1793                    sym.kind >= ERRONEOUS) {
1794                 currentResolutionContext.step = steps.head;
1795                 sym = findConstructor(pos, env, site, argtypes, typeargtypes,
1796                         steps.head.isBoxingRequired(),
1797                         env.info.varArgs = steps.head.isVarargsRequired());
1798                 currentResolutionContext.resolutionCache.put(steps.head, sym);
1799                 steps = steps.tail;
1800             }
1801             if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
1802                 MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
1803                 sym = access(currentResolutionContext.resolutionCache.get(errPhase),
1804                         pos, site, names.init, true, argtypes, typeargtypes);
1805                 env.info.varArgs = errPhase.isVarargsRequired();
1806             }
1807             return sym;
1808         }
1809         finally {
1810             currentResolutionContext = prevResolutionContext;
1811         }
1812     }
1813 
1814     /** Resolve constructor using diamond inference.
1815      *  @param pos       The position to use for error reporting.
1816      *  @param env       The environment current at the constructor invocation.
1817      *  @param site      The type of class for which a constructor is searched.
1818      *                   The scope of this class has been touched in attribution.
1819      *  @param argtypes  The types of the constructor invocation's value
1820      *                   arguments.
1821      *  @param typeargtypes  The types of the constructor invocation's type
1822      *                   arguments.
1823      */
1824     Symbol resolveDiamond(DiagnosticPosition pos,
1825                               Env<AttrContext> env,
1826                               Type site,
1827                               List<Type> argtypes,
1828                               List<Type> typeargtypes) {
1829         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1830         try {
1831             currentResolutionContext = new MethodResolutionContext();
1832             Symbol sym = methodNotFound;
1833             List<MethodResolutionPhase> steps = methodResolutionSteps;
1834             while (steps.nonEmpty() &&
1835                    steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
1836                    sym.kind >= ERRONEOUS) {
1837                 currentResolutionContext.step = steps.head;
1838                 sym = findDiamond(env, site, argtypes, typeargtypes,
1839                         steps.head.isBoxingRequired(),
1840                         env.info.varArgs = steps.head.isVarargsRequired());
1841                 currentResolutionContext.resolutionCache.put(steps.head, sym);
1842                 steps = steps.tail;
1843             }
1844             if (sym.kind >= AMBIGUOUS) {
1845                 final JCDiagnostic details = sym.kind == WRONG_MTH ?
1846                                 currentResolutionContext.candidates.head.details :
1847                                 null;
1848                 Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") {
1849                     @Override
1850                     JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
1851                             Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
1852                         String key = details == null ?
1853                             "cant.apply.diamond" :
1854                             "cant.apply.diamond.1";
1855                         return diags.create(dkind, log.currentSource(), pos, key,
1856                                 diags.fragment("diamond", site.tsym), details);
1857                     }
1858                 };
1859                 MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
1860                 sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes);
1861                 env.info.varArgs = errPhase.isVarargsRequired();
1862             }
1863             return sym;
1864         }
1865         finally {
1866             currentResolutionContext = prevResolutionContext;
1867         }
1868     }
1869 
1870     /** This method scans all the constructor symbol in a given class scope -
1871      *  assuming that the original scope contains a constructor of the kind:
1872      *  Foo(X x, Y y), where X,Y are class type-variables declared in Foo,
1873      *  a method check is executed against the modified constructor type:
1874      *  <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond
1875      *  inference. The inferred return type of the synthetic constructor IS
1876      *  the inferred type for the diamond operator.
1877      */
1878     private Symbol findDiamond(Env<AttrContext> env,
1879                               Type site,
1880                               List<Type> argtypes,
1881                               List<Type> typeargtypes,
1882                               boolean allowBoxing,
1883                               boolean useVarargs) {
1884         Symbol bestSoFar = methodNotFound;
1885         for (Scope.Entry e = site.tsym.members().lookup(names.init);
1886              e.scope != null;
1887              e = e.next()) {
1888             //- System.out.println(" e " + e.sym);
1889             if (e.sym.kind == MTH &&
1890                 (e.sym.flags_field & SYNTHETIC) == 0) {
1891                     List<Type> oldParams = e.sym.type.tag == FORALL ?
1892                             ((ForAll)e.sym.type).tvars :
1893                             List.<Type>nil();
1894                     Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
1895                             types.createMethodTypeWithReturn(e.sym.type.asMethodType(), site));
1896                     bestSoFar = selectBest(env, site, argtypes, typeargtypes,
1897                             new MethodSymbol(e.sym.flags(), names.init, constrType, site.tsym),
1898                             bestSoFar,
1899                             allowBoxing,
1900                             useVarargs,
1901                             false);
1902             }
1903         }
1904         return bestSoFar;
1905     }
1906 
1907     /** Resolve constructor.
1908      *  @param pos       The position to use for error reporting.
1909      *  @param env       The environment current at the constructor invocation.
1910      *  @param site      The type of class for which a constructor is searched.
1911      *  @param argtypes  The types of the constructor invocation's value
1912      *                   arguments.
1913      *  @param typeargtypes  The types of the constructor invocation's type
1914      *                   arguments.
1915      *  @param allowBoxing Allow boxing and varargs conversions.
1916      *  @param useVarargs Box trailing arguments into an array for varargs.
1917      */
1918     Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env,
1919                               Type site, List<Type> argtypes,
1920                               List<Type> typeargtypes,
1921                               boolean allowBoxing,
1922                               boolean useVarargs) {
1923         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1924         try {
1925             currentResolutionContext = new MethodResolutionContext();
1926             return findConstructor(pos, env, site, argtypes, typeargtypes, allowBoxing, useVarargs);
1927         }
1928         finally {
1929             currentResolutionContext = prevResolutionContext;
1930         }
1931     }
1932 
1933     Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env,
1934                               Type site, List<Type> argtypes,
1935                               List<Type> typeargtypes,
1936                               boolean allowBoxing,
1937                               boolean useVarargs) {
1938         Symbol sym = findMethod(env, site,
1939                                     names.init, argtypes,
1940                                     typeargtypes, allowBoxing,
1941                                     useVarargs, false);
1942         chk.checkDeprecated(pos, env.info.scope.owner, sym);
1943         return sym;
1944     }
1945 
1946     /** Resolve a constructor, throw a fatal error if not found.
1947      *  @param pos       The position to use for error reporting.
1948      *  @param env       The environment current at the method invocation.
1949      *  @param site      The type to be constructed.
1950      *  @param argtypes  The types of the invocation's value arguments.
1951      *  @param typeargtypes  The types of the invocation's type arguments.
1952      */
1953     public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env,
1954                                         Type site,
1955                                         List<Type> argtypes,
1956                                         List<Type> typeargtypes) {
1957         MethodResolutionContext resolveContext = new MethodResolutionContext();
1958         resolveContext.internalResolution = true;
1959         Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
1960         if (sym.kind == MTH) return (MethodSymbol)sym;
1961         else throw new FatalError(
1962                  diags.fragment("fatal.err.cant.locate.ctor", site));
1963     }
1964 
1965     /** Resolve operator.
1966      *  @param pos       The position to use for error reporting.
1967      *  @param optag     The tag of the operation tree.
1968      *  @param env       The environment current at the operation.
1969      *  @param argtypes  The types of the operands.
1970      */
1971     Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag,
1972                            Env<AttrContext> env, List<Type> argtypes) {
1973         MethodResolutionContext prevResolutionContext = currentResolutionContext;
1974         try {
1975             currentResolutionContext = new MethodResolutionContext();
1976             Name name = treeinfo.operatorName(optag);
1977             Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
1978                                     null, false, false, true);
1979             if (boxingEnabled && sym.kind >= WRONG_MTHS)
1980                 sym = findMethod(env, syms.predefClass.type, name, argtypes,
1981                                  null, true, false, true);
1982             return access(sym, pos, env.enclClass.sym.type, name,
1983                           false, argtypes, null);
1984         }
1985         finally {
1986             currentResolutionContext = prevResolutionContext;
1987         }
1988     }
1989 
1990     /** Resolve operator.
1991      *  @param pos       The position to use for error reporting.
1992      *  @param optag     The tag of the operation tree.
1993      *  @param env       The environment current at the operation.
1994      *  @param arg       The type of the operand.
1995      */
1996     Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) {
1997         return resolveOperator(pos, optag, env, List.of(arg));
1998     }
1999 
2000     /** Resolve binary operator.
2001      *  @param pos       The position to use for error reporting.
2002      *  @param optag     The tag of the operation tree.
2003      *  @param env       The environment current at the operation.
2004      *  @param left      The types of the left operand.
2005      *  @param right     The types of the right operand.
2006      */
2007     Symbol resolveBinaryOperator(DiagnosticPosition pos,
2008                                  JCTree.Tag optag,
2009                                  Env<AttrContext> env,
2010                                  Type left,
2011                                  Type right) {
2012         return resolveOperator(pos, optag, env, List.of(left, right));
2013     }
2014 
2015     /**
2016      * Resolve `c.name' where name == this or name == super.
2017      * @param pos           The position to use for error reporting.
2018      * @param env           The environment current at the expression.
2019      * @param c             The qualifier.
2020      * @param name          The identifier's name.
2021      */
2022     Symbol resolveSelf(DiagnosticPosition pos,
2023                        Env<AttrContext> env,
2024                        TypeSymbol c,
2025                        Name name) {
2026         Env<AttrContext> env1 = env;
2027         boolean staticOnly = false;
2028         while (env1.outer != null) {
2029             if (isStatic(env1)) staticOnly = true;
2030             if (env1.enclClass.sym == c) {
2031                 Symbol sym = env1.info.scope.lookup(name).sym;
2032                 if (sym != null) {
2033                     if (staticOnly) sym = new StaticError(sym);
2034                     return access(sym, pos, env.enclClass.sym.type,
2035                                   name, true);
2036                 }
2037             }
2038             if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
2039             env1 = env1.outer;
2040         }
2041         log.error(pos, "not.encl.class", c);
2042         return syms.errSymbol;
2043     }
2044 
2045     /**
2046      * Resolve `c.this' for an enclosing class c that contains the
2047      * named member.
2048      * @param pos           The position to use for error reporting.
2049      * @param env           The environment current at the expression.
2050      * @param member        The member that must be contained in the result.
2051      */
2052     Symbol resolveSelfContaining(DiagnosticPosition pos,
2053                                  Env<AttrContext> env,
2054                                  Symbol member,
2055                                  boolean isSuperCall) {
2056         Name name = names._this;
2057         Env<AttrContext> env1 = isSuperCall ? env.outer : env;
2058         boolean staticOnly = false;
2059         if (env1 != null) {
2060             while (env1 != null && env1.outer != null) {
2061                 if (isStatic(env1)) staticOnly = true;
2062                 if (env1.enclClass.sym.isSubClass(member.owner, types)) {
2063                     Symbol sym = env1.info.scope.lookup(name).sym;
2064                     if (sym != null) {
2065                         if (staticOnly) sym = new StaticError(sym);
2066                         return access(sym, pos, env.enclClass.sym.type,
2067                                       name, true);
2068                     }
2069                 }
2070                 if ((env1.enclClass.sym.flags() & STATIC) != 0)
2071                     staticOnly = true;
2072                 env1 = env1.outer;
2073             }
2074         }
2075         log.error(pos, "encl.class.required", member);
2076         return syms.errSymbol;
2077     }
2078 
2079     /**
2080      * Resolve an appropriate implicit this instance for t's container.
2081      * JLS 8.8.5.1 and 15.9.2
2082      */
2083     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t) {
2084         return resolveImplicitThis(pos, env, t, false);
2085     }
2086 
2087     Type resolveImplicitThis(DiagnosticPosition pos, Env<AttrContext> env, Type t, boolean isSuperCall) {
2088         Type thisType = (((t.tsym.owner.kind & (MTH|VAR)) != 0)
2089                          ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this)
2090                          : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type;
2091         if (env.info.isSelfCall && thisType.tsym == env.enclClass.sym)
2092             log.error(pos, "cant.ref.before.ctor.called", "this");
2093         return thisType;
2094     }
2095 
2096 /* ***************************************************************************
2097  *  ResolveError classes, indicating error situations when accessing symbols
2098  ****************************************************************************/
2099 
2100     //used by TransTypes when checking target type of synthetic cast
2101     public void logAccessErrorInternal(Env<AttrContext> env, JCTree tree, Type type) {
2102         AccessError error = new AccessError(env, env.enclClass.type, type.tsym);
2103         logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null);
2104     }
2105     //where
2106     private void logResolveError(ResolveError error,
2107             DiagnosticPosition pos,
2108             Symbol location,
2109             Type site,
2110             Name name,
2111             List<Type> argtypes,
2112             List<Type> typeargtypes) {
2113         JCDiagnostic d = error.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR,
2114                 pos, location, site, name, argtypes, typeargtypes);
2115         if (d != null) {
2116             d.setFlag(DiagnosticFlag.RESOLVE_ERROR);
2117             log.report(d);
2118         }
2119     }
2120 
2121     private final LocalizedString noArgs = new LocalizedString("compiler.misc.no.args");
2122 
2123     public Object methodArguments(List<Type> argtypes) {
2124         return argtypes == null || argtypes.isEmpty() ? noArgs : argtypes;
2125     }
2126 
2127     /**
2128      * Root class for resolution errors. Subclass of ResolveError
2129      * represent a different kinds of resolution error - as such they must
2130      * specify how they map into concrete compiler diagnostics.
2131      */
2132     private abstract class ResolveError extends Symbol {
2133 
2134         /** The name of the kind of error, for debugging only. */
2135         final String debugName;
2136 
2137         ResolveError(int kind, String debugName) {
2138             super(kind, 0, null, null, null);
2139             this.debugName = debugName;
2140         }
2141 
2142         @Override
2143         public <R, P> R accept(ElementVisitor<R, P> v, P p) {
2144             throw new AssertionError();
2145         }
2146 
2147         @Override
2148         public String toString() {
2149             return debugName;
2150         }
2151 
2152         @Override
2153         public boolean exists() {
2154             return false;
2155         }
2156 
2157         /**
2158          * Create an external representation for this erroneous symbol to be
2159          * used during attribution - by default this returns the symbol of a
2160          * brand new error type which stores the original type found
2161          * during resolution.
2162          *
2163          * @param name     the name used during resolution
2164          * @param location the location from which the symbol is accessed
2165          */
2166         protected Symbol access(Name name, TypeSymbol location) {
2167             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
2168         }
2169 
2170         /**
2171          * Create a diagnostic representing this resolution error.
2172          *
2173          * @param dkind     The kind of the diagnostic to be created (e.g error).
2174          * @param pos       The position to be used for error reporting.
2175          * @param site      The original type from where the selection took place.
2176          * @param name      The name of the symbol to be resolved.
2177          * @param argtypes  The invocation's value arguments,
2178          *                  if we looked for a method.
2179          * @param typeargtypes  The invocation's type arguments,
2180          *                      if we looked for a method.
2181          */
2182         abstract JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2183                 DiagnosticPosition pos,
2184                 Symbol location,
2185                 Type site,
2186                 Name name,
2187                 List<Type> argtypes,
2188                 List<Type> typeargtypes);
2189 
2190         /**
2191          * A name designates an operator if it consists
2192          * of a non-empty sequence of operator symbols +-~!/*%&|^<>=
2193          */
2194         boolean isOperator(Name name) {
2195             int i = 0;
2196             while (i < name.getByteLength() &&
2197                    "+-~!*/%&|^<>=".indexOf(name.getByteAt(i)) >= 0) i++;
2198             return i > 0 && i == name.getByteLength();
2199         }
2200     }
2201 
2202     /**
2203      * This class is the root class of all resolution errors caused by
2204      * an invalid symbol being found during resolution.
2205      */
2206     abstract class InvalidSymbolError extends ResolveError {
2207 
2208         /** The invalid symbol found during resolution */
2209         Symbol sym;
2210 
2211         InvalidSymbolError(int kind, Symbol sym, String debugName) {
2212             super(kind, debugName);
2213             this.sym = sym;
2214         }
2215 
2216         @Override
2217         public boolean exists() {
2218             return true;
2219         }
2220 
2221         @Override
2222         public String toString() {
2223              return super.toString() + " wrongSym=" + sym;
2224         }
2225 
2226         @Override
2227         public Symbol access(Name name, TypeSymbol location) {
2228             if (sym.kind >= AMBIGUOUS)
2229                 return ((ResolveError)sym).access(name, location);
2230             else if ((sym.kind & ERRONEOUS) == 0 && (sym.kind & TYP) != 0)
2231                 return types.createErrorType(name, location, sym.type).tsym;
2232             else
2233                 return sym;
2234         }
2235     }
2236 
2237     /**
2238      * InvalidSymbolError error class indicating that a symbol matching a
2239      * given name does not exists in a given site.
2240      */
2241     class SymbolNotFoundError extends ResolveError {
2242 
2243         SymbolNotFoundError(int kind) {
2244             super(kind, "symbol not found error");
2245         }
2246 
2247         @Override
2248         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2249                 DiagnosticPosition pos,
2250                 Symbol location,
2251                 Type site,
2252                 Name name,
2253                 List<Type> argtypes,
2254                 List<Type> typeargtypes) {
2255             argtypes = argtypes == null ? List.<Type>nil() : argtypes;
2256             typeargtypes = typeargtypes == null ? List.<Type>nil() : typeargtypes;
2257             if (name == names.error)
2258                 return null;
2259 
2260             if (isOperator(name)) {
2261                 boolean isUnaryOp = argtypes.size() == 1;
2262                 String key = argtypes.size() == 1 ?
2263                     "operator.cant.be.applied" :
2264                     "operator.cant.be.applied.1";
2265                 Type first = argtypes.head;
2266                 Type second = !isUnaryOp ? argtypes.tail.head : null;
2267                 return diags.create(dkind, log.currentSource(), pos,
2268                         key, name, first, second);
2269             }
2270             boolean hasLocation = false;
2271             if (location == null) {
2272                 location = site.tsym;
2273             }
2274             if (!location.name.isEmpty()) {
2275                 if (location.kind == PCK && !site.tsym.exists()) {
2276                     return diags.create(dkind, log.currentSource(), pos,
2277                         "doesnt.exist", location);
2278                 }
2279                 hasLocation = !location.name.equals(names._this) &&
2280                         !location.name.equals(names._super);
2281             }
2282             boolean isConstructor = kind == ABSENT_MTH &&
2283                     name == names.table.names.init;
2284             KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
2285             Name idname = isConstructor ? site.tsym.name : name;
2286             String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
2287             if (hasLocation) {
2288                 return diags.create(dkind, log.currentSource(), pos,
2289                         errKey, kindname, idname, //symbol kindname, name
2290                         typeargtypes, argtypes, //type parameters and arguments (if any)
2291                         getLocationDiag(location, site)); //location kindname, type
2292             }
2293             else {
2294                 return diags.create(dkind, log.currentSource(), pos,
2295                         errKey, kindname, idname, //symbol kindname, name
2296                         typeargtypes, argtypes); //type parameters and arguments (if any)
2297             }
2298         }
2299         //where
2300         private String getErrorKey(KindName kindname, boolean hasTypeArgs, boolean hasLocation) {
2301             String key = "cant.resolve";
2302             String suffix = hasLocation ? ".location" : "";
2303             switch (kindname) {
2304                 case METHOD:
2305                 case CONSTRUCTOR: {
2306                     suffix += ".args";
2307                     suffix += hasTypeArgs ? ".params" : "";
2308                 }
2309             }
2310             return key + suffix;
2311         }
2312         private JCDiagnostic getLocationDiag(Symbol location, Type site) {
2313             if (location.kind == VAR) {
2314                 return diags.fragment("location.1",
2315                     kindName(location),
2316                     location,
2317                     location.type);
2318             } else {
2319                 return diags.fragment("location",
2320                     typeKindName(site),
2321                     site,
2322                     null);
2323             }
2324         }
2325     }
2326 
2327     /**
2328      * InvalidSymbolError error class indicating that a given symbol
2329      * (either a method, a constructor or an operand) is not applicable
2330      * given an actual arguments/type argument list.
2331      */
2332     class InapplicableSymbolError extends ResolveError {
2333 
2334         InapplicableSymbolError() {
2335             super(WRONG_MTH, "inapplicable symbol error");
2336         }
2337 
2338         protected InapplicableSymbolError(int kind, String debugName) {
2339             super(kind, debugName);
2340         }
2341 
2342         @Override
2343         public String toString() {
2344             return super.toString();
2345         }
2346 
2347         @Override
2348         public boolean exists() {
2349             return true;
2350         }
2351 
2352         @Override
2353         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2354                 DiagnosticPosition pos,
2355                 Symbol location,
2356                 Type site,
2357                 Name name,
2358                 List<Type> argtypes,
2359                 List<Type> typeargtypes) {
2360             if (name == names.error)
2361                 return null;
2362 
2363             if (isOperator(name)) {
2364                 boolean isUnaryOp = argtypes.size() == 1;
2365                 String key = argtypes.size() == 1 ?
2366                     "operator.cant.be.applied" :
2367                     "operator.cant.be.applied.1";
2368                 Type first = argtypes.head;
2369                 Type second = !isUnaryOp ? argtypes.tail.head : null;
2370                 return diags.create(dkind, log.currentSource(), pos,
2371                         key, name, first, second);
2372             }
2373             else {
2374                 Candidate c = errCandidate();
2375                 Symbol ws = c.sym.asMemberOf(site, types);
2376                 return diags.create(dkind, log.currentSource(), pos,
2377                           "cant.apply.symbol" + (c.details != null ? ".1" : ""),
2378                           kindName(ws),
2379                           ws.name == names.init ? ws.owner.name : ws.name,
2380                           methodArguments(ws.type.getParameterTypes()),
2381                           methodArguments(argtypes),
2382                           kindName(ws.owner),
2383                           ws.owner.type,
2384                           c.details);
2385             }
2386         }
2387 
2388         @Override
2389         public Symbol access(Name name, TypeSymbol location) {
2390             return types.createErrorType(name, location, syms.errSymbol.type).tsym;
2391         }
2392 
2393         protected boolean shouldReport(Candidate c) {
2394             return !c.isApplicable() &&
2395                     (((c.sym.flags() & VARARGS) != 0 && c.step == VARARITY) ||
2396                       (c.sym.flags() & VARARGS) == 0 && c.step == (boxingEnabled ? BOX : BASIC));
2397         }
2398 
2399         private Candidate errCandidate() {
2400             for (Candidate c : currentResolutionContext.candidates) {
2401                 if (shouldReport(c)) {
2402                     return c;
2403                 }
2404             }
2405             Assert.error();
2406             return null;
2407         }
2408     }
2409 
2410     /**
2411      * ResolveError error class indicating that a set of symbols
2412      * (either methods, constructors or operands) is not applicable
2413      * given an actual arguments/type argument list.
2414      */
2415     class InapplicableSymbolsError extends InapplicableSymbolError {
2416 
2417         InapplicableSymbolsError() {
2418             super(WRONG_MTHS, "inapplicable symbols");
2419         }
2420 
2421         @Override
2422         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2423                 DiagnosticPosition pos,
2424                 Symbol location,
2425                 Type site,
2426                 Name name,
2427                 List<Type> argtypes,
2428                 List<Type> typeargtypes) {
2429             if (currentResolutionContext.candidates.nonEmpty()) {
2430                 JCDiagnostic err = diags.create(dkind,
2431                         log.currentSource(),
2432                         pos,
2433                         "cant.apply.symbols",
2434                         name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
2435                         getName(),
2436                         argtypes);
2437                 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
2438             } else {
2439                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind, pos,
2440                     location, site, name, argtypes, typeargtypes);
2441             }
2442         }
2443 
2444         //where
2445         List<JCDiagnostic> candidateDetails(Type site) {
2446             List<JCDiagnostic> details = List.nil();
2447             for (Candidate c : currentResolutionContext.candidates) {
2448                 if (!shouldReport(c)) continue;
2449                 JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
2450                         Kinds.kindName(c.sym),
2451                         c.sym.location(site, types),
2452                         c.sym.asMemberOf(site, types),
2453                         c.details);
2454                 details = details.prepend(detailDiag);
2455             }
2456             return details.reverse();
2457         }
2458 
2459         private Name getName() {
2460             Symbol sym = currentResolutionContext.candidates.head.sym;
2461             return sym.name == names.init ?
2462                 sym.owner.name :
2463                 sym.name;
2464         }
2465     }
2466 
2467     /**
2468      * An InvalidSymbolError error class indicating that a symbol is not
2469      * accessible from a given site
2470      */
2471     class AccessError extends InvalidSymbolError {
2472 
2473         private Env<AttrContext> env;
2474         private Type site;
2475 
2476         AccessError(Symbol sym) {
2477             this(null, null, sym);
2478         }
2479 
2480         AccessError(Env<AttrContext> env, Type site, Symbol sym) {
2481             super(HIDDEN, sym, "access error");
2482             this.env = env;
2483             this.site = site;
2484             if (debugResolve)
2485                 log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
2486         }
2487 
2488         @Override
2489         public boolean exists() {
2490             return false;
2491         }
2492 
2493         @Override
2494         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2495                 DiagnosticPosition pos,
2496                 Symbol location,
2497                 Type site,
2498                 Name name,
2499                 List<Type> argtypes,
2500                 List<Type> typeargtypes) {
2501             if (sym.owner.type.tag == ERROR)
2502                 return null;
2503 
2504             if (sym.name == names.init && sym.owner != site.tsym) {
2505                 return new SymbolNotFoundError(ABSENT_MTH).getDiagnostic(dkind,
2506                         pos, location, site, name, argtypes, typeargtypes);
2507             }
2508             else if ((sym.flags() & PUBLIC) != 0
2509                 || (env != null && this.site != null
2510                     && !isAccessible(env, this.site))) {
2511                 return diags.create(dkind, log.currentSource(),
2512                         pos, "not.def.access.class.intf.cant.access",
2513                     sym, sym.location());
2514             }
2515             else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0) {
2516                 return diags.create(dkind, log.currentSource(),
2517                         pos, "report.access", sym,
2518                         asFlagSet(sym.flags() & (PRIVATE | PROTECTED)),
2519                         sym.location());
2520             }
2521             else {
2522                 return diags.create(dkind, log.currentSource(),
2523                         pos, "not.def.public.cant.access", sym, sym.location());
2524             }
2525         }
2526     }
2527 
2528     /**
2529      * InvalidSymbolError error class indicating that an instance member
2530      * has erroneously been accessed from a static context.
2531      */
2532     class StaticError extends InvalidSymbolError {
2533 
2534         StaticError(Symbol sym) {
2535             super(STATICERR, sym, "static error");
2536         }
2537 
2538         @Override
2539         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2540                 DiagnosticPosition pos,
2541                 Symbol location,
2542                 Type site,
2543                 Name name,
2544                 List<Type> argtypes,
2545                 List<Type> typeargtypes) {
2546             Symbol errSym = ((sym.kind == TYP && sym.type.tag == CLASS)
2547                 ? types.erasure(sym.type).tsym
2548                 : sym);
2549             return diags.create(dkind, log.currentSource(), pos,
2550                     "non-static.cant.be.ref", kindName(sym), errSym);
2551         }
2552     }
2553 
2554     /**
2555      * InvalidSymbolError error class indicating that a pair of symbols
2556      * (either methods, constructors or operands) are ambiguous
2557      * given an actual arguments/type argument list.
2558      */
2559     class AmbiguityError extends InvalidSymbolError {
2560 
2561         /** The other maximally specific symbol */
2562         Symbol sym2;
2563 
2564         AmbiguityError(Symbol sym1, Symbol sym2) {
2565             super(AMBIGUOUS, sym1, "ambiguity error");
2566             this.sym2 = sym2;
2567         }
2568 
2569         @Override
2570         JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
2571                 DiagnosticPosition pos,
2572                 Symbol location,
2573                 Type site,
2574                 Name name,
2575                 List<Type> argtypes,
2576                 List<Type> typeargtypes) {
2577             AmbiguityError pair = this;
2578             while (true) {
2579                 if (pair.sym.kind == AMBIGUOUS)
2580                     pair = (AmbiguityError)pair.sym;
2581                 else if (pair.sym2.kind == AMBIGUOUS)
2582                     pair = (AmbiguityError)pair.sym2;
2583                 else break;
2584             }
2585             Name sname = pair.sym.name;
2586             if (sname == names.init) sname = pair.sym.owner.name;
2587             return diags.create(dkind, log.currentSource(),
2588                       pos, "ref.ambiguous", sname,
2589                       kindName(pair.sym),
2590                       pair.sym,
2591                       pair.sym.location(site, types),
2592                       kindName(pair.sym2),
2593                       pair.sym2,
2594                       pair.sym2.location(site, types));
2595         }
2596     }
2597 
2598     enum MethodResolutionPhase {
2599         BASIC(false, false),
2600         BOX(true, false),
2601         VARARITY(true, true);
2602 
2603         boolean isBoxingRequired;
2604         boolean isVarargsRequired;
2605 
2606         MethodResolutionPhase(boolean isBoxingRequired, boolean isVarargsRequired) {
2607            this.isBoxingRequired = isBoxingRequired;
2608            this.isVarargsRequired = isVarargsRequired;
2609         }
2610 
2611         public boolean isBoxingRequired() {
2612             return isBoxingRequired;
2613         }
2614 
2615         public boolean isVarargsRequired() {
2616             return isVarargsRequired;
2617         }
2618 
2619         public boolean isApplicable(boolean boxingEnabled, boolean varargsEnabled) {
2620             return (varargsEnabled || !isVarargsRequired) &&
2621                    (boxingEnabled || !isBoxingRequired);
2622         }
2623     }
2624 
2625     final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
2626 
2627     /**
2628      * A resolution context is used to keep track of intermediate results of
2629      * overload resolution, such as list of method that are not applicable
2630      * (used to generate more precise diagnostics) and so on. Resolution contexts
2631      * can be nested - this means that when each overload resolution routine should
2632      * work within the resolution context it created.
2633      */
2634     class MethodResolutionContext {
2635 
2636         private List<Candidate> candidates = List.nil();
2637 
2638         private Map<MethodResolutionPhase, Symbol> resolutionCache =
2639             new EnumMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.class);
2640 
2641         private MethodResolutionPhase step = null;
2642 
2643         private boolean internalResolution = false;
2644 
2645         private MethodResolutionPhase firstErroneousResolutionPhase() {
2646             MethodResolutionPhase bestSoFar = BASIC;
2647             Symbol sym = methodNotFound;
2648             List<MethodResolutionPhase> steps = methodResolutionSteps;
2649             while (steps.nonEmpty() &&
2650                    steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
2651                    sym.kind >= WRONG_MTHS) {
2652                 sym = resolutionCache.get(steps.head);
2653                 bestSoFar = steps.head;
2654                 steps = steps.tail;
2655             }
2656             return bestSoFar;
2657         }
2658 
2659         void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
2660             Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
2661             if (!candidates.contains(c))
2662                 candidates = candidates.append(c);
2663         }
2664 
2665         void addApplicableCandidate(Symbol sym, Type mtype) {
2666             Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype);
2667             candidates = candidates.append(c);
2668         }
2669 
2670         /**
2671          * This class represents an overload resolution candidate. There are two
2672          * kinds of candidates: applicable methods and inapplicable methods;
2673          * applicable methods have a pointer to the instantiated method type,
2674          * while inapplicable candidates contain further details about the
2675          * reason why the method has been considered inapplicable.
2676          */
2677         class Candidate {
2678 
2679             final MethodResolutionPhase step;
2680             final Symbol sym;
2681             final JCDiagnostic details;
2682             final Type mtype;
2683 
2684             private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) {
2685                 this.step = step;
2686                 this.sym = sym;
2687                 this.details = details;
2688                 this.mtype = mtype;
2689             }
2690 
2691             @Override
2692             public boolean equals(Object o) {
2693                 if (o instanceof Candidate) {
2694                     Symbol s1 = this.sym;
2695                     Symbol s2 = ((Candidate)o).sym;
2696                     if  ((s1 != s2 &&
2697                         (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
2698                         (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
2699                         ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
2700                         return true;
2701                 }
2702                 return false;
2703             }
2704 
2705             boolean isApplicable() {
2706                 return mtype != null;
2707             }
2708         }
2709     }
2710 
2711     MethodResolutionContext currentResolutionContext = null;
2712 }