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

changeset 1352
d4b3cb1ece84
parent 1348
573ceb23beeb
child 1374
c002fdee76fd
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Oct 05 14:21:09 2012 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Sat Oct 06 10:35:38 2012 +0100
     1.3 @@ -40,6 +40,7 @@
     1.4  import com.sun.tools.javac.jvm.*;
     1.5  import com.sun.tools.javac.tree.*;
     1.6  import com.sun.tools.javac.tree.JCTree.*;
     1.7 +import com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind;
     1.8  import com.sun.tools.javac.util.*;
     1.9  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
    1.10  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    1.11 @@ -98,10 +99,6 @@
    1.12  
    1.13          varNotFound = new
    1.14              SymbolNotFoundError(ABSENT_VAR);
    1.15 -        wrongMethod = new
    1.16 -            InapplicableSymbolError();
    1.17 -        wrongMethods = new
    1.18 -            InapplicableSymbolsError();
    1.19          methodNotFound = new
    1.20              SymbolNotFoundError(ABSENT_MTH);
    1.21          typeNotFound = new
    1.22 @@ -133,8 +130,6 @@
    1.23      /** error symbols, which are returned when resolution fails
    1.24       */
    1.25      private final SymbolNotFoundError varNotFound;
    1.26 -    private final InapplicableSymbolError wrongMethod;
    1.27 -    private final InapplicableSymbolsError wrongMethods;
    1.28      private final SymbolNotFoundError methodNotFound;
    1.29      private final SymbolNotFoundError typeNotFound;
    1.30  
    1.31 @@ -454,8 +449,18 @@
    1.32                          boolean useVarargs,
    1.33                          Warner warn)
    1.34          throws Infer.InferenceException {
    1.35 -        if (useVarargs && (m.flags() & VARARGS) == 0)
    1.36 -            throw inapplicableMethodException.setMessage();
    1.37 +        if (useVarargs && (m.flags() & VARARGS) == 0) {
    1.38 +            //better error recovery - if we stumbled upon a non-varargs method
    1.39 +            //during varargs applicability phase, the method should be treated as
    1.40 +            //not applicable; the reason for inapplicability can be found in the
    1.41 +            //candidate for 'm' that was created during the BOX phase.
    1.42 +            Candidate prevCandidate = currentResolutionContext.getCandidate(m, BOX);
    1.43 +            JCDiagnostic details = null;
    1.44 +            if (prevCandidate != null && !prevCandidate.isApplicable()) {
    1.45 +                details = prevCandidate.details;
    1.46 +            }
    1.47 +            throw inapplicableMethodException.setMessage(details);
    1.48 +        }
    1.49          Type mt = types.memberType(site, m);
    1.50  
    1.51          // tvars is the list of formal type variables for which type arguments
    1.52 @@ -1028,11 +1033,10 @@
    1.53                  currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
    1.54              switch (bestSoFar.kind) {
    1.55              case ABSENT_MTH:
    1.56 -                return wrongMethod;
    1.57 +                return new InapplicableSymbolError(currentResolutionContext);
    1.58              case WRONG_MTH:
    1.59                  if (operator) return bestSoFar;
    1.60 -            case WRONG_MTHS:
    1.61 -                return wrongMethods;
    1.62 +                bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
    1.63              default:
    1.64                  return bestSoFar;
    1.65              }
    1.66 @@ -1181,7 +1185,8 @@
    1.67  
    1.68              //is this a structural actual argument?
    1.69              boolean isStructuralPoly = actual.tag == DEFERRED &&
    1.70 -                    ((DeferredType)actual).tree.hasTag(LAMBDA);
    1.71 +                    (((DeferredType)actual).tree.hasTag(LAMBDA) ||
    1.72 +                    ((DeferredType)actual).tree.hasTag(REFERENCE));
    1.73  
    1.74              Type newFormal = f1;
    1.75  
    1.76 @@ -2210,7 +2215,7 @@
    1.77                  final JCDiagnostic details = errSym.kind == WRONG_MTH ?
    1.78                                  ((InapplicableSymbolError)errSym).errCandidate().details :
    1.79                                  null;
    1.80 -                errSym = new InapplicableSymbolError(errSym.kind, "diamondError") {
    1.81 +                errSym = new InapplicableSymbolError(errSym.kind, "diamondError", currentResolutionContext) {
    1.82                      @Override
    1.83                      JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
    1.84                              Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
    1.85 @@ -2276,6 +2281,335 @@
    1.86          return bestSoFar;
    1.87      }
    1.88  
    1.89 +    /**
    1.90 +     * Resolution of member references is typically done as a single
    1.91 +     * overload resolution step, where the argument types A are inferred from
    1.92 +     * the target functional descriptor.
    1.93 +     *
    1.94 +     * If the member reference is a method reference with a type qualifier,
    1.95 +     * a two-step lookup process is performed. The first step uses the
    1.96 +     * expected argument list A, while the second step discards the first
    1.97 +     * type from A (which is treated as a receiver type).
    1.98 +     *
    1.99 +     * There are two cases in which inference is performed: (i) if the member
   1.100 +     * reference is a constructor reference and the qualifier type is raw - in
   1.101 +     * which case diamond inference is used to infer a parameterization for the
   1.102 +     * type qualifier; (ii) if the member reference is an unbound reference
   1.103 +     * where the type qualifier is raw - in that case, during the unbound lookup
   1.104 +     * the receiver argument type is used to infer an instantiation for the raw
   1.105 +     * qualifier type.
   1.106 +     *
   1.107 +     * When a multi-step resolution process is exploited, it is an error
   1.108 +     * if two candidates are found (ambiguity).
   1.109 +     *
   1.110 +     * This routine returns a pair (T,S), where S is the member reference symbol,
   1.111 +     * and T is the type of the class in which S is defined. This is necessary as
   1.112 +     * the type T might be dynamically inferred (i.e. if constructor reference
   1.113 +     * has a raw qualifier).
   1.114 +     */
   1.115 +    Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(DiagnosticPosition pos,
   1.116 +                                  Env<AttrContext> env,
   1.117 +                                  JCMemberReference referenceTree,
   1.118 +                                  Type site,
   1.119 +                                  Name name, List<Type> argtypes,
   1.120 +                                  List<Type> typeargtypes,
   1.121 +                                  boolean boxingAllowed) {
   1.122 +        //step 1 - bound lookup
   1.123 +        ReferenceLookupHelper boundLookupHelper = name.equals(names.init) ?
   1.124 +                new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, boxingAllowed) :
   1.125 +                new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, boxingAllowed);
   1.126 +        Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
   1.127 +        Symbol boundSym = findMemberReference(boundEnv, boundLookupHelper);
   1.128 +
   1.129 +        //step 2 - unbound lookup
   1.130 +        ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup();
   1.131 +        Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
   1.132 +        Symbol unboundSym = findMemberReference(unboundEnv, unboundLookupHelper);
   1.133 +
   1.134 +        //merge results
   1.135 +        Pair<Symbol, ReferenceLookupHelper> res;
   1.136 +        if (unboundSym.kind != MTH) {
   1.137 +            res = new Pair<Symbol, ReferenceLookupHelper>(boundSym, boundLookupHelper);
   1.138 +            env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
   1.139 +        } else if (boundSym.kind == MTH) {
   1.140 +            res = new Pair<Symbol, ReferenceLookupHelper>(ambiguityError(boundSym, unboundSym), boundLookupHelper);
   1.141 +            env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
   1.142 +        } else {
   1.143 +            res = new Pair<Symbol, ReferenceLookupHelper>(unboundSym, unboundLookupHelper);
   1.144 +            env.info.pendingResolutionPhase = unboundEnv.info.pendingResolutionPhase;
   1.145 +        }
   1.146 +
   1.147 +        return res;
   1.148 +    }
   1.149 +
   1.150 +    /**
   1.151 +     * Helper for defining custom method-like lookup logic; a lookup helper
   1.152 +     * provides hooks for (i) the actual lookup logic and (ii) accessing the
   1.153 +     * lookup result (this step might result in compiler diagnostics to be generated)
   1.154 +     */
   1.155 +    abstract class LookupHelper {
   1.156 +
   1.157 +        /** name of the symbol to lookup */
   1.158 +        Name name;
   1.159 +
   1.160 +        /** location in which the lookup takes place */
   1.161 +        Type site;
   1.162 +
   1.163 +        /** actual types used during the lookup */
   1.164 +        List<Type> argtypes;
   1.165 +
   1.166 +        /** type arguments used during the lookup */
   1.167 +        List<Type> typeargtypes;
   1.168 +
   1.169 +        LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
   1.170 +            this.name = name;
   1.171 +            this.site = site;
   1.172 +            this.argtypes = argtypes;
   1.173 +            this.typeargtypes = typeargtypes;
   1.174 +        }
   1.175 +
   1.176 +        /**
   1.177 +         * Search for a symbol under a given overload resolution phase - this method
   1.178 +         * is usually called several times, once per each overload resolution phase
   1.179 +         */
   1.180 +        abstract Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase);
   1.181 +
   1.182 +        /**
   1.183 +         * Validate the result of the lookup
   1.184 +         */
   1.185 +        abstract Symbol access(Env<AttrContext> env, Symbol symbol);
   1.186 +    }
   1.187 +
   1.188 +    /**
   1.189 +     * Helper class for member reference lookup. A reference lookup helper
   1.190 +     * defines the basic logic for member reference lookup; a method gives
   1.191 +     * access to an 'unbound' helper used to perform an unbound member
   1.192 +     * reference lookup.
   1.193 +     */
   1.194 +    abstract class ReferenceLookupHelper extends LookupHelper {
   1.195 +
   1.196 +        /** The member reference tree */
   1.197 +        JCMemberReference referenceTree;
   1.198 +
   1.199 +        /** Max overload resolution phase handled by this helper */
   1.200 +        MethodResolutionPhase maxPhase;
   1.201 +
   1.202 +        ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
   1.203 +                List<Type> argtypes, List<Type> typeargtypes, boolean boxingAllowed) {
   1.204 +            super(name, site, argtypes, typeargtypes);
   1.205 +            this.referenceTree = referenceTree;
   1.206 +            this.maxPhase = boxingAllowed ? VARARITY : BASIC;
   1.207 +        }
   1.208 +
   1.209 +        /**
   1.210 +         * Returns an unbound version of this lookup helper. By default, this
   1.211 +         * method returns an dummy lookup helper.
   1.212 +         */
   1.213 +        ReferenceLookupHelper unboundLookup() {
   1.214 +            //dummy loopkup helper that always return 'methodNotFound'
   1.215 +            return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase.isBoxingRequired()) {
   1.216 +                @Override
   1.217 +                ReferenceLookupHelper unboundLookup() {
   1.218 +                    return this;
   1.219 +                }
   1.220 +                @Override
   1.221 +                Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase) {
   1.222 +                    return methodNotFound;
   1.223 +                }
   1.224 +                @Override
   1.225 +                ReferenceKind referenceKind(Symbol sym) {
   1.226 +                    Assert.error();
   1.227 +                    return null;
   1.228 +                }
   1.229 +            };
   1.230 +        }
   1.231 +
   1.232 +        /**
   1.233 +         * Get the kind of the member reference
   1.234 +         */
   1.235 +        abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
   1.236 +
   1.237 +        @Override
   1.238 +        Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
   1.239 +            return (env.info.pendingResolutionPhase.ordinal() > maxPhase.ordinal()) ?
   1.240 +                    methodNotFound : lookupReference(env, phase);
   1.241 +        }
   1.242 +
   1.243 +        abstract Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase);
   1.244 +
   1.245 +        Symbol access(Env<AttrContext> env, Symbol sym) {
   1.246 +            if (sym.kind >= AMBIGUOUS) {
   1.247 +                MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
   1.248 +                if (errPhase.ordinal() > maxPhase.ordinal()) {
   1.249 +                    errPhase = maxPhase;
   1.250 +                }
   1.251 +                env.info.pendingResolutionPhase = errPhase;
   1.252 +                sym = currentResolutionContext.resolutionCache.get(errPhase);
   1.253 +            }
   1.254 +            return sym;
   1.255 +        }
   1.256 +    }
   1.257 +
   1.258 +    /**
   1.259 +     * Helper class for method reference lookup. The lookup logic is based
   1.260 +     * upon Resolve.findMethod; in certain cases, this helper class has a
   1.261 +     * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
   1.262 +     * In such cases, non-static lookup results are thrown away.
   1.263 +     */
   1.264 +    class MethodReferenceLookupHelper extends ReferenceLookupHelper {
   1.265 +
   1.266 +        MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
   1.267 +                List<Type> argtypes, List<Type> typeargtypes, boolean boxingAllowed) {
   1.268 +            super(referenceTree, name, site, argtypes, typeargtypes, boxingAllowed);
   1.269 +        }
   1.270 +
   1.271 +        protected Symbol lookupReferenceInternal(Env<AttrContext> env, MethodResolutionPhase phase) {
   1.272 +            return findMethod(env, site, name, argtypes, typeargtypes,
   1.273 +                    phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
   1.274 +        }
   1.275 +
   1.276 +        protected Symbol adjustLookupResult(Env<AttrContext> env, Symbol sym) {
   1.277 +            return !TreeInfo.isStaticSelector(referenceTree.expr, names) ||
   1.278 +                        sym.kind != MTH ||
   1.279 +                        sym.isStatic() ? sym : new StaticError(sym);
   1.280 +        }
   1.281 +
   1.282 +        @Override
   1.283 +        final Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase) {
   1.284 +            return adjustLookupResult(env, lookupReferenceInternal(env, phase));
   1.285 +        }
   1.286 +
   1.287 +        @Override
   1.288 +        ReferenceLookupHelper unboundLookup() {
   1.289 +            if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
   1.290 +                    argtypes.nonEmpty() &&
   1.291 +                    types.isSubtypeUnchecked(argtypes.head, site)) {
   1.292 +                return new UnboundMethodReferenceLookupHelper(referenceTree, name,
   1.293 +                        site, argtypes, typeargtypes, maxPhase.isBoxingRequired());
   1.294 +            } else {
   1.295 +                return super.unboundLookup();
   1.296 +            }
   1.297 +        }
   1.298 +
   1.299 +        @Override
   1.300 +        ReferenceKind referenceKind(Symbol sym) {
   1.301 +            if (sym.isStatic()) {
   1.302 +                return TreeInfo.isStaticSelector(referenceTree.expr, names) ?
   1.303 +                        ReferenceKind.STATIC : ReferenceKind.STATIC_EVAL;
   1.304 +            } else {
   1.305 +                Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
   1.306 +                return selName != null && selName == names._super ?
   1.307 +                        ReferenceKind.SUPER :
   1.308 +                        ReferenceKind.BOUND;
   1.309 +            }
   1.310 +        }
   1.311 +    }
   1.312 +
   1.313 +    /**
   1.314 +     * Helper class for unbound method reference lookup. Essentially the same
   1.315 +     * as the basic method reference lookup helper; main difference is that static
   1.316 +     * lookup results are thrown away. If qualifier type is raw, an attempt to
   1.317 +     * infer a parameterized type is made using the first actual argument (that
   1.318 +     * would otherwise be ignored during the lookup).
   1.319 +     */
   1.320 +    class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
   1.321 +
   1.322 +        UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
   1.323 +                List<Type> argtypes, List<Type> typeargtypes, boolean boxingAllowed) {
   1.324 +            super(referenceTree, name,
   1.325 +                    site.isRaw() ? types.asSuper(argtypes.head, site.tsym) : site,
   1.326 +                    argtypes.tail, typeargtypes, boxingAllowed);
   1.327 +        }
   1.328 +
   1.329 +        @Override
   1.330 +        protected Symbol adjustLookupResult(Env<AttrContext> env, Symbol sym) {
   1.331 +            return sym.kind != MTH || !sym.isStatic() ? sym : new StaticError(sym);
   1.332 +        }
   1.333 +
   1.334 +        @Override
   1.335 +        ReferenceLookupHelper unboundLookup() {
   1.336 +            return this;
   1.337 +        }
   1.338 +
   1.339 +        @Override
   1.340 +        ReferenceKind referenceKind(Symbol sym) {
   1.341 +            return ReferenceKind.UNBOUND;
   1.342 +        }
   1.343 +    }
   1.344 +
   1.345 +    /**
   1.346 +     * Helper class for constructor reference lookup. The lookup logic is based
   1.347 +     * upon either Resolve.findMethod or Resolve.findDiamond - depending on
   1.348 +     * whether the constructor reference needs diamond inference (this is the case
   1.349 +     * if the qualifier type is raw). A special erroneous symbol is returned
   1.350 +     * if the lookup returns the constructor of an inner class and there's no
   1.351 +     * enclosing instance in scope.
   1.352 +     */
   1.353 +    class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
   1.354 +
   1.355 +        boolean needsInference;
   1.356 +
   1.357 +        ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes,
   1.358 +                List<Type> typeargtypes, boolean boxingAllowed) {
   1.359 +            super(referenceTree, names.init, site, argtypes, typeargtypes, boxingAllowed);
   1.360 +            if (site.isRaw()) {
   1.361 +                this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym);
   1.362 +                needsInference = true;
   1.363 +            }
   1.364 +        }
   1.365 +
   1.366 +        @Override
   1.367 +        protected Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase) {
   1.368 +            Symbol sym = needsInference ?
   1.369 +                findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
   1.370 +                findMethod(env, site, name, argtypes, typeargtypes,
   1.371 +                        phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
   1.372 +            return sym.kind != MTH ||
   1.373 +                          site.getEnclosingType().tag == NONE ||
   1.374 +                          hasEnclosingInstance(env, site) ?
   1.375 +                          sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) {
   1.376 +                    @Override
   1.377 +                    JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) {
   1.378 +                       return diags.create(dkind, log.currentSource(), pos,
   1.379 +                            "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
   1.380 +                    }
   1.381 +                };
   1.382 +        }
   1.383 +
   1.384 +        @Override
   1.385 +        ReferenceKind referenceKind(Symbol sym) {
   1.386 +            return site.getEnclosingType().tag == NONE ?
   1.387 +                    ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
   1.388 +        }
   1.389 +    }
   1.390 +
   1.391 +    /**
   1.392 +     * Resolution step for member reference. This generalizes a standard
   1.393 +     * method/constructor lookup - on each overload resolution step, a
   1.394 +     * lookup helper class is used to perform the reference lookup; at the end
   1.395 +     * of the lookup, the helper is used to validate the results.
   1.396 +     */
   1.397 +    Symbol findMemberReference(Env<AttrContext> env, LookupHelper lookupHelper) {
   1.398 +        MethodResolutionContext prevResolutionContext = currentResolutionContext;
   1.399 +        try {
   1.400 +            currentResolutionContext = new MethodResolutionContext();
   1.401 +            Symbol sym = methodNotFound;
   1.402 +            List<MethodResolutionPhase> steps = methodResolutionSteps;
   1.403 +            while (steps.nonEmpty() &&
   1.404 +                   steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
   1.405 +                   sym.kind >= ERRONEOUS) {
   1.406 +                currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
   1.407 +                sym = lookupHelper.lookup(env, steps.head);
   1.408 +                currentResolutionContext.resolutionCache.put(steps.head, sym);
   1.409 +                steps = steps.tail;
   1.410 +            }
   1.411 +            return lookupHelper.access(env, sym);
   1.412 +        }
   1.413 +        finally {
   1.414 +            currentResolutionContext = prevResolutionContext;
   1.415 +        }
   1.416 +    }
   1.417 +
   1.418      /** Resolve constructor.
   1.419       *  @param pos       The position to use for error reporting.
   1.420       *  @param env       The environment current at the constructor invocation.
   1.421 @@ -2425,6 +2759,23 @@
   1.422                                   Env<AttrContext> env,
   1.423                                   Symbol member,
   1.424                                   boolean isSuperCall) {
   1.425 +        Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall);
   1.426 +        if (sym == null) {
   1.427 +            log.error(pos, "encl.class.required", member);
   1.428 +            return syms.errSymbol;
   1.429 +        } else {
   1.430 +            return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true);
   1.431 +        }
   1.432 +    }
   1.433 +
   1.434 +    boolean hasEnclosingInstance(Env<AttrContext> env, Type type) {
   1.435 +        Symbol encl = resolveSelfContainingInternal(env, type.tsym, false);
   1.436 +        return encl != null && encl.kind < ERRONEOUS;
   1.437 +    }
   1.438 +
   1.439 +    private Symbol resolveSelfContainingInternal(Env<AttrContext> env,
   1.440 +                                 Symbol member,
   1.441 +                                 boolean isSuperCall) {
   1.442          Name name = names._this;
   1.443          Env<AttrContext> env1 = isSuperCall ? env.outer : env;
   1.444          boolean staticOnly = false;
   1.445 @@ -2435,8 +2786,7 @@
   1.446                      Symbol sym = env1.info.scope.lookup(name).sym;
   1.447                      if (sym != null) {
   1.448                          if (staticOnly) sym = new StaticError(sym);
   1.449 -                        return accessBase(sym, pos, env.enclClass.sym.type,
   1.450 -                                      name, true);
   1.451 +                        return sym;
   1.452                      }
   1.453                  }
   1.454                  if ((env1.enclClass.sym.flags() & STATIC) != 0)
   1.455 @@ -2444,8 +2794,7 @@
   1.456                  env1 = env1.outer;
   1.457              }
   1.458          }
   1.459 -        log.error(pos, "encl.class.required", member);
   1.460 -        return syms.errSymbol;
   1.461 +        return null;
   1.462      }
   1.463  
   1.464      /**
   1.465 @@ -2513,7 +2862,7 @@
   1.466       * represent a different kinds of resolution error - as such they must
   1.467       * specify how they map into concrete compiler diagnostics.
   1.468       */
   1.469 -    private abstract class ResolveError extends Symbol {
   1.470 +    abstract class ResolveError extends Symbol {
   1.471  
   1.472          /** The name of the kind of error, for debugging only. */
   1.473          final String debugName;
   1.474 @@ -2703,12 +3052,15 @@
   1.475       */
   1.476      class InapplicableSymbolError extends ResolveError {
   1.477  
   1.478 -        InapplicableSymbolError() {
   1.479 -            super(WRONG_MTH, "inapplicable symbol error");
   1.480 +        protected MethodResolutionContext resolveContext;
   1.481 +
   1.482 +        InapplicableSymbolError(MethodResolutionContext context) {
   1.483 +            this(WRONG_MTH, "inapplicable symbol error", context);
   1.484          }
   1.485  
   1.486 -        protected InapplicableSymbolError(int kind, String debugName) {
   1.487 +        protected InapplicableSymbolError(int kind, String debugName, MethodResolutionContext context) {
   1.488              super(kind, debugName);
   1.489 +            this.resolveContext = context;
   1.490          }
   1.491  
   1.492          @Override
   1.493 @@ -2746,7 +3098,7 @@
   1.494                  Candidate c = errCandidate();
   1.495                  Symbol ws = c.sym.asMemberOf(site, types);
   1.496                  return diags.create(dkind, log.currentSource(), pos,
   1.497 -                          "cant.apply.symbol" + (c.details != null ? ".1" : ""),
   1.498 +                          "cant.apply.symbol",
   1.499                            kindName(ws),
   1.500                            ws.name == names.init ? ws.owner.name : ws.name,
   1.501                            methodArguments(ws.type.getParameterTypes()),
   1.502 @@ -2763,13 +3115,13 @@
   1.503          }
   1.504  
   1.505          protected boolean shouldReport(Candidate c) {
   1.506 +            MethodResolutionPhase errPhase = resolveContext.firstErroneousResolutionPhase();
   1.507              return !c.isApplicable() &&
   1.508 -                    (((c.sym.flags() & VARARGS) != 0 && c.step == VARARITY) ||
   1.509 -                      (c.sym.flags() & VARARGS) == 0 && c.step == (boxingEnabled ? BOX : BASIC));
   1.510 +                    c.step == errPhase;
   1.511          }
   1.512  
   1.513          private Candidate errCandidate() {
   1.514 -            for (Candidate c : currentResolutionContext.candidates) {
   1.515 +            for (Candidate c : resolveContext.candidates) {
   1.516                  if (shouldReport(c)) {
   1.517                      return c;
   1.518                  }
   1.519 @@ -2786,8 +3138,8 @@
   1.520       */
   1.521      class InapplicableSymbolsError extends InapplicableSymbolError {
   1.522  
   1.523 -        InapplicableSymbolsError() {
   1.524 -            super(WRONG_MTHS, "inapplicable symbols");
   1.525 +        InapplicableSymbolsError(MethodResolutionContext context) {
   1.526 +            super(WRONG_MTHS, "inapplicable symbols", context);
   1.527          }
   1.528  
   1.529          @Override
   1.530 @@ -2798,7 +3150,7 @@
   1.531                  Name name,
   1.532                  List<Type> argtypes,
   1.533                  List<Type> typeargtypes) {
   1.534 -            if (currentResolutionContext.candidates.nonEmpty()) {
   1.535 +            if (!resolveContext.candidates.isEmpty()) {
   1.536                  JCDiagnostic err = diags.create(dkind,
   1.537                          log.currentSource(),
   1.538                          pos,
   1.539 @@ -2816,7 +3168,7 @@
   1.540          //where
   1.541          List<JCDiagnostic> candidateDetails(Type site) {
   1.542              List<JCDiagnostic> details = List.nil();
   1.543 -            for (Candidate c : currentResolutionContext.candidates) {
   1.544 +            for (Candidate c : resolveContext.candidates) {
   1.545                  if (!shouldReport(c)) continue;
   1.546                  JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
   1.547                          Kinds.kindName(c.sym),
   1.548 @@ -2829,7 +3181,7 @@
   1.549          }
   1.550  
   1.551          private Name getName() {
   1.552 -            Symbol sym = currentResolutionContext.candidates.head.sym;
   1.553 +            Symbol sym = resolveContext.candidates.head.sym;
   1.554              return sym.name == names.init ?
   1.555                  sym.owner.name :
   1.556                  sym.name;
   1.557 @@ -3023,6 +3375,7 @@
   1.558                     steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
   1.559                     sym.kind >= WRONG_MTHS) {
   1.560                  sym = resolutionCache.get(steps.head);
   1.561 +                if (sym.kind == ABSENT_MTH) break; //ignore spurious empty entries
   1.562                  bestSoFar = steps.head;
   1.563                  steps = steps.tail;
   1.564              }
   1.565 @@ -3031,8 +3384,7 @@
   1.566  
   1.567          void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
   1.568              Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
   1.569 -            if (!candidates.contains(c))
   1.570 -                candidates = candidates.append(c);
   1.571 +            candidates = candidates.append(c);
   1.572          }
   1.573  
   1.574          void addApplicableCandidate(Symbol sym, Type mtype) {
   1.575 @@ -3040,6 +3392,16 @@
   1.576              candidates = candidates.append(c);
   1.577          }
   1.578  
   1.579 +        Candidate getCandidate(Symbol sym, MethodResolutionPhase phase) {
   1.580 +            for (Candidate c : currentResolutionContext.candidates) {
   1.581 +                if (c.step == phase &&
   1.582 +                        c.sym.baseSymbol() == sym.baseSymbol()) {
   1.583 +                    return c;
   1.584 +                }
   1.585 +            }
   1.586 +            return null;
   1.587 +        }
   1.588 +
   1.589          /**
   1.590           * This class represents an overload resolution candidate. There are two
   1.591           * kinds of candidates: applicable methods and inapplicable methods;
   1.592 @@ -3067,9 +3429,9 @@
   1.593                      Symbol s1 = this.sym;
   1.594                      Symbol s2 = ((Candidate)o).sym;
   1.595                      if  ((s1 != s2 &&
   1.596 -                        (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
   1.597 -                        (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
   1.598 -                        ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
   1.599 +                            (s1.overrides(s2, s1.owner.type.tsym, types, false) ||
   1.600 +                            (s2.overrides(s1, s2.owner.type.tsym, types, false)))) ||
   1.601 +                            ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner))
   1.602                          return true;
   1.603                  }
   1.604                  return false;

mercurial