Skip to content

Commit ec92068

Browse files
committed
Fixed BracesInConditionalsAndLoopsRule
### What's done: - creating BLOCK section in THEN section - reused ASTFactory It's part of #1737
1 parent 2d03fa2 commit ec92068

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

diktat-rules/src/main/kotlin/com/saveourtool/diktat/ruleset/rules/chapter3/BracesInConditionalsAndLoopsRule.kt

+36-13
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,18 @@ import com.saveourtool.diktat.ruleset.utils.prevSibling
1212
import org.jetbrains.kotlin.KtNodeTypes
1313
import org.jetbrains.kotlin.KtNodeTypes.BLOCK
1414
import org.jetbrains.kotlin.KtNodeTypes.CALL_EXPRESSION
15+
import org.jetbrains.kotlin.KtNodeTypes.ELSE
1516
import org.jetbrains.kotlin.KtNodeTypes.IF
1617
import org.jetbrains.kotlin.KtNodeTypes.REFERENCE_EXPRESSION
1718
import org.jetbrains.kotlin.KtNodeTypes.SAFE_ACCESS_EXPRESSION
19+
import org.jetbrains.kotlin.KtNodeTypes.THEN
1820
import org.jetbrains.kotlin.KtNodeTypes.WHEN
21+
import org.jetbrains.kotlin.com.intellij.lang.ASTFactory
1922
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
2023
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.CompositeElement
2124
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.LeafPsiElement
2225
import org.jetbrains.kotlin.com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl
26+
import org.jetbrains.kotlin.com.intellij.psi.tree.IElementType
2327
import org.jetbrains.kotlin.lexer.KtTokens.DO_KEYWORD
2428
import org.jetbrains.kotlin.lexer.KtTokens.ELSE_KEYWORD
2529
import org.jetbrains.kotlin.lexer.KtTokens.IF_KEYWORD
@@ -81,14 +85,14 @@ class BracesInConditionalsAndLoopsRule(configRules: List<RulesConfig>) : DiktatR
8185
NO_BRACES_IN_CONDITIONALS_AND_LOOPS.warnAndFix(configRules, emitWarn, isFixMode, "IF",
8286
(thenNode?.prevSibling { it.elementType == IF_KEYWORD } ?: node).startOffset, node) {
8387
thenNode?.run {
84-
(psi as KtElement).replaceWithBlock(indent)
88+
this.replaceWithBlock(indent)
8589
if (elseNode != null && elseKeyword != null) {
8690
node.replaceChild(elseKeyword.prevSibling.node, PsiWhiteSpaceImpl(" "))
8791
}
8892
}
8993
?: run {
9094
val nodeAfterCondition = ifPsi.rightParenthesis!!.node.treeNext
91-
node.insertEmptyBlockBetweenChildren(nodeAfterCondition, nodeAfterCondition, indent)
95+
node.insertEmptyBlockBetweenChildren(nodeAfterCondition, nodeAfterCondition, indent, THEN)
9296
}
9397
}
9498
}
@@ -119,7 +123,7 @@ class BracesInConditionalsAndLoopsRule(configRules: List<RulesConfig>) : DiktatR
119123
}
120124
?: run {
121125
// `else` can have empty body e.g. when there is a semicolon after: `else ;`
122-
node.insertEmptyBlockBetweenChildren(elseKeyword.node.treeNext, null, indent)
126+
node.insertEmptyBlockBetweenChildren(elseKeyword.node.treeNext, null, indent, ELSE)
123127
}
124128
}
125129
}
@@ -171,24 +175,43 @@ class BracesInConditionalsAndLoopsRule(configRules: List<RulesConfig>) : DiktatR
171175
}
172176

173177
private fun KtElement.replaceWithBlock(indent: Int) {
174-
this.astReplace(KtBlockExpression(
178+
val ktBlockNode = KtBlockExpression(
175179
"{\n${" ".repeat(indent + INDENT_STEP)}$text\n${" ".repeat(indent)}}"
176-
))
180+
)
181+
this.astReplace(ktBlockNode)
182+
}
183+
184+
private fun ASTNode.replaceWithBlock(indent: Int) {
185+
val blockNode = ASTFactory.composite(BLOCK)
186+
this.treeParent.addChild(blockNode, this)
187+
blockNode.addChild(ASTFactory.leaf(LBRACE, "{"))
188+
blockNode.addChild(ASTFactory.whitespace("\n${" ".repeat(indent + INDENT_STEP)}"))
189+
blockNode.addChild(this)
190+
blockNode.addChild(ASTFactory.whitespace("\n${" ".repeat(indent)}"))
191+
blockNode.addChild(ASTFactory.leaf(RBRACE, "}"))
177192
}
178193

179194
private fun ASTNode.insertEmptyBlockBetweenChildren(
180195
firstChild: ASTNode,
181196
secondChild: ASTNode?,
182-
indent: Int
197+
indent: Int,
198+
elementType: IElementType? = null,
183199
) {
184-
val emptyBlock = CompositeElement(KtNodeTypes.BLOCK_CODE_FRAGMENT)
185-
addChild(emptyBlock, firstChild)
186-
addChild(PsiWhiteSpaceImpl(" "), emptyBlock)
187-
emptyBlock.addChild(LeafPsiElement(LBRACE, "{"))
188-
emptyBlock.addChild(PsiWhiteSpaceImpl("\n${" ".repeat(indent)}"))
189-
emptyBlock.addChild(LeafPsiElement(RBRACE, "}"))
200+
val emptyBlock = ASTFactory.composite(BLOCK)
201+
elementType?.let {
202+
val anotherBlock = ASTFactory.composite(it)
203+
addChild(anotherBlock, firstChild)
204+
addChild(ASTFactory.whitespace(" "), anotherBlock)
205+
anotherBlock.addChild(emptyBlock)
206+
} ?: run {
207+
addChild(emptyBlock, firstChild)
208+
addChild(ASTFactory.whitespace(" "), emptyBlock)
209+
}
210+
emptyBlock.addChild(ASTFactory.leaf(LBRACE, "{"))
211+
emptyBlock.addChild(ASTFactory.whitespace("\n${" ".repeat(indent)}"))
212+
emptyBlock.addChild(ASTFactory.leaf(RBRACE, "}"))
190213
secondChild?.let {
191-
replaceChild(it, PsiWhiteSpaceImpl(" "))
214+
replaceChild(it, ASTFactory.whitespace(" "))
192215
}
193216
}
194217
companion object {

diktat-rules/src/test/kotlin/com/saveourtool/diktat/ruleset/chapter3/BracesRuleFixTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test
1111
class BracesRuleFixTest : FixTestBase("test/paragraph3/braces", ::BracesInConditionalsAndLoopsRule) {
1212
@Test
1313
@Tag(WarningNames.NO_BRACES_IN_CONDITIONALS_AND_LOOPS)
14-
@Disabled("https://github.com/saveourtool/diktat/issues/1737")
14+
// @Disabled("https://github.com/saveourtool/diktat/issues/1737")
1515
fun `should add braces to if-else statements - 1`() {
1616
fixAndCompare("IfElseBraces1Expected.kt", "IfElseBraces1Test.kt")
1717
}

0 commit comments

Comments
 (0)