src/share/classes/com/sun/tools/javac/comp/Resolve.java

Tue, 24 Jan 2012 17:52:02 +0000

author
mcimadamore
date
Tue, 24 Jan 2012 17:52:02 +0000
changeset 1186
51fb17abfc32
parent 1127
ca49d50318dc
child 1215
161230ec7c73
permissions
-rw-r--r--

7129801: Merge the two method applicability routines
Summary: Resolve.java and Infer.java should reuse the same method applicability check routine
Reviewed-by: dlsmith, jjg

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

mercurial