Implement smart enter processors for try, catch (parameters and body) and finally with tests
Fixes #KT-10013
This commit is contained in:
@@ -49,7 +49,12 @@ class KotlinSmartEnterHandler: SmartEnterProcessorWithFixers() {
|
|||||||
KotlinFunctionDeclarationBodyFixer(),
|
KotlinFunctionDeclarationBodyFixer(),
|
||||||
|
|
||||||
KotlinPropertySetterParametersFixer(),
|
KotlinPropertySetterParametersFixer(),
|
||||||
KotlinPropertySetterBodyFixer()
|
KotlinPropertySetterBodyFixer(),
|
||||||
|
|
||||||
|
KotlinTryBodyFixer(),
|
||||||
|
KotlinCatchParameterFixer(),
|
||||||
|
KotlinCatchBodyFixer(),
|
||||||
|
KotlinFinallyBodyFixer()
|
||||||
)
|
)
|
||||||
|
|
||||||
addEnterProcessors(KotlinPlainEnterProcessor())
|
addEnterProcessors(KotlinPlainEnterProcessor())
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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.idea.editor.KotlinSmartEnterHandler
|
||||||
|
import org.jetbrains.kotlin.psi.KtCatchClause
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
|
|
||||||
|
class KotlinCatchBodyFixer : SmartEnterProcessorWithFixers.Fixer<KotlinSmartEnterHandler>() {
|
||||||
|
override fun apply(editor: Editor, processor: KotlinSmartEnterHandler, psiElement: PsiElement) {
|
||||||
|
if (psiElement !is KtCatchClause) return
|
||||||
|
|
||||||
|
if (psiElement.catchBody == null) {
|
||||||
|
editor.document.insertString(psiElement.endOffset, "{}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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.idea.editor.KotlinSmartEnterHandler
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi.KtCatchClause
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
|
||||||
|
class KotlinCatchParameterFixer : SmartEnterProcessorWithFixers.Fixer<KotlinSmartEnterHandler>() {
|
||||||
|
override fun apply(editor: Editor, processor: KotlinSmartEnterHandler, psiElement: PsiElement) {
|
||||||
|
if (psiElement !is KtCatchClause) return
|
||||||
|
|
||||||
|
val catchEnd = psiElement.node.findChildByType(KtTokens.CATCH_KEYWORD)!!.textRange!!.endOffset
|
||||||
|
|
||||||
|
val parameterList = psiElement.parameterList
|
||||||
|
if (parameterList == null || parameterList.node.findChildByType(KtTokens.RPAR) == null) {
|
||||||
|
val endOffset = Math.min(psiElement.endOffset, psiElement.catchBody?.startOffset ?: Int.MAX_VALUE)
|
||||||
|
val parameter = parameterList?.parameters?.firstOrNull()?.text ?: ""
|
||||||
|
editor.document.replaceString(catchEnd, endOffset, "($parameter)")
|
||||||
|
processor.registerUnresolvedError(endOffset - 1)
|
||||||
|
}
|
||||||
|
else if (parameterList.parameters.firstOrNull()?.text.isNullOrBlank()) {
|
||||||
|
processor.registerUnresolvedError(parameterList.startOffset + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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.idea.editor.KotlinSmartEnterHandler
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi.KtFinallySection
|
||||||
|
|
||||||
|
class KotlinFinallyBodyFixer : SmartEnterProcessorWithFixers.Fixer<KotlinSmartEnterHandler>() {
|
||||||
|
override fun apply(editor: Editor, processor: KotlinSmartEnterHandler, psiElement: PsiElement) {
|
||||||
|
if (psiElement !is KtFinallySection) return
|
||||||
|
|
||||||
|
if (!psiElement.finalExpression.text.startsWith('{')) {
|
||||||
|
editor.document.insertString(psiElement.node.findChildByType(KtTokens.FINALLY_KEYWORD)!!.textRange.end, "{}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.idea.editor.KotlinSmartEnterHandler
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi.KtTryExpression
|
||||||
|
|
||||||
|
class KotlinTryBodyFixer : SmartEnterProcessorWithFixers.Fixer<KotlinSmartEnterHandler>() {
|
||||||
|
override fun apply(editor: Editor, processor: KotlinSmartEnterHandler, psiElement: PsiElement) {
|
||||||
|
if (psiElement !is KtTryExpression) return
|
||||||
|
|
||||||
|
if (psiElement.tryBlock.lBrace == null) {
|
||||||
|
val offset = psiElement.node.findChildByType(KtTokens.TRY_KEYWORD)?.textRange?.endOffset ?: return
|
||||||
|
editor.document.insertString(offset, "{}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1185,12 +1185,106 @@ class SmartEnterTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun testTryBody() = doFunTest(
|
||||||
|
"""
|
||||||
|
try<caret>
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testCatchBody() = doFunTest(
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(e: Exception) <caret>
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(e: Exception) {
|
||||||
|
<caret>
|
||||||
|
}${" "}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testCatchParameter1() = doFunTest(
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch<caret>
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(<caret>) {
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testCatchParameter2() = doFunTest(
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(<caret>
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(<caret>) {
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testCatchParameter3() = doFunTest(
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(<caret> {}
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(<caret>) {
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
fun testCatchParameter4() = doFunTest(
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(e: Exception<caret>
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(e: Exception) {
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
fun testFinallyBody() = doFunTest(
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(e: Exception) {
|
||||||
|
} finally<caret>
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
"""
|
||||||
|
try {
|
||||||
|
} catch(e: Exception) {
|
||||||
|
} finally {
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
fun doFunTest(before: String, after: String) {
|
fun doFunTest(before: String, after: String) {
|
||||||
fun String.withFunContext(): String {
|
fun String.withFunContext(): String {
|
||||||
val bodyText = "//----\n${this.trimIndent()}\n//----"
|
val bodyText = "//----\n${this.trimIndent()}\n//----"
|
||||||
val withIndent = bodyText.prependIndent(" ")
|
val withIndent = bodyText.prependIndent(" ")
|
||||||
|
|
||||||
return "fun method() {\n${withIndent}\n}"
|
return "fun method() {\n$withIndent\n}"
|
||||||
}
|
}
|
||||||
|
|
||||||
doTest(before.withFunContext(), after.withFunContext())
|
doTest(before.withFunContext(), after.withFunContext())
|
||||||
|
|||||||
Reference in New Issue
Block a user