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;