From da4097f488b1472225a699c2be9b415bdda9660a Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Thu, 17 Oct 2019 12:58:41 +0300 Subject: [PATCH] KT-29926: Support completion of suspend lambda parameters in the body - `suspendLambdaSignature` directory is just a copy of `lambdaSignature` --- .../completion/smart/LambdaSignatureItems.kt | 4 ++-- .../NoAdditionalSpace.kt | 7 ++++++ .../NoAdditionalSpace.kt.after | 7 ++++++ .../smart/suspendLambdaSignature/Simple.kt | 7 ++++++ .../suspendLambdaSignature/Simple.kt.after | 7 ++++++ .../SuspendExplicitParameterTypesRequired.kt | 11 +++++++++ .../test/JvmSmartCompletionTestGenerated.java | 5 ++++ .../SmartCompletionHandlerTestGenerated.java | 23 +++++++++++++++++++ .../kotlin/idea/core/ExpectedInfos.kt | 5 ++-- ...ceSmartCompletionHandlerTestGenerated.java | 23 +++++++++++++++++++ 10 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/NoAdditionalSpace.kt create mode 100644 idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/NoAdditionalSpace.kt.after create mode 100644 idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/Simple.kt create mode 100644 idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/Simple.kt.after create mode 100644 idea/idea-completion/testData/smart/lambdaSignature/SuspendExplicitParameterTypesRequired.kt diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/LambdaSignatureItems.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/LambdaSignatureItems.kt index 69ab9401258..e8e4bd74ad3 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/LambdaSignatureItems.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/LambdaSignatureItems.kt @@ -20,7 +20,7 @@ import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType -import org.jetbrains.kotlin.builtins.isFunctionType +import org.jetbrains.kotlin.builtins.isFunctionOrSuspendFunctionType import org.jetbrains.kotlin.idea.completion.LambdaSignatureTemplates import org.jetbrains.kotlin.idea.completion.suppressAutoInsertion import org.jetbrains.kotlin.idea.core.ExpectedInfos @@ -48,7 +48,7 @@ object LambdaSignatureItems { val expectedFunctionTypes = ExpectedInfos(bindingContext, resolutionFacade, null).calculate(literalExpression) .mapNotNull { it.fuzzyType?.type } - .filter { it.isFunctionType } + .filter { it.isFunctionOrSuspendFunctionType } .toSet() for (functionType in expectedFunctionTypes) { if (functionType.getValueParameterTypesFromFunctionType().isEmpty()) continue diff --git a/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/NoAdditionalSpace.kt b/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/NoAdditionalSpace.kt new file mode 100644 index 00000000000..e17aeef00c3 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/NoAdditionalSpace.kt @@ -0,0 +1,7 @@ +fun foo(p: suspend (x: Char, String) -> Unit){} + +fun bar() { + foo { } +} + +// ELEMENT: "x, s ->" diff --git a/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/NoAdditionalSpace.kt.after b/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/NoAdditionalSpace.kt.after new file mode 100644 index 00000000000..8b8f681f845 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/NoAdditionalSpace.kt.after @@ -0,0 +1,7 @@ +fun foo(p: suspend (x: Char, String) -> Unit){} + +fun bar() { + foo { x, s -> } +} + +// ELEMENT: "x, s ->" diff --git a/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/Simple.kt b/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/Simple.kt new file mode 100644 index 00000000000..5a60d76e0ad --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/Simple.kt @@ -0,0 +1,7 @@ +fun foo(p: suspend (x: Char, String) -> Unit){} + +fun bar() { + foo { } +} + +// ELEMENT: "x, s ->" diff --git a/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/Simple.kt.after b/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/Simple.kt.after new file mode 100644 index 00000000000..8b8f681f845 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/Simple.kt.after @@ -0,0 +1,7 @@ +fun foo(p: suspend (x: Char, String) -> Unit){} + +fun bar() { + foo { x, s -> } +} + +// ELEMENT: "x, s ->" diff --git a/idea/idea-completion/testData/smart/lambdaSignature/SuspendExplicitParameterTypesRequired.kt b/idea/idea-completion/testData/smart/lambdaSignature/SuspendExplicitParameterTypesRequired.kt new file mode 100644 index 00000000000..3f429b9d997 --- /dev/null +++ b/idea/idea-completion/testData/smart/lambdaSignature/SuspendExplicitParameterTypesRequired.kt @@ -0,0 +1,11 @@ +fun foo(p: suspend (String, Int) -> Unit){} +fun foo(p: suspend Any.(Char, xx: Any) -> Unit){} + +fun bar() { + foo { } +} + +// EXIST: "String, Int ->" +// EXIST: "Char, xx ->" +// ABSENT: "s, i ->" +// ABSENT: "c, xx ->" diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java index 27f94f19ff7..a20cb5f3ebc 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java @@ -1330,6 +1330,11 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT public void testSingleParameter() throws Exception { runTest("idea/idea-completion/testData/smart/lambdaSignature/SingleParameter.kt"); } + + @TestMetadata("SuspendExplicitParameterTypesRequired.kt") + public void testSuspendExplicitParameterTypesRequired() throws Exception { + runTest("idea/idea-completion/testData/smart/lambdaSignature/SuspendExplicitParameterTypesRequired.kt"); + } } @TestMetadata("idea/idea-completion/testData/smart/multipleArgsItem") diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java index f921b62b71a..8352fd8e707 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java @@ -803,4 +803,27 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion runTest("idea/idea-completion/testData/handlers/smart/lambdaSignature/Simple.kt"); } } + + @TestMetadata("idea/idea-completion/testData/handlers/smart/suspendLambdaSignature") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SuspendLambdaSignature extends AbstractSmartCompletionHandlerTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInSuspendLambdaSignature() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/smart/suspendLambdaSignature"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("NoAdditionalSpace.kt") + public void testNoAdditionalSpace() throws Exception { + runTest("idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/NoAdditionalSpace.kt"); + } + + @TestMetadata("Simple.kt") + public void testSimple() throws Exception { + runTest("idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/Simple.kt"); + } + } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ExpectedInfos.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ExpectedInfos.kt index fff0f17c795..ec17814f0ab 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ExpectedInfos.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ExpectedInfos.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.core import com.intellij.openapi.util.text.StringUtil import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType +import org.jetbrains.kotlin.builtins.isFunctionOrSuspendFunctionType import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.resolve.ResolutionFacade @@ -375,7 +376,7 @@ class ExpectedInfos( if (alreadyHasStar) return if (isFunctionLiteralArgument) { - if (parameterType.isFunctionType) { + if (parameterType.isFunctionOrSuspendFunctionType) { add(ExpectedInfo.createForArgument(parameterType, expectedName, null, argumentPositionData)) } } @@ -504,7 +505,7 @@ class ExpectedInfos( val literalExpression = functionLiteral.parent as KtLambdaExpression calculate(literalExpression) .mapNotNull { it.fuzzyType } - .filter { it.type.isFunctionType } + .filter { it.type.isFunctionOrSuspendFunctionType } .map { val returnType = it.type.getReturnTypeFromFunctionType() ExpectedInfo(returnType.toFuzzyType(it.freeParameters), null, Tail.RBRACE) diff --git a/idea/performanceTests/org/jetbrains/kotlin/idea/perf/PerformanceSmartCompletionHandlerTestGenerated.java b/idea/performanceTests/org/jetbrains/kotlin/idea/perf/PerformanceSmartCompletionHandlerTestGenerated.java index 47849891783..e98c686b25b 100644 --- a/idea/performanceTests/org/jetbrains/kotlin/idea/perf/PerformanceSmartCompletionHandlerTestGenerated.java +++ b/idea/performanceTests/org/jetbrains/kotlin/idea/perf/PerformanceSmartCompletionHandlerTestGenerated.java @@ -803,4 +803,27 @@ public class PerformanceSmartCompletionHandlerTestGenerated extends AbstractPerf runTest("idea/idea-completion/testData/handlers/smart/lambdaSignature/Simple.kt"); } } + + @TestMetadata("idea/idea-completion/testData/handlers/smart/suspendLambdaSignature") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SuspendLambdaSignature extends AbstractPerformanceSmartCompletionHandlerTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doPerfTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInSuspendLambdaSignature() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/smart/suspendLambdaSignature"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("NoAdditionalSpace.kt") + public void testNoAdditionalSpace() throws Exception { + runTest("idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/NoAdditionalSpace.kt"); + } + + @TestMetadata("Simple.kt") + public void testSimple() throws Exception { + runTest("idea/idea-completion/testData/handlers/smart/suspendLambdaSignature/Simple.kt"); + } + } }