1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Sun Nov 04 10:59:42 2012 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Sun Nov 04 11:01:49 2012 +0000 1.3 @@ -51,6 +51,8 @@ 1.4 import java.util.EnumMap; 1.5 import java.util.EnumSet; 1.6 import java.util.Iterator; 1.7 +import java.util.LinkedHashMap; 1.8 +import java.util.LinkedHashSet; 1.9 import java.util.Map; 1.10 import java.util.Set; 1.11 1.12 @@ -450,22 +452,9 @@ 1.13 List<Type> typeargtypes, 1.14 boolean allowBoxing, 1.15 boolean useVarargs, 1.16 - Warner warn) 1.17 - throws Infer.InferenceException { 1.18 - if (useVarargs && (m.flags() & VARARGS) == 0) { 1.19 - //better error recovery - if we stumbled upon a non-varargs method 1.20 - //during varargs applicability phase, the method should be treated as 1.21 - //not applicable; the reason for inapplicability can be found in the 1.22 - //candidate for 'm' that was created during the BOX phase. 1.23 - Candidate prevCandidate = currentResolutionContext.getCandidate(m, BOX); 1.24 - JCDiagnostic details = null; 1.25 - if (prevCandidate != null && !prevCandidate.isApplicable()) { 1.26 - details = prevCandidate.details; 1.27 - } 1.28 - throw inapplicableMethodException.setMessage(details); 1.29 - } 1.30 + Warner warn) throws Infer.InferenceException { 1.31 + 1.32 Type mt = types.memberType(site, m); 1.33 - 1.34 // tvars is the list of formal type variables for which type arguments 1.35 // need to inferred. 1.36 List<Type> tvars = List.nil(); 1.37 @@ -1023,8 +1012,11 @@ 1.38 boolean allowBoxing, 1.39 boolean useVarargs, 1.40 boolean operator) { 1.41 - if (sym.kind == ERR) return bestSoFar; 1.42 - if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar; 1.43 + if (sym.kind == ERR || 1.44 + !sym.isInheritedIn(site.tsym, types) || 1.45 + (useVarargs && (sym.flags() & VARARGS) == 0)) { 1.46 + return bestSoFar; 1.47 + } 1.48 Assert.check(sym.kind < AMBIGUOUS); 1.49 try { 1.50 Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes, 1.51 @@ -1035,13 +1027,13 @@ 1.52 if (!operator) 1.53 currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); 1.54 switch (bestSoFar.kind) { 1.55 - case ABSENT_MTH: 1.56 - return new InapplicableSymbolError(currentResolutionContext); 1.57 - case WRONG_MTH: 1.58 - if (operator) return bestSoFar; 1.59 - bestSoFar = new InapplicableSymbolsError(currentResolutionContext); 1.60 - default: 1.61 - return bestSoFar; 1.62 + case ABSENT_MTH: 1.63 + return new InapplicableSymbolError(currentResolutionContext); 1.64 + case WRONG_MTH: 1.65 + if (operator) return bestSoFar; 1.66 + bestSoFar = new InapplicableSymbolsError(currentResolutionContext); 1.67 + default: 1.68 + return bestSoFar; 1.69 } 1.70 } 1.71 if (!isAccessible(env, site, sym)) { 1.72 @@ -1330,7 +1322,7 @@ 1.73 } 1.74 } 1.75 1.76 - Symbol lookupMethod(Env<AttrContext> env, 1.77 + Symbol findMethodInScope(Env<AttrContext> env, 1.78 Type site, 1.79 Name name, 1.80 List<Type> argtypes, 1.81 @@ -1414,7 +1406,7 @@ 1.82 List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() }; 1.83 InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK; 1.84 for (TypeSymbol s : superclasses(intype)) { 1.85 - bestSoFar = lookupMethod(env, site, name, argtypes, typeargtypes, 1.86 + bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, 1.87 s.members(), bestSoFar, allowBoxing, useVarargs, operator, true); 1.88 if (name == names.init) return bestSoFar; 1.89 iphase = (iphase == null) ? null : iphase.update(s, this); 1.90 @@ -1436,7 +1428,7 @@ 1.91 if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure()) 1.92 if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && 1.93 (itype.tsym.flags() & DEFAULT) == 0) continue; 1.94 - bestSoFar = lookupMethod(env, site, name, argtypes, typeargtypes, 1.95 + bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes, 1.96 itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true); 1.97 if (concrete != bestSoFar && 1.98 concrete.kind < ERR && bestSoFar.kind < ERR && 1.99 @@ -1936,7 +1928,7 @@ 1.100 ((InapplicableSymbolError)errSym).errCandidate().sym : accessedSym; 1.101 1.102 List<Type> argtypes2 = Type.map(argtypes, 1.103 - deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, msym, currentResolutionContext.firstErroneousResolutionPhase())); 1.104 + deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, msym, currentResolutionContext.step)); 1.105 1.106 if (msym != accessedSym) { 1.107 //fixup deferred type caches - this 'hack' is required because the symbol 1.108 @@ -2030,33 +2022,14 @@ 1.109 Name name, 1.110 List<Type> argtypes, 1.111 List<Type> typeargtypes) { 1.112 - MethodResolutionContext prevResolutionContext = currentResolutionContext; 1.113 - try { 1.114 - currentResolutionContext = new MethodResolutionContext(); 1.115 - Symbol sym = methodNotFound; 1.116 - List<MethodResolutionPhase> steps = methodResolutionSteps; 1.117 - while (steps.nonEmpty() && 1.118 - steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1.119 - sym.kind >= ERRONEOUS) { 1.120 - currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head; 1.121 - sym = findFun(env, name, argtypes, typeargtypes, 1.122 - steps.head.isBoxingRequired, 1.123 - steps.head.isVarargsRequired); 1.124 - currentResolutionContext.resolutionCache.put(steps.head, sym); 1.125 - steps = steps.tail; 1.126 + return lookupMethod(env, pos, env.enclClass.sym, new BasicLookupHelper(name, env.enclClass.type, argtypes, typeargtypes) { 1.127 + @Override 1.128 + Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 1.129 + return findFun(env, name, argtypes, typeargtypes, 1.130 + phase.isBoxingRequired(), 1.131 + phase.isVarargsRequired()); 1.132 } 1.133 - if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error 1.134 - MethodResolutionPhase errPhase = 1.135 - currentResolutionContext.firstErroneousResolutionPhase(); 1.136 - sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase), 1.137 - pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes); 1.138 - env.info.pendingResolutionPhase = errPhase; 1.139 - } 1.140 - return sym; 1.141 - } 1.142 - finally { 1.143 - currentResolutionContext = prevResolutionContext; 1.144 - } 1.145 + }); 1.146 } 1.147 1.148 /** Resolve a qualified method identifier 1.149 @@ -2082,40 +2055,27 @@ 1.150 DiagnosticPosition pos, Env<AttrContext> env, 1.151 Symbol location, Type site, Name name, List<Type> argtypes, 1.152 List<Type> typeargtypes) { 1.153 - MethodResolutionContext prevResolutionContext = currentResolutionContext; 1.154 - try { 1.155 - currentResolutionContext = resolveContext; 1.156 - Symbol sym = methodNotFound; 1.157 - List<MethodResolutionPhase> steps = methodResolutionSteps; 1.158 - while (steps.nonEmpty() && 1.159 - steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1.160 - sym.kind >= ERRONEOUS) { 1.161 - currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head; 1.162 - sym = findMethod(env, site, name, argtypes, typeargtypes, 1.163 - steps.head.isBoxingRequired(), 1.164 - steps.head.isVarargsRequired(), false); 1.165 - currentResolutionContext.resolutionCache.put(steps.head, sym); 1.166 - steps = steps.tail; 1.167 + return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) { 1.168 + @Override 1.169 + Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 1.170 + return findMethod(env, site, name, argtypes, typeargtypes, 1.171 + phase.isBoxingRequired(), 1.172 + phase.isVarargsRequired(), false); 1.173 } 1.174 - if (sym.kind >= AMBIGUOUS) { 1.175 - //if nothing is found return the 'first' error 1.176 - MethodResolutionPhase errPhase = 1.177 - currentResolutionContext.firstErroneousResolutionPhase(); 1.178 - sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase), 1.179 - pos, location, site, name, true, argtypes, typeargtypes); 1.180 - env.info.pendingResolutionPhase = errPhase; 1.181 - } else if (allowMethodHandles) { 1.182 - MethodSymbol msym = (MethodSymbol)sym; 1.183 - if (msym.isSignaturePolymorphic(types)) { 1.184 - env.info.pendingResolutionPhase = BASIC; 1.185 - return findPolymorphicSignatureInstance(env, sym, argtypes); 1.186 + @Override 1.187 + Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 1.188 + if (sym.kind >= AMBIGUOUS) { 1.189 + sym = super.access(env, pos, location, sym); 1.190 + } else if (allowMethodHandles) { 1.191 + MethodSymbol msym = (MethodSymbol)sym; 1.192 + if (msym.isSignaturePolymorphic(types)) { 1.193 + env.info.pendingResolutionPhase = BASIC; 1.194 + return findPolymorphicSignatureInstance(env, sym, argtypes); 1.195 + } 1.196 } 1.197 + return sym; 1.198 } 1.199 - return sym; 1.200 - } 1.201 - finally { 1.202 - currentResolutionContext = prevResolutionContext; 1.203 - } 1.204 + }); 1.205 } 1.206 1.207 /** Find or create an implicit method of exactly the given type (after erasure). 1.208 @@ -2183,38 +2143,53 @@ 1.209 List<Type> typeargtypes) { 1.210 return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes); 1.211 } 1.212 + 1.213 private Symbol resolveConstructor(MethodResolutionContext resolveContext, 1.214 - DiagnosticPosition pos, 1.215 + final DiagnosticPosition pos, 1.216 Env<AttrContext> env, 1.217 Type site, 1.218 List<Type> argtypes, 1.219 List<Type> typeargtypes) { 1.220 - MethodResolutionContext prevResolutionContext = currentResolutionContext; 1.221 - try { 1.222 - currentResolutionContext = resolveContext; 1.223 - Symbol sym = methodNotFound; 1.224 - List<MethodResolutionPhase> steps = methodResolutionSteps; 1.225 - while (steps.nonEmpty() && 1.226 - steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1.227 - sym.kind >= ERRONEOUS) { 1.228 - currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head; 1.229 - sym = findConstructor(pos, env, site, argtypes, typeargtypes, 1.230 - steps.head.isBoxingRequired(), 1.231 - steps.head.isVarargsRequired()); 1.232 - currentResolutionContext.resolutionCache.put(steps.head, sym); 1.233 - steps = steps.tail; 1.234 + return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { 1.235 + @Override 1.236 + Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 1.237 + return findConstructor(pos, env, site, argtypes, typeargtypes, 1.238 + phase.isBoxingRequired(), 1.239 + phase.isVarargsRequired()); 1.240 } 1.241 - if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error 1.242 - MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase(); 1.243 - sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase), 1.244 - pos, site, names.init, true, argtypes, typeargtypes); 1.245 - env.info.pendingResolutionPhase = errPhase; 1.246 - } 1.247 - return sym; 1.248 - } 1.249 - finally { 1.250 - currentResolutionContext = prevResolutionContext; 1.251 - } 1.252 + }); 1.253 + } 1.254 + 1.255 + /** Resolve a constructor, throw a fatal error if not found. 1.256 + * @param pos The position to use for error reporting. 1.257 + * @param env The environment current at the method invocation. 1.258 + * @param site The type to be constructed. 1.259 + * @param argtypes The types of the invocation's value arguments. 1.260 + * @param typeargtypes The types of the invocation's type arguments. 1.261 + */ 1.262 + public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1.263 + Type site, 1.264 + List<Type> argtypes, 1.265 + List<Type> typeargtypes) { 1.266 + MethodResolutionContext resolveContext = new MethodResolutionContext(); 1.267 + resolveContext.internalResolution = true; 1.268 + Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes); 1.269 + if (sym.kind == MTH) return (MethodSymbol)sym; 1.270 + else throw new FatalError( 1.271 + diags.fragment("fatal.err.cant.locate.ctor", site)); 1.272 + } 1.273 + 1.274 + Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1.275 + Type site, List<Type> argtypes, 1.276 + List<Type> typeargtypes, 1.277 + boolean allowBoxing, 1.278 + boolean useVarargs) { 1.279 + Symbol sym = findMethod(env, site, 1.280 + names.init, argtypes, 1.281 + typeargtypes, allowBoxing, 1.282 + useVarargs, false); 1.283 + chk.checkDeprecated(pos, env.info.scope.owner, sym); 1.284 + return sym; 1.285 } 1.286 1.287 /** Resolve constructor using diamond inference. 1.288 @@ -2232,47 +2207,36 @@ 1.289 Type site, 1.290 List<Type> argtypes, 1.291 List<Type> typeargtypes) { 1.292 - MethodResolutionContext prevResolutionContext = currentResolutionContext; 1.293 - try { 1.294 - currentResolutionContext = new MethodResolutionContext(); 1.295 - Symbol sym = methodNotFound; 1.296 - List<MethodResolutionPhase> steps = methodResolutionSteps; 1.297 - while (steps.nonEmpty() && 1.298 - steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1.299 - sym.kind >= ERRONEOUS) { 1.300 - currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head; 1.301 - sym = findDiamond(env, site, argtypes, typeargtypes, 1.302 - steps.head.isBoxingRequired(), 1.303 - steps.head.isVarargsRequired()); 1.304 - currentResolutionContext.resolutionCache.put(steps.head, sym); 1.305 - steps = steps.tail; 1.306 + return lookupMethod(env, pos, site.tsym, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) { 1.307 + @Override 1.308 + Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 1.309 + return findDiamond(env, site, argtypes, typeargtypes, 1.310 + phase.isBoxingRequired(), 1.311 + phase.isVarargsRequired()); 1.312 } 1.313 - if (sym.kind >= AMBIGUOUS) { 1.314 - Symbol errSym = 1.315 - currentResolutionContext.resolutionCache.get(currentResolutionContext.firstErroneousResolutionPhase()); 1.316 - final JCDiagnostic details = errSym.kind == WRONG_MTH ? 1.317 - ((InapplicableSymbolError)errSym).errCandidate().details : 1.318 - null; 1.319 - errSym = new InapplicableSymbolError(errSym.kind, "diamondError", currentResolutionContext) { 1.320 - @Override 1.321 - JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, 1.322 - Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 1.323 - String key = details == null ? 1.324 - "cant.apply.diamond" : 1.325 - "cant.apply.diamond.1"; 1.326 - return diags.create(dkind, log.currentSource(), pos, key, 1.327 - diags.fragment("diamond", site.tsym), details); 1.328 - } 1.329 - }; 1.330 - MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase(); 1.331 - sym = accessMethod(errSym, pos, site, names.init, true, argtypes, typeargtypes); 1.332 - env.info.pendingResolutionPhase = errPhase; 1.333 + @Override 1.334 + Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 1.335 + if (sym.kind >= AMBIGUOUS) { 1.336 + final JCDiagnostic details = sym.kind == WRONG_MTH ? 1.337 + ((InapplicableSymbolError)sym).errCandidate().details : 1.338 + null; 1.339 + sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) { 1.340 + @Override 1.341 + JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, 1.342 + Symbol location, Type site, Name name, List<Type> argtypes, List<Type> typeargtypes) { 1.343 + String key = details == null ? 1.344 + "cant.apply.diamond" : 1.345 + "cant.apply.diamond.1"; 1.346 + return diags.create(dkind, log.currentSource(), pos, key, 1.347 + diags.fragment("diamond", site.tsym), details); 1.348 + } 1.349 + }; 1.350 + sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes); 1.351 + env.info.pendingResolutionPhase = currentResolutionContext.step; 1.352 + } 1.353 + return sym; 1.354 } 1.355 - return sym; 1.356 - } 1.357 - finally { 1.358 - currentResolutionContext = prevResolutionContext; 1.359 - } 1.360 + }); 1.361 } 1.362 1.363 /** This method scans all the constructor symbol in a given class scope - 1.364 @@ -2319,6 +2283,58 @@ 1.365 return bestSoFar; 1.366 } 1.367 1.368 + 1.369 + 1.370 + /** Resolve operator. 1.371 + * @param pos The position to use for error reporting. 1.372 + * @param optag The tag of the operation tree. 1.373 + * @param env The environment current at the operation. 1.374 + * @param argtypes The types of the operands. 1.375 + */ 1.376 + Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag, 1.377 + Env<AttrContext> env, List<Type> argtypes) { 1.378 + MethodResolutionContext prevResolutionContext = currentResolutionContext; 1.379 + try { 1.380 + currentResolutionContext = new MethodResolutionContext(); 1.381 + Name name = treeinfo.operatorName(optag); 1.382 + Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, 1.383 + null, false, false, true); 1.384 + if (boxingEnabled && sym.kind >= WRONG_MTHS) 1.385 + sym = findMethod(env, syms.predefClass.type, name, argtypes, 1.386 + null, true, false, true); 1.387 + return accessMethod(sym, pos, env.enclClass.sym.type, name, 1.388 + false, argtypes, null); 1.389 + } 1.390 + finally { 1.391 + currentResolutionContext = prevResolutionContext; 1.392 + } 1.393 + } 1.394 + 1.395 + /** Resolve operator. 1.396 + * @param pos The position to use for error reporting. 1.397 + * @param optag The tag of the operation tree. 1.398 + * @param env The environment current at the operation. 1.399 + * @param arg The type of the operand. 1.400 + */ 1.401 + Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) { 1.402 + return resolveOperator(pos, optag, env, List.of(arg)); 1.403 + } 1.404 + 1.405 + /** Resolve binary operator. 1.406 + * @param pos The position to use for error reporting. 1.407 + * @param optag The tag of the operation tree. 1.408 + * @param env The environment current at the operation. 1.409 + * @param left The types of the left operand. 1.410 + * @param right The types of the right operand. 1.411 + */ 1.412 + Symbol resolveBinaryOperator(DiagnosticPosition pos, 1.413 + JCTree.Tag optag, 1.414 + Env<AttrContext> env, 1.415 + Type left, 1.416 + Type right) { 1.417 + return resolveOperator(pos, optag, env, List.of(left, right)); 1.418 + } 1.419 + 1.420 /** 1.421 * Resolution of member references is typically done as a single 1.422 * overload resolution step, where the argument types A are inferred from 1.423 @@ -2352,17 +2368,18 @@ 1.424 Name name, List<Type> argtypes, 1.425 List<Type> typeargtypes, 1.426 boolean boxingAllowed) { 1.427 + MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC; 1.428 //step 1 - bound lookup 1.429 ReferenceLookupHelper boundLookupHelper = name.equals(names.init) ? 1.430 - new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, boxingAllowed) : 1.431 - new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, boxingAllowed); 1.432 + new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase) : 1.433 + new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase); 1.434 Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup()); 1.435 - Symbol boundSym = findMemberReference(boundEnv, boundLookupHelper); 1.436 + Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundLookupHelper); 1.437 1.438 //step 2 - unbound lookup 1.439 ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(); 1.440 Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup()); 1.441 - Symbol unboundSym = findMemberReference(unboundEnv, unboundLookupHelper); 1.442 + Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, unboundLookupHelper); 1.443 1.444 //merge results 1.445 Pair<Symbol, ReferenceLookupHelper> res; 1.446 @@ -2399,11 +2416,23 @@ 1.447 /** type arguments used during the lookup */ 1.448 List<Type> typeargtypes; 1.449 1.450 - LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) { 1.451 + /** Max overload resolution phase handled by this helper */ 1.452 + MethodResolutionPhase maxPhase; 1.453 + 1.454 + LookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 1.455 this.name = name; 1.456 this.site = site; 1.457 this.argtypes = argtypes; 1.458 this.typeargtypes = typeargtypes; 1.459 + this.maxPhase = maxPhase; 1.460 + } 1.461 + 1.462 + /** 1.463 + * Should lookup stop at given phase with given result 1.464 + */ 1.465 + protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) { 1.466 + return phase.ordinal() > maxPhase.ordinal() || 1.467 + sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS; 1.468 } 1.469 1.470 /** 1.471 @@ -2415,7 +2444,23 @@ 1.472 /** 1.473 * Validate the result of the lookup 1.474 */ 1.475 - abstract Symbol access(Env<AttrContext> env, Symbol symbol); 1.476 + abstract Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym); 1.477 + } 1.478 + 1.479 + abstract class BasicLookupHelper extends LookupHelper { 1.480 + 1.481 + BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) { 1.482 + super(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY); 1.483 + } 1.484 + 1.485 + @Override 1.486 + Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 1.487 + if (sym.kind >= AMBIGUOUS) { 1.488 + //if nothing is found return the 'first' error 1.489 + sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes); 1.490 + } 1.491 + return sym; 1.492 + } 1.493 } 1.494 1.495 /** 1.496 @@ -2429,14 +2474,11 @@ 1.497 /** The member reference tree */ 1.498 JCMemberReference referenceTree; 1.499 1.500 - /** Max overload resolution phase handled by this helper */ 1.501 - MethodResolutionPhase maxPhase; 1.502 - 1.503 ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 1.504 - List<Type> argtypes, List<Type> typeargtypes, boolean boxingAllowed) { 1.505 - super(name, site, argtypes, typeargtypes); 1.506 + List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 1.507 + super(name, site, argtypes, typeargtypes, maxPhase); 1.508 this.referenceTree = referenceTree; 1.509 - this.maxPhase = boxingAllowed ? VARARITY : BASIC; 1.510 + 1.511 } 1.512 1.513 /** 1.514 @@ -2445,13 +2487,13 @@ 1.515 */ 1.516 ReferenceLookupHelper unboundLookup() { 1.517 //dummy loopkup helper that always return 'methodNotFound' 1.518 - return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase.isBoxingRequired()) { 1.519 + return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) { 1.520 @Override 1.521 ReferenceLookupHelper unboundLookup() { 1.522 return this; 1.523 } 1.524 @Override 1.525 - Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase) { 1.526 + Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 1.527 return methodNotFound; 1.528 } 1.529 @Override 1.530 @@ -2467,23 +2509,8 @@ 1.531 */ 1.532 abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym); 1.533 1.534 - @Override 1.535 - Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 1.536 - return (env.info.pendingResolutionPhase.ordinal() > maxPhase.ordinal()) ? 1.537 - methodNotFound : lookupReference(env, phase); 1.538 - } 1.539 - 1.540 - abstract Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase); 1.541 - 1.542 - Symbol access(Env<AttrContext> env, Symbol sym) { 1.543 - if (sym.kind >= AMBIGUOUS) { 1.544 - MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase(); 1.545 - if (errPhase.ordinal() > maxPhase.ordinal()) { 1.546 - errPhase = maxPhase; 1.547 - } 1.548 - env.info.pendingResolutionPhase = errPhase; 1.549 - sym = currentResolutionContext.resolutionCache.get(errPhase); 1.550 - } 1.551 + Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 1.552 + //skip error reporting 1.553 return sym; 1.554 } 1.555 } 1.556 @@ -2497,8 +2524,8 @@ 1.557 class MethodReferenceLookupHelper extends ReferenceLookupHelper { 1.558 1.559 MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 1.560 - List<Type> argtypes, List<Type> typeargtypes, boolean boxingAllowed) { 1.561 - super(referenceTree, name, site, argtypes, typeargtypes, boxingAllowed); 1.562 + List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 1.563 + super(referenceTree, name, site, argtypes, typeargtypes, maxPhase); 1.564 } 1.565 1.566 protected Symbol lookupReferenceInternal(Env<AttrContext> env, MethodResolutionPhase phase) { 1.567 @@ -2513,7 +2540,7 @@ 1.568 } 1.569 1.570 @Override 1.571 - final Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase) { 1.572 + final Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 1.573 return adjustLookupResult(env, lookupReferenceInternal(env, phase)); 1.574 } 1.575 1.576 @@ -2523,7 +2550,7 @@ 1.577 argtypes.nonEmpty() && 1.578 types.isSubtypeUnchecked(argtypes.head, site)) { 1.579 return new UnboundMethodReferenceLookupHelper(referenceTree, name, 1.580 - site, argtypes, typeargtypes, maxPhase.isBoxingRequired()); 1.581 + site, argtypes, typeargtypes, maxPhase); 1.582 } else { 1.583 return super.unboundLookup(); 1.584 } 1.585 @@ -2553,10 +2580,10 @@ 1.586 class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper { 1.587 1.588 UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site, 1.589 - List<Type> argtypes, List<Type> typeargtypes, boolean boxingAllowed) { 1.590 + List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 1.591 super(referenceTree, name, 1.592 site.isRaw() ? types.asSuper(argtypes.head, site.tsym) : site, 1.593 - argtypes.tail, typeargtypes, boxingAllowed); 1.594 + argtypes.tail, typeargtypes, maxPhase); 1.595 } 1.596 1.597 @Override 1.598 @@ -2588,8 +2615,8 @@ 1.599 boolean needsInference; 1.600 1.601 ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List<Type> argtypes, 1.602 - List<Type> typeargtypes, boolean boxingAllowed) { 1.603 - super(referenceTree, names.init, site, argtypes, typeargtypes, boxingAllowed); 1.604 + List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 1.605 + super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase); 1.606 if (site.isRaw()) { 1.607 this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym); 1.608 needsInference = true; 1.609 @@ -2597,7 +2624,7 @@ 1.610 } 1.611 1.612 @Override 1.613 - protected Symbol lookupReference(Env<AttrContext> env, MethodResolutionPhase phase) { 1.614 + protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 1.615 Symbol sym = needsInference ? 1.616 findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) : 1.617 findMethod(env, site, name, argtypes, typeargtypes, 1.618 @@ -2622,140 +2649,36 @@ 1.619 } 1.620 1.621 /** 1.622 - * Resolution step for member reference. This generalizes a standard 1.623 - * method/constructor lookup - on each overload resolution step, a 1.624 - * lookup helper class is used to perform the reference lookup; at the end 1.625 - * of the lookup, the helper is used to validate the results. 1.626 + * Main overload resolution routine. On each overload resolution step, a 1.627 + * lookup helper class is used to perform the method/constructor lookup; 1.628 + * at the end of the lookup, the helper is used to validate the results 1.629 + * (this last step might trigger overload resolution diagnostics). 1.630 */ 1.631 - Symbol findMemberReference(Env<AttrContext> env, LookupHelper lookupHelper) { 1.632 + Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, LookupHelper lookupHelper) { 1.633 + return lookupMethod(env, pos, location, new MethodResolutionContext(), lookupHelper); 1.634 + } 1.635 + 1.636 + Symbol lookupMethod(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, 1.637 + MethodResolutionContext resolveContext, LookupHelper lookupHelper) { 1.638 MethodResolutionContext prevResolutionContext = currentResolutionContext; 1.639 try { 1.640 - currentResolutionContext = new MethodResolutionContext(); 1.641 - Symbol sym = methodNotFound; 1.642 - List<MethodResolutionPhase> steps = methodResolutionSteps; 1.643 - while (steps.nonEmpty() && 1.644 - steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1.645 - sym.kind >= ERRONEOUS) { 1.646 - currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head; 1.647 - sym = lookupHelper.lookup(env, steps.head); 1.648 - currentResolutionContext.resolutionCache.put(steps.head, sym); 1.649 - steps = steps.tail; 1.650 + Symbol bestSoFar = methodNotFound; 1.651 + currentResolutionContext = resolveContext; 1.652 + for (MethodResolutionPhase phase : methodResolutionSteps) { 1.653 + if (!phase.isApplicable(boxingEnabled, varargsEnabled) || 1.654 + lookupHelper.shouldStop(bestSoFar, phase)) break; 1.655 + MethodResolutionPhase prevPhase = currentResolutionContext.step; 1.656 + Symbol prevBest = bestSoFar; 1.657 + currentResolutionContext.step = phase; 1.658 + bestSoFar = phase.mergeResults(bestSoFar, lookupHelper.lookup(env, phase)); 1.659 + env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase; 1.660 } 1.661 - return lookupHelper.access(env, sym); 1.662 - } 1.663 - finally { 1.664 + return lookupHelper.access(env, pos, location, bestSoFar); 1.665 + } finally { 1.666 currentResolutionContext = prevResolutionContext; 1.667 } 1.668 } 1.669 1.670 - /** Resolve constructor. 1.671 - * @param pos The position to use for error reporting. 1.672 - * @param env The environment current at the constructor invocation. 1.673 - * @param site The type of class for which a constructor is searched. 1.674 - * @param argtypes The types of the constructor invocation's value 1.675 - * arguments. 1.676 - * @param typeargtypes The types of the constructor invocation's type 1.677 - * arguments. 1.678 - * @param allowBoxing Allow boxing and varargs conversions. 1.679 - * @param useVarargs Box trailing arguments into an array for varargs. 1.680 - */ 1.681 - Symbol resolveConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1.682 - Type site, List<Type> argtypes, 1.683 - List<Type> typeargtypes, 1.684 - boolean allowBoxing, 1.685 - boolean useVarargs) { 1.686 - MethodResolutionContext prevResolutionContext = currentResolutionContext; 1.687 - try { 1.688 - currentResolutionContext = new MethodResolutionContext(); 1.689 - return findConstructor(pos, env, site, argtypes, typeargtypes, allowBoxing, useVarargs); 1.690 - } 1.691 - finally { 1.692 - currentResolutionContext = prevResolutionContext; 1.693 - } 1.694 - } 1.695 - 1.696 - Symbol findConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1.697 - Type site, List<Type> argtypes, 1.698 - List<Type> typeargtypes, 1.699 - boolean allowBoxing, 1.700 - boolean useVarargs) { 1.701 - Symbol sym = findMethod(env, site, 1.702 - names.init, argtypes, 1.703 - typeargtypes, allowBoxing, 1.704 - useVarargs, false); 1.705 - chk.checkDeprecated(pos, env.info.scope.owner, sym); 1.706 - return sym; 1.707 - } 1.708 - 1.709 - /** Resolve a constructor, throw a fatal error if not found. 1.710 - * @param pos The position to use for error reporting. 1.711 - * @param env The environment current at the method invocation. 1.712 - * @param site The type to be constructed. 1.713 - * @param argtypes The types of the invocation's value arguments. 1.714 - * @param typeargtypes The types of the invocation's type arguments. 1.715 - */ 1.716 - public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env<AttrContext> env, 1.717 - Type site, 1.718 - List<Type> argtypes, 1.719 - List<Type> typeargtypes) { 1.720 - MethodResolutionContext resolveContext = new MethodResolutionContext(); 1.721 - resolveContext.internalResolution = true; 1.722 - Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes); 1.723 - if (sym.kind == MTH) return (MethodSymbol)sym; 1.724 - else throw new FatalError( 1.725 - diags.fragment("fatal.err.cant.locate.ctor", site)); 1.726 - } 1.727 - 1.728 - /** Resolve operator. 1.729 - * @param pos The position to use for error reporting. 1.730 - * @param optag The tag of the operation tree. 1.731 - * @param env The environment current at the operation. 1.732 - * @param argtypes The types of the operands. 1.733 - */ 1.734 - Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag, 1.735 - Env<AttrContext> env, List<Type> argtypes) { 1.736 - MethodResolutionContext prevResolutionContext = currentResolutionContext; 1.737 - try { 1.738 - currentResolutionContext = new MethodResolutionContext(); 1.739 - Name name = treeinfo.operatorName(optag); 1.740 - Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, 1.741 - null, false, false, true); 1.742 - if (boxingEnabled && sym.kind >= WRONG_MTHS) 1.743 - sym = findMethod(env, syms.predefClass.type, name, argtypes, 1.744 - null, true, false, true); 1.745 - return accessMethod(sym, pos, env.enclClass.sym.type, name, 1.746 - false, argtypes, null); 1.747 - } 1.748 - finally { 1.749 - currentResolutionContext = prevResolutionContext; 1.750 - } 1.751 - } 1.752 - 1.753 - /** Resolve operator. 1.754 - * @param pos The position to use for error reporting. 1.755 - * @param optag The tag of the operation tree. 1.756 - * @param env The environment current at the operation. 1.757 - * @param arg The type of the operand. 1.758 - */ 1.759 - Symbol resolveUnaryOperator(DiagnosticPosition pos, JCTree.Tag optag, Env<AttrContext> env, Type arg) { 1.760 - return resolveOperator(pos, optag, env, List.of(arg)); 1.761 - } 1.762 - 1.763 - /** Resolve binary operator. 1.764 - * @param pos The position to use for error reporting. 1.765 - * @param optag The tag of the operation tree. 1.766 - * @param env The environment current at the operation. 1.767 - * @param left The types of the left operand. 1.768 - * @param right The types of the right operand. 1.769 - */ 1.770 - Symbol resolveBinaryOperator(DiagnosticPosition pos, 1.771 - JCTree.Tag optag, 1.772 - Env<AttrContext> env, 1.773 - Type left, 1.774 - Type right) { 1.775 - return resolveOperator(pos, optag, env, List.of(left, right)); 1.776 - } 1.777 - 1.778 /** 1.779 * Resolve `c.name' where name == this or name == super. 1.780 * @param pos The position to use for error reporting. 1.781 @@ -3190,20 +3113,14 @@ 1.782 return types.createErrorType(name, location, syms.errSymbol.type).tsym; 1.783 } 1.784 1.785 - protected boolean shouldReport(Candidate c) { 1.786 - MethodResolutionPhase errPhase = resolveContext.firstErroneousResolutionPhase(); 1.787 - return !c.isApplicable() && 1.788 - c.step == errPhase; 1.789 - } 1.790 - 1.791 private Candidate errCandidate() { 1.792 + Candidate bestSoFar = null; 1.793 for (Candidate c : resolveContext.candidates) { 1.794 - if (shouldReport(c)) { 1.795 - return c; 1.796 - } 1.797 + if (c.isApplicable()) continue; 1.798 + bestSoFar = c; 1.799 } 1.800 - Assert.error(); 1.801 - return null; 1.802 + Assert.checkNonNull(bestSoFar); 1.803 + return bestSoFar; 1.804 } 1.805 } 1.806 1.807 @@ -3232,7 +3149,7 @@ 1.808 pos, 1.809 "cant.apply.symbols", 1.810 name == names.init ? KindName.CONSTRUCTOR : absentKind(kind), 1.811 - getName(), 1.812 + name == names.init ? site.tsym.name : name, 1.813 argtypes); 1.814 return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site)); 1.815 } else { 1.816 @@ -3243,24 +3160,17 @@ 1.817 1.818 //where 1.819 List<JCDiagnostic> candidateDetails(Type site) { 1.820 - List<JCDiagnostic> details = List.nil(); 1.821 + Map<Symbol, JCDiagnostic> details = new LinkedHashMap<Symbol, JCDiagnostic>(); 1.822 for (Candidate c : resolveContext.candidates) { 1.823 - if (!shouldReport(c)) continue; 1.824 + if (c.isApplicable()) continue; 1.825 JCDiagnostic detailDiag = diags.fragment("inapplicable.method", 1.826 Kinds.kindName(c.sym), 1.827 c.sym.location(site, types), 1.828 c.sym.asMemberOf(site, types), 1.829 c.details); 1.830 - details = details.prepend(detailDiag); 1.831 + details.put(c.sym, detailDiag); 1.832 } 1.833 - return details.reverse(); 1.834 - } 1.835 - 1.836 - private Name getName() { 1.837 - Symbol sym = resolveContext.candidates.head.sym; 1.838 - return sym.name == names.init ? 1.839 - sym.owner.name : 1.840 - sym.name; 1.841 + return List.from(details.values()); 1.842 } 1.843 } 1.844 1.845 @@ -3398,7 +3308,21 @@ 1.846 enum MethodResolutionPhase { 1.847 BASIC(false, false), 1.848 BOX(true, false), 1.849 - VARARITY(true, true); 1.850 + VARARITY(true, true) { 1.851 + @Override 1.852 + public Symbol mergeResults(Symbol bestSoFar, Symbol sym) { 1.853 + switch (sym.kind) { 1.854 + case WRONG_MTH: 1.855 + return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ? 1.856 + bestSoFar : 1.857 + sym; 1.858 + case ABSENT_MTH: 1.859 + return bestSoFar; 1.860 + default: 1.861 + return sym; 1.862 + } 1.863 + } 1.864 + }; 1.865 1.866 boolean isBoxingRequired; 1.867 boolean isVarargsRequired; 1.868 @@ -3420,6 +3344,10 @@ 1.869 return (varargsEnabled || !isVarargsRequired) && 1.870 (boxingEnabled || !isBoxingRequired); 1.871 } 1.872 + 1.873 + public Symbol mergeResults(Symbol prev, Symbol sym) { 1.874 + return sym; 1.875 + } 1.876 } 1.877 1.878 final List<MethodResolutionPhase> methodResolutionSteps = List.of(BASIC, BOX, VARARITY); 1.879 @@ -3435,29 +3363,11 @@ 1.880 1.881 private List<Candidate> candidates = List.nil(); 1.882 1.883 - private Map<MethodResolutionPhase, Symbol> resolutionCache = 1.884 - new EnumMap<MethodResolutionPhase, Symbol>(MethodResolutionPhase.class); 1.885 - 1.886 MethodResolutionPhase step = null; 1.887 1.888 private boolean internalResolution = false; 1.889 private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE; 1.890 1.891 - private MethodResolutionPhase firstErroneousResolutionPhase() { 1.892 - MethodResolutionPhase bestSoFar = BASIC; 1.893 - Symbol sym = methodNotFound; 1.894 - List<MethodResolutionPhase> steps = methodResolutionSteps; 1.895 - while (steps.nonEmpty() && 1.896 - steps.head.isApplicable(boxingEnabled, varargsEnabled) && 1.897 - sym.kind >= WRONG_MTHS) { 1.898 - sym = resolutionCache.get(steps.head); 1.899 - if (sym.kind == ABSENT_MTH) break; //ignore spurious empty entries 1.900 - bestSoFar = steps.head; 1.901 - steps = steps.tail; 1.902 - } 1.903 - return bestSoFar; 1.904 - } 1.905 - 1.906 void addInapplicableCandidate(Symbol sym, JCDiagnostic details) { 1.907 Candidate c = new Candidate(currentResolutionContext.step, sym, details, null); 1.908 candidates = candidates.append(c); 1.909 @@ -3468,16 +3378,6 @@ 1.910 candidates = candidates.append(c); 1.911 } 1.912 1.913 - Candidate getCandidate(Symbol sym, MethodResolutionPhase phase) { 1.914 - for (Candidate c : currentResolutionContext.candidates) { 1.915 - if (c.step == phase && 1.916 - c.sym.baseSymbol() == sym.baseSymbol()) { 1.917 - return c; 1.918 - } 1.919 - } 1.920 - return null; 1.921 - } 1.922 - 1.923 /** 1.924 * This class represents an overload resolution candidate. There are two 1.925 * kinds of candidates: applicable methods and inapplicable methods;