From 9e0e3aaebb87c48da3da9fff47e79c4185d1fc1e Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 27 Nov 2015 16:13:18 +0300 Subject: [PATCH] Don't insert {} after 'else' and 'try' in infinished statements --- .../idea/editor/KotlinTypedHandler.java | 18 ++- .../kotlin/idea/editor/TypedHandlerTest.kt | 126 ++++++++++++++++-- 2 files changed, 130 insertions(+), 14 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinTypedHandler.java b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinTypedHandler.java index 129db9fa8f7..4449a093eae 100644 --- a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinTypedHandler.java +++ b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinTypedHandler.java @@ -52,8 +52,16 @@ import org.jetbrains.kotlin.psi.KtSimpleNameStringTemplateEntry; public class KotlinTypedHandler extends TypedHandlerDelegate { private final static TokenSet CONTROL_FLOW_EXPRESSIONS = TokenSet.create( KtNodeTypes.IF, + KtNodeTypes.ELSE, KtNodeTypes.FOR, - KtNodeTypes.WHILE); + KtNodeTypes.WHILE, + KtNodeTypes.TRY); + + private final static TokenSet SUPPRESS_AUTO_INSERT_CLOSE_BRACE_AFTER = TokenSet.create( + KtTokens.RPAR, + KtTokens.ELSE_KEYWORD, + KtTokens.TRY_KEYWORD + ); private boolean kotlinLTTyped; @@ -90,10 +98,12 @@ public class KotlinTypedHandler extends TypedHandlerDelegate { iterator.retreat(); } - if (iterator.atEnd() || iterator.getTokenType() != KtTokens.RPAR) { + if (iterator.atEnd() || !(SUPPRESS_AUTO_INSERT_CLOSE_BRACE_AFTER.contains(iterator.getTokenType()))) { return Result.CONTINUE; } + int tokenBeforeBraceOffset = iterator.getStart(); + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); PsiElement leaf = file.findElementAt(offset); @@ -101,9 +111,7 @@ public class KotlinTypedHandler extends TypedHandlerDelegate { PsiElement parent = leaf.getParent(); if (parent != null && CONTROL_FLOW_EXPRESSIONS.contains(parent.getNode().getElementType())) { ASTNode nonWhitespaceSibling = FormatterUtil.getPreviousNonWhitespaceSibling(leaf.getNode()); - if (nonWhitespaceSibling != null && nonWhitespaceSibling.getText().equals(")")) { - // Check that ')' belongs to same parent - + if (nonWhitespaceSibling != null && nonWhitespaceSibling.getStartOffset() == tokenBeforeBraceOffset) { EditorModificationUtil.insertStringAtCaret(editor, "{", false, true); indentBrace(project, editor, '{'); diff --git a/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt b/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt index 427eb33278e..57f8260b8e5 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt @@ -21,12 +21,12 @@ import com.intellij.testFramework.LightCodeInsightTestCase import com.intellij.testFramework.LightPlatformCodeInsightTestCase public class TypedHandlerTest : LightCodeInsightTestCase() { - val amp = '$' + val dollar = '$' public fun testTypeStringTemplateStart(): Unit = doCharTypeTest( '{', """val x = "$" """, - """val x = "$amp{}" """ + """val x = "$dollar{}" """ ) public fun testAutoIndentRightOpenBrace(): Unit = doCharTypeTest( @@ -56,19 +56,19 @@ public class TypedHandlerTest : LightCodeInsightTestCase() { public fun testTypeStringTemplateStartWithCloseBraceAfter(): Unit = doCharTypeTest( '{', """fun foo() { "$" }""", - """fun foo() { "$amp{}" }""" + """fun foo() { "$dollar{}" }""" ) public fun testTypeStringTemplateStartBeforeString(): Unit = doCharTypeTest( '{', """fun foo() { "$something" }""", - """fun foo() { "$amp{}something" }""" + """fun foo() { "$dollar{}something" }""" ) public fun testKT3575(): Unit = doCharTypeTest( '{', """val x = "$]" """, - """val x = "$amp{}]" """ + """val x = "$dollar{}]" """ ) public fun testAutoCloseBraceInFunctionDeclaration(): Unit = doCharTypeTest( @@ -112,6 +112,54 @@ public class TypedHandlerTest : LightCodeInsightTestCase() { "}" ) + public fun testDoNotAutoCloseBraceInUnfinishedElseSurroundOnSameLine(): Unit = doCharTypeTest( + '{', + + "fun foo() {\n" + + " if(true) {} else foo()\n" + + "}", + + "fun foo() {\n" + + " if(true) {} else {foo()\n" + + "}" + ) + + public fun testDoNotAutoCloseBraceInUnfinishedTryOnSameLine(): Unit = doCharTypeTest( + '{', + + "fun foo() {\n" + + " try foo()\n" + + "}", + + "fun foo() {\n" + + " try {foo()\n" + + "}" + ) + + public fun testDoNotAutoCloseBraceInUnfinishedCatchOnSameLine(): Unit = doCharTypeTest( + '{', + + "fun foo() {\n" + + " try {} catch (e: Exception) foo()\n" + + "}", + + "fun foo() {\n" + + " try {} catch (e: Exception) {foo()\n" + + "}" + ) + + public fun testDoNotAutoCloseBraceInUnfinishedFinallyOnSameLine(): Unit = doCharTypeTest( + '{', + + "fun foo() {\n" + + " try {} catch (e: Exception) finally foo()\n" + + "}", + + "fun foo() {\n" + + " try {} catch (e: Exception) finally {foo()\n" + + "}" + ) + public fun testDoNotAutoCloseBraceInUnfinishedWhileSurroundOnSameLine(): Unit = doCharTypeTest( '{', @@ -154,6 +202,34 @@ public class TypedHandlerTest : LightCodeInsightTestCase() { "}" ) + public fun testDoNotAutoCloseBraceInUnfinishedElseSurroundOnOtherLine(): Unit = doCharTypeTest( + '{', + + "fun foo() {\n" + + " if(true) {} else \n" + + " foo()\n" + + "}", + + "fun foo() {\n" + + " if(true) {} else {\n" + + " foo()\n" + + "}" + ) + + public fun testDoNotAutoCloseBraceInUnfinishedTryOnOtherLine(): Unit = doCharTypeTest( + '{', + + "fun foo() {\n" + + " try \n" + + " foo()\n" + + "}", + + "fun foo() {\n" + + " try {\n" + + " foo()\n" + + "}" + ) + public fun testDoNotAutoCloseBraceInUnfinishedIfSurroundOnNewLine(): Unit = doCharTypeTest( '{', @@ -170,6 +246,38 @@ public class TypedHandlerTest : LightCodeInsightTestCase() { "}" ) + public fun testDoNotAutoCloseBraceInUnfinishedElseSurroundOnNewLine(): Unit = doCharTypeTest( + '{', + + "fun foo() {\n" + + " if(true) {} else\n" + + " \n" + + " foo()\n" + + "}", + + "fun foo() {\n" + + " if(true) {} else\n" + + " {\n" + + " foo()\n" + + "}" + ) + + public fun testDoNotAutoCloseBraceInUnfinishedTryOnNewLine(): Unit = doCharTypeTest( + '{', + + "fun foo() {\n" + + " try\n" + + " \n" + + " foo()\n" + + "}", + + "fun foo() {\n" + + " try\n" + + " {\n" + + " foo()\n" + + "}" + ) + public fun testAutoCloseBraceInsideFor(): Unit = doCharTypeTest( '{', @@ -224,8 +332,8 @@ public class TypedHandlerTest : LightCodeInsightTestCase() { public fun testAutoInsertParenInStringLiteral(): Unit = doCharTypeTest( '(', - """fun f() { println("$amp{f}") }""", - """fun f() { println("$amp{f()}") }""" + """fun f() { println("$dollar{f}") }""", + """fun f() { println("$dollar{f()}") }""" ) public fun testAutoInsertParenInCode(): Unit = doCharTypeTest( @@ -257,9 +365,9 @@ public class TypedHandlerTest : LightCodeInsightTestCase() { public fun testSplitStringByEnter_BeforeSubstitution(): Unit = doCharTypeTest( '\n', - """val s = "foo${amp}bar"""", + """val s = "foo${dollar}bar"""", "val s = \"foo\" +\n" + - " \"${amp}bar\"" + " \"${dollar}bar\"" ) public fun testSplitStringByEnter_AddParentheses(): Unit = doCharTypeTest(