Implement EnterBetweenBracesAndBracketsNoCommitDelegate

Part of #KT-22211
Part of #KT-39353
This commit is contained in:
Dmitry Gridin
2020-06-03 21:58:24 +07:00
parent e72fb755a0
commit 7a58a59114
15 changed files with 118 additions and 46 deletions
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.editor
import com.intellij.codeInsight.editorActions.enter.EnterBetweenBracesNoCommitDelegate
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.lexer.KtTokens
class EnterBetweenBracesAndBracketsNoCommitDelegate : EnterBetweenBracesNoCommitDelegate() {
override fun isCommentType(type: IElementType?): Boolean = type in KtTokens.COMMENTS
override fun isBracePair(lBrace: Char, rBrace: Char): Boolean = super.isBracePair(lBrace, rBrace) || (lBrace == '[' && rBrace == ']')
}
@@ -63,11 +63,17 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
// println(debugInfo(currentPosition))
// ~~~ TESTING ~~~
val before = currentPosition.beforeWhitespacesAndComments()
val before = currentPosition.beforeOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET)
val after = currentPosition.afterOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET)
when {
before.isAt(TemplateEntryOpen) -> {
val baseLineOffset = before.startOffset
return factory.createIndentCalculator(Indent.getNormalIndent()) { baseLineOffset }
val indent = if (!currentPosition.hasEmptyLineAfter(offset) && after.isAt(TemplateEntryClose))
Indent.getNoneIndent()
else
Indent.getNormalIndent()
return factory.createIndentCalculator(indent) { baseLineOffset }
}
before.isAtAnyOf(TryKeyword, FinallyKeyword) -> return factory.createIndentCalculator(
@@ -75,20 +81,17 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
IndentCalculator.LINE_BEFORE,
)
before.isInControlFlowStatement() -> {
val afterWhitespacesAndComments = currentPosition.afterWhitespacesAndComments()
return factory.createIndentCalculator(
when {
afterWhitespacesAndComments.isAt(LeftParenthesis) -> Indent.getContinuationIndent()
afterWhitespacesAndComments.isAtAnyOf(BlockOpeningBrace, Arrow) -> Indent.getNoneIndent()
else -> Indent.getNormalIndent()
},
IndentCalculator.LINE_BEFORE,
)
}
before.isInControlFlowStatement() -> return factory.createIndentCalculator(
when {
after.isAt(LeftParenthesis) -> Indent.getContinuationIndent()
after.isAtAnyOf(BlockOpeningBrace, Arrow) -> Indent.getNoneIndent()
else -> Indent.getNormalIndent()
},
IndentCalculator.LINE_BEFORE,
)
}
currentPosition.afterWhitespacesAndComments()
after
.takeIf { it.isAt(TemplateEntryClose) }
?.let { templateEntryPosition ->
val indent = if (currentPosition.hasEmptyLineAfter(offset)) Indent.getNormalIndent() else Indent.getNoneIndent()
@@ -100,34 +103,18 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
return null
}
private fun SemanticEditorPosition.beforeWhitespacesAndComments(): SemanticEditorPosition = beforeOptionalMix(
Whitespace,
LineComment,
BlockComment,
)
private fun SemanticEditorPosition.afterWhitespacesAndComments(): SemanticEditorPosition = afterOptionalMix(
Whitespace,
LineComment,
BlockComment,
)
private fun SemanticEditorPosition.moveBeforeWhitespacesAndComments(): SemanticEditorPosition = apply {
moveBeforeOptionalMix(Whitespace, LineComment, BlockComment)
}
private fun SemanticEditorPosition.isInControlFlowStatement(): Boolean = with(copy()) {
if (isAt(BlockOpeningBrace)) {
moveBefore()
moveBeforeParentheses(LeftParenthesis, RightParenthesis)
moveBeforeWhitespacesAndComments()
moveBeforeOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET)
}
if (currElement in CONTROL_FLOW_CONSTRUCTIONS) return true
if (!isAt(RightParenthesis)) return false
moveBeforeParentheses(LeftParenthesis, RightParenthesis)
moveBeforeWhitespacesAndComments()
moveBeforeOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET)
return currElement in CONTROL_FLOW_CONSTRUCTIONS
}
@@ -141,6 +128,7 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
FinallyKeyword,
WhileKeyword,
RegularStringPart,
KDoc,
}
companion object {
@@ -150,6 +138,7 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
KtTokens.LONG_TEMPLATE_ENTRY_END to TemplateEntryClose,
KtTokens.EOL_COMMENT to LineComment,
KtTokens.BLOCK_COMMENT to BlockComment,
KtTokens.DOC_COMMENT to KDoc,
KtTokens.ARROW to Arrow,
KtTokens.LBRACE to BlockOpeningBrace,
KtTokens.RBRACE to BlockClosingBrace,
@@ -165,6 +154,8 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
KtTokens.DO_KEYWORD to DoKeyword,
KtTokens.FOR_KEYWORD to ForKeyword,
KtTokens.REGULAR_STRING_PART to RegularStringPart,
KtTokens.LBRACKET to ArrayOpeningBracket,
KtTokens.RBRACKET to ArrayClosingBracket,
)
private val CONTROL_FLOW_CONSTRUCTIONS: HashSet<SemanticEditorPosition.SyntaxElement> = hashSetOf(
@@ -178,5 +169,11 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
CatchKeyword,
FinallyKeyword,
)
private val WHITE_SPACE_OR_COMMENT_BIT_SET: Array<SemanticEditorPosition.SyntaxElement> = arrayOf(
Whitespace,
LineComment,
BlockComment,
)
}
}
@@ -308,6 +308,21 @@ public class PerformanceTypingIndentationTestGenerated extends AbstractPerforman
runTest("idea/testData/indentationOnNewline/InExpressionsParentheses.kt");
}
@TestMetadata("InExpressionsParentheses2.kt")
public void testInExpressionsParentheses2() throws Exception {
runTest("idea/testData/indentationOnNewline/InExpressionsParentheses2.kt");
}
@TestMetadata("InExpressionsParentheses3.kt")
public void testInExpressionsParentheses3() throws Exception {
runTest("idea/testData/indentationOnNewline/InExpressionsParentheses3.kt");
}
@TestMetadata("InExpressionsParentheses4.kt")
public void testInExpressionsParentheses4() throws Exception {
runTest("idea/testData/indentationOnNewline/InExpressionsParentheses4.kt");
}
@TestMetadata("InExpressionsParenthesesBeforeOperand.kt")
public void testInExpressionsParenthesesBeforeOperand() throws Exception {
runTest("idea/testData/indentationOnNewline/InExpressionsParenthesesBeforeOperand.kt");
+2
View File
@@ -81,6 +81,8 @@
id="KotlinEnterHandler" order="before EnterBetweenBracesHandler"/>
<enterHandlerDelegate implementation="org.jetbrains.kotlin.idea.editor.KotlinMultilineStringEnterHandler"
id="KotlinMultilineStringEnterHandler" order="before EnterBetweenBracesHandler"/>
<enterBetweenBracesDelegate language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.editor.EnterBetweenBracesAndBracketsNoCommitDelegate"/>
<lang.smartEnterProcessor language="kotlin" implementationClass="org.jetbrains.kotlin.idea.editor.KotlinSmartEnterHandler"/>
<backspaceHandlerDelegate implementation="org.jetbrains.kotlin.idea.editor.KotlinBackspaceHandler"/>
<backspaceHandlerDelegate implementation="org.jetbrains.kotlin.idea.editor.KotlinStringTemplateBackspaceHandler"/>
@@ -1,6 +0,0 @@
val somelong = 3 + 4 - (
<caret>
)
// SET_TRUE: ALIGN_MULTILINE_BINARY_OPERATION
// WITHOUT_CUSTOM_LINE_INDENT_PROVIDER
@@ -3,4 +3,4 @@ val somelong = 3 + 4 - (
)
// SET_TRUE: ALIGN_MULTILINE_BINARY_OPERATION
// WITHOUT_CUSTOM_LINE_INDENT_PROVIDER
// IGNORE_FORMATTER
@@ -1,4 +1,4 @@
val somelong = 3 + 4 - (<caret>)
// SET_TRUE: ALIGN_MULTILINE_BINARY_OPERATION
// WITHOUT_CUSTOM_LINE_INDENT_PROVIDER
// IGNORE_FORMATTER
@@ -0,0 +1,6 @@
val somelong = 3 + 4 - (
<caret>
)
// SET_FALSE: ALIGN_MULTILINE_BINARY_OPERATION
// IGNORE_FORMATTER
@@ -0,0 +1,4 @@
val somelong = 3 + 4 - (<caret>)
// SET_FALSE: ALIGN_MULTILINE_BINARY_OPERATION
// IGNORE_FORMATTER
@@ -0,0 +1,8 @@
fun a() {
val somelong = 3 + 4 - (
<caret>
)
}
// SET_FALSE: ALIGN_MULTILINE_BINARY_OPERATION
// IGNORE_FORMATTER
@@ -0,0 +1,6 @@
fun a() {
val somelong = 3 + 4 - (<caret>)
}
// SET_FALSE: ALIGN_MULTILINE_BINARY_OPERATION
// IGNORE_FORMATTER
@@ -0,0 +1,8 @@
fun a() {
val somelong = 3 + 4 - (
<caret>
)
}
// SET_TRUE: ALIGN_MULTILINE_BINARY_OPERATION
// IGNORE_FORMATTER
@@ -0,0 +1,6 @@
fun a() {
val somelong = 3 + 4 - (<caret>)
}
// SET_TRUE: ALIGN_MULTILINE_BINARY_OPERATION
// IGNORE_FORMATTER
@@ -4,7 +4,7 @@ fun a() {
select
${
<caret>
}
}
from T
"""
}
@@ -310,6 +310,21 @@ public class TypingIndentationTestBaseGenerated extends AbstractTypingIndentatio
runTest("idea/testData/indentationOnNewline/InExpressionsParentheses.after.kt");
}
@TestMetadata("InExpressionsParentheses2.after.kt")
public void testInExpressionsParentheses2() throws Exception {
runTest("idea/testData/indentationOnNewline/InExpressionsParentheses2.after.kt");
}
@TestMetadata("InExpressionsParentheses3.after.kt")
public void testInExpressionsParentheses3() throws Exception {
runTest("idea/testData/indentationOnNewline/InExpressionsParentheses3.after.kt");
}
@TestMetadata("InExpressionsParentheses4.after.kt")
public void testInExpressionsParentheses4() throws Exception {
runTest("idea/testData/indentationOnNewline/InExpressionsParentheses4.after.kt");
}
@TestMetadata("InExpressionsParenthesesBeforeOperand.after.kt")
public void testInExpressionsParenthesesBeforeOperand() throws Exception {
runTest("idea/testData/indentationOnNewline/InExpressionsParenthesesBeforeOperand.after.kt");
@@ -706,11 +721,6 @@ public class TypingIndentationTestBaseGenerated extends AbstractTypingIndentatio
runTest("idea/testData/indentationOnNewline/InEnumInitializerListNotEmpty.after.inv.kt");
}
@TestMetadata("InExpressionsParentheses.after.inv.kt")
public void testInExpressionsParentheses() throws Exception {
runTest("idea/testData/indentationOnNewline/InExpressionsParentheses.after.inv.kt");
}
@TestMetadata("InExpressionsParenthesesBeforeOperand.after.inv.kt")
public void testInExpressionsParenthesesBeforeOperand() throws Exception {
runTest("idea/testData/indentationOnNewline/InExpressionsParenthesesBeforeOperand.after.inv.kt");