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);
+ }
+}