diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 3ace49a28cbd..e3d46f7c4b4f 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -575,7 +575,7 @@ public class LambdaUtil { final MethodSignature signature1 = method.getSignature(resolveResult.getSubstitutor()); final MethodSignature signature2 = ((PsiMethod)resolve).getSignature(substRef.get()); - if (areAcceptable(signature1, signature2, classRef.get(), substRef.get())) return true; + if (areAcceptable(signature1, signature2, classRef.get(), substRef.get(), ((PsiMethod)resolve).isVarArgs())) return true; } } return false; @@ -584,7 +584,8 @@ public class LambdaUtil { public static boolean areAcceptable(MethodSignature signature1, MethodSignature signature2, PsiClass psiClass, - PsiSubstitutor psiSubstitutor) { + PsiSubstitutor psiSubstitutor, + boolean isVarargs) { int offset = 0; final PsiType[] signatureParameterTypes1 = signature1.getParameterTypes(); final PsiType[] signatureParameterTypes2 = signature2.getParameterTypes(); @@ -596,7 +597,7 @@ public class LambdaUtil { (receiverType instanceof PsiClassType && ((PsiClassType)receiverType).isRaw() && receiverType.equals(TypeConversionUtil.erasure(classType)))) { offset++; } - else { + else if (!isVarargs){ return false; } } @@ -605,9 +606,10 @@ public class LambdaUtil { } } - for (int i = 0; i < signatureParameterTypes2.length; i++) { + final int min = Math.min(signatureParameterTypes2.length, signatureParameterTypes1.length); + for (int i = 0; i < min; i++) { final PsiType type1 = signatureParameterTypes1[offset + i]; - final PsiType type2 = signatureParameterTypes2[i]; + final PsiType type2 = isVarargs && i == min - 1 ? ((PsiArrayType)signatureParameterTypes2[i]).getComponentType() : signatureParameterTypes2[i]; if (!GenericsUtil.eliminateWildcards(psiSubstitutor.substitute(type1)).equals(GenericsUtil.eliminateWildcards(type2))) { return false; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java index fcce0708b871..3050e853c016 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java @@ -282,7 +282,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase PsiSubstitutor subst = PsiSubstitutor.EMPTY; subst = subst.putAll(mySubstitutor); if (!LambdaUtil.areAcceptable(mySignature, - psiMethod.getSignature(subst.putAll(conflict.getSubstitutor())), myContainingClass, mySubstitutor)) { + psiMethod.getSignature(subst.putAll(conflict.getSubstitutor())), myContainingClass, mySubstitutor, psiMethod.isVarArgs())) { iterator.remove(); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/MethodRefMisc1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/MethodRefMisc1.java index ccc0d159594f..a3434a67a5c9 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/MethodRefMisc1.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/MethodRefMisc1.java @@ -1,3 +1,4 @@ +import java.util.*; class MyTest { static void m(int i) {//here @@ -56,3 +57,141 @@ class MyTest2 { call(1, MyTest2::m); //ambiguous } } + +class MyTest3 { + interface I { + void m(); + } + + MyTest3() {} + + static void m() { } + + public static void main(String[] args) { + I s = new MyTest3()::m; + } +} + +class MyTest4 { + + interface I { + MyTest4 m(List l1, List l2); + } + + MyTest4 meth(List... lli) { return null; } + MyTest4(List... lli) { } + + I s1 = this::meth; + I s2 = MyTest4::new; +} + +class MyTest5 { + interface I_void { + void m(); + } + + interface I_Void { + void m(); + } + + static void m_void() {} + + static Void _Void() {return null; } + + public static void main(String[] args) { + I_void s1 = MyTest5::m_void; + s1.m(); + I_Void s2 = MyTest5::m_void; + s2.m(); + I_void s3 = MyTest5::_Void; + s3.m(); + I_Void s4 = MyTest5::_Void; + s4.m(); + } +} +class MyTest6 { + interface I { + MyTest6 invoke(); + } + + MyTest6() { + } + + static MyTest6 m() { + return null; + } + + public static void main(String[] args) { + I I1 = ((I)() -> {return null; })::invoke; + I1.invoke(); + I I2 = ((I)MyTest6::new)::invoke; + I1.invoke(); + I I3 = ((I)MyTest6::m)::invoke; + I1.invoke(); + } +} + +class MyTest7{ + + interface I { + R invoke(); + } + + @interface A { } + + static abstract class AC { } + + enum E { } + + void test() { + I s1 = A::new; + I s2 = I::new; + I s3 = AC::new; + I s4 = E::new; + } +} + +class MyTest8{ + + static class Sup {} + + + static class Sub extends Sup { + + interface I { Sup m(Sup x, String str); } + + class Inner extends Sup { + Inner(String val) { } + } + + void test() { + I var = Sub.Inner::new;; + } + } +} + +class MyTest9 { + + static class SuperFoo { } + + static class Foo extends SuperFoo { } + + interface I1 { + void m(); + } + + interface I2 { + void m(); + } + + static Foo m() { return null; } + + static void g1(I1 s) { } + static void g2(I1 s) { } + static void g2(I2 s) { } + + void test() { + g1(MyTest9::m); + g2(MyTest9::m); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java new file mode 100644 index 000000000000..9c8931dd9cc4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/Varargs.java @@ -0,0 +1,22 @@ +class MethodReference27 { + + interface SAM { + void m(int i1, int i2); + } + + static void m1(int i1, int i2) { } + static void m1(Integer i1, int i2) { } + static void m1(int i1, Integer i2) { } + static void m1(Integer i1, Integer i2) {} + static void m1(Integer... is) { } + + static void m2(int... is) { } + static void m2(double... ds) {} + + public static void main(String[] args) { + SAM s1 = MethodReference27::m1; + s1.m(42,42); + SAM s2 = MethodReference27 :: m2; + s2.m(42,42); + } +}