method refs: varargs in receiver position supported (IDEA-92711)

This commit is contained in:
anna
2012-10-10 13:06:58 +02:00
parent b929c5ad2f
commit 635ebe4e27
3 changed files with 40 additions and 2 deletions

View File

@@ -454,9 +454,15 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
if (hasReceiver && parameterTypes.length == signatureParameterTypes2.length + 1 && !staticOrValidConstructorRef) {
boolean correct = true;
for (int i = 0; i < signatureParameterTypes2.length; i++) {
final PsiType type1 = parameterTypes[i + 1];
final PsiType type1 = subst.substitute(GenericsUtil.eliminateWildcards(parameterTypes[i + 1]));
final PsiType type2 = signatureParameterTypes2[i];
correct &= TypeConversionUtil.isAssignable(type2, subst.substitute(GenericsUtil.eliminateWildcards(type1)));
final boolean assignable = TypeConversionUtil.isAssignable(type2, type1);
if (varArgs && i == signatureParameterTypes2.length - 1) {
correct &= assignable || TypeConversionUtil.isAssignable(((PsiArrayType)type2).getComponentType(), type1);
}
else {
correct &= assignable;
}
}
if (correct) {
secondCandidates.add(conflict);

View File

@@ -0,0 +1,28 @@
import java.util.*;
class Test {
void test() {
Comparator<Test> r2 = Test::yyy;
<error descr="Incompatible types. Found: '<method reference>', required: 'Comparator1<Test>'">Comparator1<Test> c1 = Test::yyy;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'Comparator1<Test>'">Comparator1<Test> c2 = Test::xxx;</error>
}
int yyy(Test... p) { return 1; }
int xxx(Test t) {return 42;}
}
interface Comparator1<T> {
int compare(T... o1);
}
class Test1 {
void test() {
Bar2 bar2 = Test1::yyy;
}
void yyy(Test1... p) {}
interface Bar2 {
public void xxx(Test1 p, Test1... ps);
}
}

View File

@@ -113,6 +113,10 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testVarargsInReceiverPosition() throws Exception {
doTest();
}
public void testInferenceFromReturnType() throws Exception {
doTest(true);
}