diff --git a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinSmartEnterHandler.kt b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinSmartEnterHandler.kt index 2b9f39b06a7..f319cad6d52 100644 --- a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinSmartEnterHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinSmartEnterHandler.kt @@ -54,7 +54,9 @@ class KotlinSmartEnterHandler: SmartEnterProcessorWithFixers() { KotlinTryBodyFixer(), KotlinCatchParameterFixer(), KotlinCatchBodyFixer(), - KotlinFinallyBodyFixer() + KotlinFinallyBodyFixer(), + + KotlinLastLambdaParameterFixer() ) addEnterProcessors(KotlinPlainEnterProcessor()) diff --git a/idea/src/org/jetbrains/kotlin/idea/editor/fixers/KotlinLastLambdaParameterFixer.kt b/idea/src/org/jetbrains/kotlin/idea/editor/fixers/KotlinLastLambdaParameterFixer.kt new file mode 100644 index 00000000000..ef8107f50c3 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/editor/fixers/KotlinLastLambdaParameterFixer.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.editor.fixers + +import com.intellij.lang.SmartEnterProcessorWithFixers +import com.intellij.openapi.editor.Editor +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.editor.KotlinSmartEnterHandler +import org.jetbrains.kotlin.psi.KtCallExpression +import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode + +class KotlinLastLambdaParameterFixer : SmartEnterProcessorWithFixers.Fixer() { + override fun apply(editor: Editor, processor: KotlinSmartEnterHandler, element: PsiElement) { + if (element !is KtCallExpression) return + + val bindingContext = element.analyze(BodyResolveMode.PARTIAL) + val resolvedCall = element.getResolvedCall(bindingContext) ?: return + + val valueParameters = resolvedCall.candidateDescriptor.valueParameters + + if (resolvedCall.valueArguments.size == valueParameters.size - 1) { + val type = valueParameters.last().type + if (KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(type)) { + val doc = editor.document + + var offset = element.endOffset + if (element.valueArgumentList?.rightParenthesis == null) { + doc.insertString(offset, ")") + offset++ + } + + doc.insertString(offset, "{ }") + processor.registerUnresolvedError(offset + 2) + processor.commit(editor) + } + } + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/smartEnter/SmartEnterTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/smartEnter/SmartEnterTest.kt index 761f5193d04..9a9f5bf3d2c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/smartEnter/SmartEnterTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/smartEnter/SmartEnterTest.kt @@ -1085,6 +1085,7 @@ class SmartEnterTest : KotlinLightCodeInsightFixtureTestCase() { } """ ) + fun testSetter6() = doFileTest( """ var a : Int = 0 @@ -1263,6 +1264,7 @@ class SmartEnterTest : KotlinLightCodeInsightFixtureTestCase() { } """ ) + fun testFinallyBody() = doFunTest( """ try { @@ -1279,6 +1281,42 @@ class SmartEnterTest : KotlinLightCodeInsightFixtureTestCase() { """ ) + fun testLambdaParam() = doFileTest( + """ + fun foo(a: Any, block: () -> Unit) { + } + fun test() { + foo(Any()) + } + """ + , + """ + fun foo(a: Any, block: () -> Unit) { + } + fun test() { + foo(Any()) { } + } + """ + ) + + fun testExtensionLambdaParam() = doFileTest( + """ + fun foo(a: Any, block: Any.() -> Unit) { + } + fun test() { + foo(Any()) + } + """ + , + """ + fun foo(a: Any, block: Any.() -> Unit) { + } + fun test() { + foo(Any()) { } + } + """ + ) + fun doFunTest(before: String, after: String) { fun String.withFunContext(): String { val bodyText = "//----\n${this.trimIndent()}\n//----"