KT-29926: Support completion of suspend lambda parameters in the body

- `suspendLambdaSignature` directory is just a copy of `lambdaSignature`
This commit is contained in:
Roman Golyshev
2019-10-17 12:58:41 +03:00
committed by Roman Golyshev
parent 84b9044187
commit da4097f488
10 changed files with 95 additions and 4 deletions
@@ -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
@@ -0,0 +1,7 @@
fun foo(p: suspend (x: Char, String) -> Unit){}
fun bar() {
foo { <caret> }
}
// ELEMENT: "x, s ->"
@@ -0,0 +1,7 @@
fun foo(p: suspend (x: Char, String) -> Unit){}
fun bar() {
foo { x, s -> <caret> }
}
// ELEMENT: "x, s ->"
@@ -0,0 +1,7 @@
fun foo(p: suspend (x: Char, String) -> Unit){}
fun bar() {
foo { <caret>}
}
// ELEMENT: "x, s ->"
@@ -0,0 +1,7 @@
fun foo(p: suspend (x: Char, String) -> Unit){}
fun bar() {
foo { x, s -> <caret> }
}
// ELEMENT: "x, s ->"
@@ -0,0 +1,11 @@
fun foo(p: suspend (String, Int) -> Unit){}
fun foo(p: suspend Any.(Char, xx: Any) -> Unit){}
fun bar() {
foo { <caret> }
}
// EXIST: "String, Int ->"
// EXIST: "Char, xx ->"
// ABSENT: "s, i ->"
// ABSENT: "c, xx ->"
@@ -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")
@@ -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");
}
}
}
@@ -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)
@@ -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");
}
}
}