new inference: accept all inexact refs during overload resolution

(cherry picked from commit c21ac7ada213c2de28b3e8e5aa15d3fde4490458)
This commit is contained in:
anna
2013-11-19 21:16:44 +01:00
parent a6c82625be
commit 12baf9a2bd
3 changed files with 82 additions and 2 deletions

View File

@@ -22,7 +22,6 @@ import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.RecursionGuard;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
@@ -100,9 +99,27 @@ public class MethodCandidateInfo extends CandidateInfo{
@ApplicabilityLevelConstant
public int getPertinentApplicabilityLevel() {
if (myTypeArguments != null) {
return getApplicabilityLevel();
}
final PsiMethod method = getElement();
if (method != null && method.hasTypeParameters() || myArgumentList == null || !PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) {
return getApplicabilityLevel();
@ApplicabilityLevelConstant int level;
if (myArgumentTypes == null) {
return ApplicabilityLevel.NOT_APPLICABLE;
}
else {
final PsiSubstitutor substitutor = getSubstitutor();
level = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() {
@Override
public Integer compute() {
return PsiUtil.getApplicabilityLevel(getElement(), substitutor, myArgumentTypes, myLanguageLevel);
}
});
}
if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable()) level = ApplicabilityLevel.NOT_APPLICABLE;
return level;
}
return ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable<Integer>() {
@Override

View File

@@ -0,0 +1,59 @@
class Test {
interface I0 {
void m();
}
interface I1<X> {
void m(X x);
}
interface I2<X,Y> {
void m(X x, Y y);
}
void m0() { }
void m1(String s) { }
void m2(String s1, String s2) { }
void m01() { }
void m01(String s) { }
void m012() { }
void m012(String s) { }
void m012(String s1, String s2) { }
static String instanceCall(I0 s) { return null; }
static <T> T instanceCall(I1<T> s) { return null; }
static <T> T instanceCall(I2<T, String> s) { return null; }
{
String i1 = instanceCall(this::m0);
String i2 = instanceCall(this::m1);
String i3 = instanceCall(this::m2);
String i4 = instanceCall<error descr="Ambiguous method call: both 'Test.instanceCall(I0)' and 'Test.instanceCall(I1<String>)' match">(this::m01)</error>;
String i5 = instanceCall<error descr="Ambiguous method call: both 'Test.instanceCall(I0)' and 'Test.instanceCall(I1<String>)' match">(this::m012)</error>;
}
void n0() { }
void n1(String s) { }
void n2(Test rec, String s2) { }
void n01() { }
void n01(String s) { }
void n012() { }
void n012(String s) { }
void n012(Test rec, String s2) { }
static <T> T staticCall(I1<T> s) { return null; }
static <T> T staticCall(I2<T, String> s) { return null; }
static {
Test s1 = staticCall(Test::n0);
Test s2 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<String & Test>)' and 'Test.staticCall(I2<Test,String>)' match">(Test::n1)</error>;
Test s3 = staticCall(<error descr="Non-static method cannot be referenced from a static context">Test::n2</error>);
Test s4 = staticCall<error descr="Ambiguous method call: both 'Test.staticCall(I1<Test>)' and 'Test.staticCall(I2<Test,String>)' match">(Test::n01)</error>;
Test s5 = staticCall<error descr="Cannot resolve method 'staticCall(<method reference>)'">(Test::n012)</error>;
}
}

View File

@@ -100,6 +100,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testPotentialApplicability() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}