method references: do not prefer varargs from first search (IDEA-182018)

This commit is contained in:
Anna.Kozlova
2017-11-13 16:29:20 +01:00
parent 5758bb4185
commit e67bf2488b
3 changed files with 39 additions and 8 deletions

View File

@@ -271,12 +271,14 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
}
}
if (resolveConflicts(firstCandidates, secondCandidates, MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY)) {
return !firstCandidates.isEmpty() ? firstCandidates.get(0) : secondCandidates.get(0);
CandidateInfo candidateInfo = resolveConflicts(firstCandidates, secondCandidates, MethodCandidateInfo.ApplicabilityLevel.FIXED_ARITY);
if (candidateInfo != null) {
return candidateInfo;
}
if (resolveConflicts(firstCandidates, secondCandidates, MethodCandidateInfo.ApplicabilityLevel.VARARGS)) {
return !firstCandidates.isEmpty() ? firstCandidates.get(0) : secondCandidates.get(0);
candidateInfo = resolveConflicts(firstCandidates, secondCandidates, MethodCandidateInfo.ApplicabilityLevel.VARARGS);
if (candidateInfo != null) {
return candidateInfo;
}
if (firstCandidates.isEmpty() && secondCandidates.isEmpty()) {
@@ -356,7 +358,7 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
}
}
private boolean resolveConflicts(List<CandidateInfo> firstCandidates, List<CandidateInfo> secondCandidates, int applicabilityLevel) {
private CandidateInfo resolveConflicts(List<CandidateInfo> firstCandidates, List<CandidateInfo> secondCandidates, int applicabilityLevel) {
final int firstApplicability = checkApplicability(firstCandidates);
checkSpecifics(firstCandidates, applicabilityLevel, myLanguageLevel);
@@ -365,14 +367,18 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR
checkSpecifics(secondCandidates, applicabilityLevel, myLanguageLevel);
if (firstApplicability < secondApplicability) {
return secondCandidates.size() == 1;
return secondCandidates.size() == 1 ? secondCandidates.get(0) : null;
}
if (secondApplicability < firstApplicability) {
return firstCandidates.size() == 1;
return firstCandidates.size() == 1 ? firstCandidates.get(0) : null;
}
return firstCandidates.size() + secondCandidates.size() == 1;
return firstCandidates.size() + secondCandidates.size() == 1
? firstCandidates.isEmpty()
? secondCandidates.get(0)
: firstCandidates.get(0)
: null;
}
@Override

View File

@@ -0,0 +1,24 @@
import java.util.function.BinaryOperator;
class Test {
static class Base<T> {
Child<T> prepend(Child<T> other) {
return null;
}
}
static class Child<T> extends Base<T> {
@SafeVarargs
final Child<T> prepend(T... args) {
return this;
}
Child<T> prepend(T arg) {
return this;
}
}
public static void main(String[] args) {
BinaryOperator<Child<String>> prepend = Child::prepend;
}
}

View File

@@ -178,6 +178,7 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testWildcardInCheckedCompatibilityConstraints() { doTest(); }
public void testConstructorReferenceWithVarargsParameters() { doTest(); }
public void testMethodReferenceSwallowedErrors() { doTest(); }
public void testConflictingVarargsFromFirstSearchWithNArityOfTheSecondSearch() { doTest(); }
public void testPreferErrorOnTopLevelToFailedSubstitutorOnNestedLevel() { doTest(); }