method refs: test data to check enum/interface/annotation not accepted; isAcceptable checks on Array types

This commit is contained in:
anna
2013-02-26 20:22:48 +01:00
parent f247ebba02
commit e48f61bf4d
4 changed files with 48 additions and 5 deletions

View File

@@ -163,16 +163,18 @@ public class PsiMethodReferenceUtil {
final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(left);
if (interfaceReturnType != null) {
if (interfaceReturnType == PsiType.VOID) return true;
if (onArrayType(((PsiClass)resolve), method.getSignature(PsiSubstitutor.EMPTY))) {
final PsiTypeParameter[] parameters = ((PsiClass)resolve).getTypeParameters();
if (parameters.length == 1) {
final PsiType arrayComponentType = result.getSubstitutor().substitute(parameters[0]);
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (resolve == JavaPsiFacade.getElementFactory(resolve.getProject()).getArrayClass(PsiUtil.getLanguageLevel(resolve))) {
if (parameters.length != 1 || parameters[0].getType() != PsiType.INT) return false;
final PsiTypeParameter[] typeParameters = ((PsiClass)resolve).getTypeParameters();
if (typeParameters.length == 1) {
final PsiType arrayComponentType = result.getSubstitutor().substitute(typeParameters[0]);
return arrayComponentType != null && TypeConversionUtil.isAssignable(interfaceReturnType, arrayComponentType.createArrayType(), true);
}
return false;
}
final PsiClassType classType = JavaPsiFacade.getElementFactory(methodReferenceExpression.getProject()).createType((PsiClass)resolve, result.getSubstitutor());
if (TypeConversionUtil.isAssignable(interfaceReturnType, classType, !((PsiClass)resolve).hasTypeParameters())) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length == 0) return true;
if (parameters.length == 1) {
if (isReceiverType(resolveResult.getSubstitutor().substitute(parameters[0].getType()), qualifierResolveResult.getContainingClass(), qualifierResolveResult.getSubstitutor())) return true;

View File

@@ -0,0 +1,29 @@
class Test {
interface IFactory {
Object m();
}
@interface Anno {}
enum E {}
interface I {}
static class Foo<X> { }
void foo(IFactory cf) { }
void testAssign() {
<error descr="Incompatible types. Found: '<method reference>', required: 'Test.IFactory'">IFactory c1 = Anno::new;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'Test.IFactory'">IFactory c2 = E::new;</error>
<error descr="Incompatible types. Found: '<method reference>', required: 'Test.IFactory'">IFactory c3 = I::new;</error>
IFactory c4 = Foo<?>::new;
IFactory c5 = <error descr="Cannot find class 1">1</error>::new;
foo<error descr="'foo(Test.IFactory)' in 'Test' cannot be applied to '(<method reference>)'">(Anno::new)</error>;
foo<error descr="'foo(Test.IFactory)' in 'Test' cannot be applied to '(<method reference>)'">(E::new)</error>;
foo<error descr="'foo(Test.IFactory)' in 'Test' cannot be applied to '(<method reference>)'">(I::new)</error>;
foo(Foo<?>::new);
foo(<error descr="Cannot find class 1">1</error>::new);
}
}

View File

@@ -25,6 +25,11 @@ class OnArrayTest {
T make(int size);
}
static class Foo<X> { }
interface ObjectArrayReturnType {
Object make(int size);
}
public static void main(String[] args) {
Cln s = int[]::clone;
IA a = int[]::new;
@@ -35,5 +40,8 @@ class OnArrayTest {
ArrayReturnType<String[]> a1 = String[]::new;
ArrayReturnType<String[][]> a2 = String[][]::new;
<error descr="Incompatible types. Found: '<method reference>', required: 'OnArrayTest.ArrayReturnType<java.lang.String[]>'">ArrayReturnType<String[]> a3 = int[]::new;</error>
ObjectArrayReturnType a4 = Foo<?>[]::new;
ObjectArrayReturnType a5 = Foo<? extends String>[]::new;
}
}

View File

@@ -204,6 +204,10 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testMethodRefAcceptance() throws Exception {
doTest();
}
private void doTest() throws Exception {
doTest(false);
}