diff --git a/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java b/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java index 5266cd713514..f378e513ea38 100644 --- a/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java +++ b/java/java-impl/src/com/intellij/codeInsight/FunctionalInterfaceSuggester.java @@ -200,19 +200,24 @@ public class FunctionalInterfaceSuggester { if (interfaceMethod != null) { final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters(); Project project = interface2Consider.getProject(); + PsiType returnType = interfaceMethod.getReturnType(); if (expression instanceof PsiLambdaExpression && ((PsiLambdaExpression)expression).hasFormalParameterTypes()) { PsiParameter[] functionalExprParameters = ((PsiLambdaExpression)expression).getParameterList().getParameters(); if (parameters.length != functionalExprParameters.length) { return Collections.emptyList(); } - 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 < functionalExprParameters.length; i++) { left[i] = parameters[i].getType(); right[i] = functionalExprParameters[i].getType(); } + List returnExpressions = LambdaUtil.getReturnExpressions(((PsiLambdaExpression)expression)); + left[parameters.length] = returnExpressions.isEmpty() ? PsiType.VOID : returnExpressions.get(0).getType(); + right[parameters.length] = returnType; + final PsiSubstitutor substitutor = PsiResolveHelper.SERVICE.getInstance(project) .inferTypeArguments(interface2Consider.getTypeParameters(), left, right, PsiUtil.getLanguageLevel(expression)); @@ -247,7 +252,7 @@ public class FunctionalInterfaceSuggester { } left[parameters.length] = method.isConstructor() ? qualifierType : method.getReturnType(); - right[parameters.length] = interfaceMethod.getReturnType(); + right[parameters.length] = returnType; final PsiSubstitutor substitutor = PsiResolveHelper.SERVICE.getInstance(project) .inferTypeArguments(interface2Consider.getTypeParameters(), left, right, PsiUtil.getLanguageLevel(expression)); diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/FunctionalInterfaceSuggesterTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/FunctionalInterfaceSuggesterTest.java index 85c7b3cc12bb..d8f1e9fc6051 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/FunctionalInterfaceSuggesterTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/FunctionalInterfaceSuggesterTest.java @@ -19,13 +19,13 @@ import com.intellij.codeInsight.FunctionalInterfaceSuggester; import com.intellij.psi.*; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.intellij.util.containers.ContainerUtil; import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.Collection; import java.util.List; -import java.util.stream.Collectors; public class FunctionalInterfaceSuggesterTest extends LightCodeInsightFixtureTestCase { @NotNull @@ -36,9 +36,8 @@ public class FunctionalInterfaceSuggesterTest extends LightCodeInsightFixtureTes public void testPrimitiveReturnTypes() { PsiClass aClass = myFixture.addClass("class Foo {double foo(double d) {return d;}}"); - List suggestedTypes = FunctionalInterfaceSuggester.suggestFunctionalInterfaces(aClass.getMethods()[0]).stream() - .map(PsiType::getCanonicalText) - .collect(Collectors.toList()); + List suggestedTypes = + ContainerUtil.map(FunctionalInterfaceSuggester.suggestFunctionalInterfaces(aClass.getMethods()[0]), PsiType::getCanonicalText); assertEquals(4, suggestedTypes.size()); assertTrue(suggestedTypes.containsAll(Arrays.asList("java.util.function.ToDoubleFunction", "java.util.function.Function", @@ -50,9 +49,8 @@ public class FunctionalInterfaceSuggesterTest extends LightCodeInsightFixtureTes PsiClass aClass = myFixture.addClass("class Foo {void foo(String s) {} void foo(int i) {}}"); PsiExpression expression = getElementFactory().createExpressionFromText("Foo::foo", aClass); assertInstanceOf(expression, PsiMethodReferenceExpression.class); - List suggestedTypes = FunctionalInterfaceSuggester.suggestFunctionalInterfaces((PsiFunctionalExpression)expression).stream() - .map(PsiType::getCanonicalText) - .collect(Collectors.toList()); + List suggestedTypes = ContainerUtil + .map(FunctionalInterfaceSuggester.suggestFunctionalInterfaces((PsiFunctionalExpression)expression), PsiType::getCanonicalText); assertEquals(3, suggestedTypes.size()); assertTrue(suggestedTypes.containsAll(Arrays.asList("java.util.function.BiConsumer", "java.util.function.BiConsumer", @@ -197,18 +195,16 @@ public class FunctionalInterfaceSuggesterTest extends LightCodeInsightFixtureTes public void testLambdaExpression() { PsiLambdaExpression expression = (PsiLambdaExpression)getElementFactory().createExpressionFromText("() -> 123", myFixture.addClass("class Empty{}")); checkWithExpected(FunctionalInterfaceSuggester.suggestFunctionalInterfaces(expression), + "java.util.concurrent.Callable", "java.util.function.DoubleSupplier", "java.util.function.IntSupplier", - "java.util.function.LongSupplier"); + "java.util.function.LongSupplier", + "java.util.function.Supplier"); } private static void checkWithExpected(Collection suggestedTypes, final String... expectedTypes) { - assertEquals(expectedTypes.length, suggestedTypes.size()); - List canonicalTextPresentation = suggestedTypes - .stream() - .map(PsiType::getCanonicalText) - .collect(Collectors.toList()); - assertTrue(canonicalTextPresentation.containsAll(Arrays.asList(expectedTypes))); + assertEquals("Suggested types: " + suggestedTypes.toString(), expectedTypes.length, suggestedTypes.size()); + assertTrue(ContainerUtil.map(suggestedTypes, PsiType::getCanonicalText).containsAll(Arrays.asList(expectedTypes))); } private Collection suggestTypes(@Language("JAVA") String fooClassText, String functionalExpressionText) {