diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/KotlinFunctionInsertHandler.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/KotlinFunctionInsertHandler.kt index 5e7e37b8b47..ca0ff0aa391 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/KotlinFunctionInsertHandler.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/handlers/KotlinFunctionInsertHandler.kt @@ -25,6 +25,7 @@ import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiElement import com.intellij.psi.codeStyle.CodeStyleSettingsManager +import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtTypeArgumentList @@ -73,10 +74,10 @@ sealed class KotlinFunctionInsertHandler : KotlinCallableInsertHandler() { val startOffset = context.startOffset val element = context.file.findElementAt(startOffset) ?: return - addArguments(context, element) + addArguments(context, element, item) } - private fun addArguments(context : InsertionContext, offsetElement : PsiElement) { + private fun addArguments(context: InsertionContext, offsetElement: PsiElement, item: LookupElement) { val completionChar = context.getCompletionChar() if (completionChar == '(') { //TODO: more correct behavior related to braces type context.setAddCompletionChar(false) @@ -122,6 +123,12 @@ sealed class KotlinFunctionInsertHandler : KotlinCallableInsertHandler() { offset += 2 } + // insert additional brackets for reserved syntax: "async {}" + if (insertLambda && (item.`object` as? DeclarationLookupObject)?.name?.identifier == "async") { + document.insertString(offset, "()") + offset += 2 + } + var openingBracketOffset = chars.indexOfSkippingSpace(openingBracket, offset) var closeBracketOffset = openingBracketOffset?.let { chars.indexOfSkippingSpace(closingBracket, it + 1) } var inBracketsShift = 0 diff --git a/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncSimple.kt b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncSimple.kt new file mode 100644 index 00000000000..d3aa295d015 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncSimple.kt @@ -0,0 +1,7 @@ +fun async(a: () -> Unit) {} + +fun test() { + asy +} + +// ELEMENT: async diff --git a/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncSimple.kt.after b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncSimple.kt.after new file mode 100644 index 00000000000..da8f6c27b6d --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncSimple.kt.after @@ -0,0 +1,7 @@ +fun async(a: () -> Unit) {} + +fun test() { + async() { } +} + +// ELEMENT: async diff --git a/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncWithoutLambda.kt b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncWithoutLambda.kt new file mode 100644 index 00000000000..061f41ec1b5 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncWithoutLambda.kt @@ -0,0 +1,7 @@ +fun async (p: Int, a: () -> Unit) {} + +fun test() { + asy +} + +// ELEMENT: async diff --git a/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncWithoutLambda.kt.after b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncWithoutLambda.kt.after new file mode 100644 index 00000000000..0f67c61514f --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncWithoutLambda.kt.after @@ -0,0 +1,7 @@ +fun async (p: Int, a: () -> Unit) {} + +fun test() { + async() +} + +// ELEMENT: async diff --git a/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync.kt b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync.kt new file mode 100644 index 00000000000..23812563eac --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync.kt @@ -0,0 +1,10 @@ +fun asyFoo(a: () -> Unit) {} + +fun async(a: () -> Unit) {} + +fun test() { + asyFoo { } +} + +// ELEMENT: async +// CHAR: '\t' \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync.kt.after b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync.kt.after new file mode 100644 index 00000000000..872816b85fd --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync.kt.after @@ -0,0 +1,10 @@ +fun asyFoo(a: () -> Unit) {} + +fun async(a: () -> Unit) {} + +fun test() { + async() { } +} + +// ELEMENT: async +// CHAR: '\t' \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync2.kt b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync2.kt new file mode 100644 index 00000000000..3a803cec1ad --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync2.kt @@ -0,0 +1,10 @@ +fun asyFoo(p: Int, a: () -> Unit) {} + +fun async(q: Int, a: () -> Unit) {} + +fun test() { + asyFoo(5) { } +} + +// ELEMENT: async +// CHAR: '\t' \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync2.kt.after b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync2.kt.after new file mode 100644 index 00000000000..4434077c803 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync2.kt.after @@ -0,0 +1,10 @@ +fun asyFoo(p: Int, a: () -> Unit) {} + +fun async(q: Int, a: () -> Unit) {} + +fun test() { + async(5) { } +} + +// ELEMENT: async +// CHAR: '\t' \ No newline at end of file diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java index 2170250f97b..8d1eb6a96de 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java @@ -378,6 +378,39 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/WithArgsNonEmptyLambdaAfter.kt"); doTest(fileName); } + + @TestMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Async extends AbstractBasicCompletionHandlerTest { + public void testAllFilesPresentInAsync() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("AsyncSimple.kt") + public void testAsyncSimple() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncSimple.kt"); + doTest(fileName); + } + + @TestMetadata("AsyncWithoutLambda.kt") + public void testAsyncWithoutLambda() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncWithoutLambda.kt"); + doTest(fileName); + } + + @TestMetadata("FromFooToAsync.kt") + public void testFromFooToAsync() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync.kt"); + doTest(fileName); + } + + @TestMetadata("FromFooToAsync2.kt") + public void testFromFooToAsync2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync2.kt"); + doTest(fileName); + } + } } @TestMetadata("idea/idea-completion/testData/handlers/basic/override")