From 9b4cacf341f30b849cc5dad26d376cadeeddeac4 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 12 Dec 2014 15:49:08 +0100 Subject: [PATCH] functional interface suggester: check return types and try to infer --- .../FunctionalInterfaceSuggester.java | 18 +++++++++++++---- .../afterFunction.java | 20 +++++++++++++++++++ .../afterIntPredicateConditionalExit.java | 10 +++++----- .../beforeFunction.java | 13 ++++++++++++ ...RefNotInContextInferredNonExact.after.java | 2 +- ...MethodRefNotInContextInferredNonExact.java | 2 +- .../IntroduceFunctionalParameterTest.java | 4 ++++ 7 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 java/java-tests/testData/refactoring/introduceFunctionalParameter/afterFunction.java create mode 100644 java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeFunction.java diff --git a/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java b/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java index 101af8d94fb2..72eecb222d6f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java +++ b/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java @@ -93,14 +93,17 @@ public class FunctionalInterfaceSuggester { return null; } - final PsiType[] left = new PsiType[parameters.length]; - final PsiType[] right = new PsiType[parameters.length]; + final PsiType[] left = new PsiType[parameters.length + 1]; + final PsiType[] right = new PsiType[parameters.length + 1]; for (int i = 0; i < parameters.length; i++) { left[i] = interfaceMethodParameters[i].getType(); right[i] = parameters[i].getType(); } + left[parameters.length] = method.getReturnType(); + right[parameters.length] = interfaceMethod.getReturnType(); + final PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); final PsiSubstitutor substitutor = PsiResolveHelper.SERVICE.getInstance(aClass.getProject()) .inferTypeArguments(typeParameters, left, right, PsiUtil.getLanguageLevel(method)); @@ -203,15 +206,19 @@ public class FunctionalInterfaceSuggester { final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters(); PsiParameter[] functionalExprParameters; int offset = 0; - final PsiType[] left = new PsiType[parameters.length]; - final PsiType[] right = new PsiType[parameters.length]; + final PsiType[] left; + final PsiType[] right; if (expression instanceof PsiLambdaExpression && ((PsiLambdaExpression)expression).hasFormalParameterTypes()) { + left = new PsiType[parameters.length]; + right = new PsiType[parameters.length]; functionalExprParameters = ((PsiLambdaExpression)expression).getParameterList().getParameters(); if (parameters.length != functionalExprParameters.length) { return null; } } else if (expression instanceof PsiMethodReferenceExpression) { + left = new PsiType[parameters.length + 1]; + right = new PsiType[parameters.length + 1]; final PsiMethod method = getTargetMethod((PsiMethodReferenceExpression)expression, qualifierType, parameters, left, right); if (method == null) { return null; @@ -220,6 +227,9 @@ public class FunctionalInterfaceSuggester { if (PsiMethodReferenceUtil.isStaticallyReferenced((PsiMethodReferenceExpression)expression) && !method.hasModifierProperty(PsiModifier.STATIC)) { offset = 1; } + + left[parameters.length] = method.getReturnType(); + right[parameters.length] = interfaceMethod.getReturnType(); } else { return null; } diff --git a/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterFunction.java b/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterFunction.java new file mode 100644 index 000000000000..29e6efac6d08 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterFunction.java @@ -0,0 +1,20 @@ +import java.util.function.Supplier; + +class Test { + void bar() { + foo(new Supplier() { + public String get() { + String s = ""; + System.out.println(s); + return s; + } + }); + } + + void foo(Supplier anObject) { + + String s = anObject.get(); + + System.out.println(s); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterIntPredicateConditionalExit.java b/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterIntPredicateConditionalExit.java index 656f25bb31df..8348efde3bd6 100644 --- a/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterIntPredicateConditionalExit.java +++ b/java/java-tests/testData/refactoring/introduceFunctionalParameter/afterIntPredicateConditionalExit.java @@ -1,9 +1,9 @@ -import java.util.function.IntPredicate; +import java.util.function.Function; class Test { void bar() { - foo(1, new IntPredicate() { - public boolean test(int i) { + foo(1, new Function() { + public boolean apply(Integer i) { if (i > 0) { System.out.println(i); System.out.println(i); @@ -14,9 +14,9 @@ class Test { }); } - void foo(int i, IntPredicate anObject) { + void foo(int i, Function anObject) { - if (anObject.test(i)) return; + if (anObject.apply(i)) return; System.out.println("Hi"); } diff --git a/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeFunction.java b/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeFunction.java new file mode 100644 index 000000000000..bce9cace9677 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceFunctionalParameter/beforeFunction.java @@ -0,0 +1,13 @@ +class Test { + void bar() { + foo(); + } + + void foo() { + + String s = ""; + System.out.println(s); + + System.out.println(s); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/MethodRefNotInContextInferredNonExact.after.java b/java/java-tests/testData/refactoring/introduceVariable/MethodRefNotInContextInferredNonExact.after.java index 437cacb0b83c..bae715372915 100644 --- a/java/java-tests/testData/refactoring/introduceVariable/MethodRefNotInContextInferredNonExact.after.java +++ b/java/java-tests/testData/refactoring/introduceVariable/MethodRefNotInContextInferredNonExact.after.java @@ -1,6 +1,6 @@ @FunctionalInterface interface I { - void foo(T t); + T foo(T t); } class Foo { diff --git a/java/java-tests/testData/refactoring/introduceVariable/MethodRefNotInContextInferredNonExact.java b/java/java-tests/testData/refactoring/introduceVariable/MethodRefNotInContextInferredNonExact.java index 19894d50d1c5..85bddf2f8e46 100644 --- a/java/java-tests/testData/refactoring/introduceVariable/MethodRefNotInContextInferredNonExact.java +++ b/java/java-tests/testData/refactoring/introduceVariable/MethodRefNotInContextInferredNonExact.java @@ -1,6 +1,6 @@ @FunctionalInterface interface I { - void foo(T t); + T foo(T t); } class Foo { diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java index 1bd71cfb4196..31c26e2ae2cd 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFunctionalParameterTest.java @@ -33,6 +33,10 @@ public class IntroduceFunctionalParameterTest extends LightRefactoringTestCase doTest(); } + public void testFunction() throws Exception { + doTest(); + } + public void testIntConsumerFromIfStatement() throws Exception { doTest(); }