mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 17:20:55 +07:00
method refs: testdata; varargs
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import java.util.*;
|
||||
class MyTest {
|
||||
|
||||
static void m(int i) {//here
|
||||
@@ -56,3 +57,141 @@ class MyTest2 {
|
||||
call<error descr="Cannot resolve method 'call(int, <method reference>)'">(1, MyTest2::m)</error>; //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<Integer> l1, List<Integer> l2);
|
||||
}
|
||||
|
||||
MyTest4 meth(List<Integer>... lli) { return null; }
|
||||
MyTest4(List<Integer>... lli) { }
|
||||
|
||||
I s1 = this::meth;
|
||||
I s2 = MyTest4::new;
|
||||
}
|
||||
|
||||
class MyTest5 {
|
||||
interface I_void<X> {
|
||||
void m();
|
||||
}
|
||||
|
||||
interface I_Void<X> {
|
||||
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> {
|
||||
R invoke();
|
||||
}
|
||||
|
||||
@interface A { }
|
||||
|
||||
static abstract class AC { }
|
||||
|
||||
enum E { }
|
||||
|
||||
void test() {
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest7.I'">I s1 = A::new;</error>
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest7.I'">I s2 = I::new;</error>
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest7.I'">I s3 = AC::new;</error>
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest7.I'">I s4 = E::new;</error>
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
<error descr="Incompatible types. Found: '<method reference>', required: 'MyTest8.Sub.I'">I var = Sub.Inner::new;</error>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MyTest9 {
|
||||
|
||||
static class SuperFoo<X> { }
|
||||
|
||||
static class Foo<X extends Number> extends SuperFoo<X> { }
|
||||
|
||||
interface I1 {
|
||||
void m();
|
||||
}
|
||||
|
||||
interface I2 {
|
||||
void m();
|
||||
}
|
||||
|
||||
static <X extends Number> Foo<X> m() { return null; }
|
||||
|
||||
static void g1(I1 s) { }
|
||||
static void g2(I1 s) { }
|
||||
static void g2(I2 s) { }
|
||||
|
||||
void test() {
|
||||
g1(MyTest9::m);
|
||||
g2<error descr="Ambiguous method call: both 'MyTest9.g2(I1)' and 'MyTest9.g2(I2)' match">(MyTest9::m)</error>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user