Skip to content

Commit b176773

Browse files
authored
Merge pull request #102 from domaframework/fix/sql-formatter-second-option-indent
Fix:sql formatter second option indent
2 parents 402b5b3 + 956a59f commit b176773

30 files changed

+360
-237
lines changed

src/main/kotlin/org/domaframework/doma/intellij/formatter/SqlBlockBuilder.kt

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@
1616
package org.domaframework.doma.intellij.formatter
1717

1818
import org.domaframework.doma.intellij.formatter.block.SqlBlock
19+
import org.domaframework.doma.intellij.formatter.block.SqlCommentBlock
1920
import org.domaframework.doma.intellij.formatter.block.expr.SqlElBlockCommentBlock
21+
import org.domaframework.doma.intellij.formatter.block.expr.SqlElConditionLoopCommentBlock
2022
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlSubGroupBlock
2123

2224
open class SqlBlockBuilder {
2325
private val groupTopNodeIndexHistory = mutableListOf<Pair<Int, SqlBlock>>()
2426

25-
private val commentBlocks = mutableListOf<SqlBlock>()
27+
private val commentBlocks = mutableListOf<SqlCommentBlock>()
28+
29+
private val conditionOrLoopBlocks = mutableListOf<SqlElConditionLoopCommentBlock>()
2630

2731
fun getGroupTopNodeIndexHistory(): List<Pair<Int, SqlBlock>> = groupTopNodeIndexHistory
2832

@@ -32,7 +36,7 @@ open class SqlBlockBuilder {
3236
groupTopNodeIndexHistory.add(block)
3337
}
3438

35-
fun addCommentBlock(block: SqlBlock) {
39+
fun addCommentBlock(block: SqlCommentBlock) {
3640
commentBlocks.add(block)
3741
}
3842

@@ -41,23 +45,28 @@ open class SqlBlockBuilder {
4145
var index = 0
4246
commentBlocks.forEach { block ->
4347
if (block !is SqlElBlockCommentBlock) {
44-
val indentLen =
45-
if (index == 0 &&
46-
baseIndent.parentBlock is SqlSubGroupBlock &&
47-
baseIndent.parentBlock?.childBlocks?.size == 1
48-
) {
49-
1
50-
} else {
51-
baseIndent.indent.indentLen
52-
}
53-
block.indent.indentLevel = IndentType.NONE
54-
block.indent.indentLen = indentLen
55-
block.indent.groupIndentLen = 0
48+
if (index == 0 &&
49+
baseIndent.parentBlock is SqlSubGroupBlock &&
50+
baseIndent.parentBlock?.childBlocks?.size == 1
51+
) {
52+
block.indent.indentLevel = IndentType.NONE
53+
block.indent.indentLen = 1
54+
block.indent.groupIndentLen = 0
55+
} else {
56+
block.setParentGroupBlock(baseIndent)
57+
}
5658
index++
5759
}
5860
}
5961
commentBlocks.clear()
6062
}
63+
if (conditionOrLoopBlocks.isNotEmpty()) {
64+
conditionOrLoopBlocks.forEach { block ->
65+
if (block.parentBlock == null) {
66+
block.setParentGroupBlock(baseIndent)
67+
}
68+
}
69+
}
6170
}
6271

6372
fun getLastGroupTopNodeIndexHistory(): Pair<Int, SqlBlock>? = groupTopNodeIndexHistory.lastOrNull()
@@ -76,8 +85,23 @@ open class SqlBlockBuilder {
7685
).clear()
7786
}
7887

79-
fun getGroupTopNodeIndexByIndentType(indentType: IndentType): Int =
88+
fun getGroupTopNodeIndex(condition: (SqlBlock) -> Boolean): Int =
8089
groupTopNodeIndexHistory.indexOfLast {
81-
it.second.indent.indentLevel == indentType
90+
condition(it.second)
8291
}
92+
93+
fun getConditionOrLoopBlocksLast(): SqlElConditionLoopCommentBlock? = conditionOrLoopBlocks.lastOrNull()
94+
95+
fun addConditionOrLoopBlock(block: SqlElConditionLoopCommentBlock) {
96+
if (!block.conditionType.isInvalid() && !block.conditionType.isEnd()
97+
) {
98+
conditionOrLoopBlocks.add(block)
99+
}
100+
}
101+
102+
fun removeConditionOrLoopBlockLast() {
103+
if (conditionOrLoopBlocks.isNotEmpty()) {
104+
conditionOrLoopBlocks.removeLast()
105+
}
106+
}
83107
}

src/main/kotlin/org/domaframework/doma/intellij/formatter/SqlBlockUtil.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class SqlBlockUtil(
110110
IndentType.INLINE -> {
111111
if (!SqlKeywordUtil.isSetLineKeyword(
112112
child.text,
113-
lastGroupBlock?.node?.text ?: "",
113+
lastGroupBlock?.getNodeText() ?: "",
114114
)
115115
) {
116116
return SqlInlineGroupBlock(child, wrap, alignment, spacingBuilder)
@@ -152,8 +152,8 @@ class SqlBlockUtil(
152152
is SqlKeywordGroupBlock -> {
153153
val lastKeyword =
154154
lastGroup.childBlocks
155-
.lastOrNull { SqlKeywordUtil.isOptionSqlKeyword(it.node.text) }
156-
if (lastKeyword != null && lastKeyword.node.text.lowercase() == "in") {
155+
.lastOrNull { SqlKeywordUtil.isOptionSqlKeyword(it.getNodeText()) }
156+
if (lastKeyword != null && lastKeyword.getNodeText().lowercase() == "in") {
157157
return SqlParallelListBlock(child, wrap, alignment, spacingBuilder)
158158
}
159159
if (lastGroup is SqlCreateKeywordGroupBlock) {
@@ -213,7 +213,7 @@ class SqlBlockUtil(
213213
when (lastGroup) {
214214
is SqlKeywordGroupBlock -> {
215215
when {
216-
SqlKeywordUtil.isBeforeTableKeyword(lastGroup.node.text) ->
216+
SqlKeywordUtil.isBeforeTableKeyword(lastGroup.getNodeText()) ->
217217
SqlTableBlock(
218218
child,
219219
wrap,

src/main/kotlin/org/domaframework/doma/intellij/formatter/SqlCustomSpacingBuilder.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ class SqlCustomSpacingBuilder {
8282
null -> return nonSpacing
8383
is SqlWhitespaceBlock -> {
8484
val indentLen: Int = child2.indent.indentLen
85-
val afterNewLine = child1.node.text.substringAfterLast("\n", "")
86-
if (child1.node.text.contains("\n")) {
85+
val afterNewLine = child1.getNodeText().substringAfterLast("\n", "")
86+
if (child1.getNodeText().contains("\n")) {
8787
val currentIndent = afterNewLine.length
8888
val newIndent =
8989
if (currentIndent != indentLen) {

src/main/kotlin/org/domaframework/doma/intellij/formatter/SqlFormattingModelBuilder.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class SqlFormattingModelBuilder : FormattingModelBuilder {
7878
.spacing(0, 0, 0, false, 0)
7979
.around(SqlTypes.WORD)
8080
.spacing(1, 1, 0, false, 0)
81+
.around(SqlTypes.NUMBER)
82+
.spacing(1, 1, 0, false, 0)
8183
.before(SqlTypes.RIGHT_PAREN)
8284
.spacing(0, 0, 0, false, 0)
8385
.around(SqlTypes.PLUS)

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/SqlBlock.kt

Lines changed: 90 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ open class SqlBlock(
9393
childBlocks.add(childBlock)
9494
}
9595

96+
fun getNodeText() = node.text.lowercase()
97+
9698
public override fun buildChildren(): MutableList<AbstractBlock> {
9799
if (isLeaf || !isEnableFormat()) return mutableListOf()
98100

@@ -114,12 +116,18 @@ open class SqlBlock(
114116
}
115117
}
116118
prevNonWhiteSpaceNode = child
117-
updateSearchKeywordLevelHistory(childBlock, child)
118-
setRightSpace(childBlock)
119-
blocks.add(childBlock)
120119
if (childBlock is SqlCommentBlock) {
121-
blockBuilder.addCommentBlock(childBlock)
120+
when (childBlock) {
121+
is SqlElConditionLoopCommentBlock ->
122+
blockBuilder.addConditionOrLoopBlock(
123+
childBlock,
124+
)
125+
126+
else -> blockBuilder.addCommentBlock(childBlock)
127+
}
122128
}
129+
updateSearchKeywordLevelHistory(childBlock, child)
130+
blocks.add(childBlock)
123131
} else {
124132
if (lastBlock !is SqlLineCommentBlock) {
125133
blocks.add(
@@ -160,24 +168,19 @@ open class SqlBlock(
160168
) ||
161169
(childBlock is SqlElConditionLoopCommentBlock)
162170

163-
private fun setRightSpace(currentBlock: SqlBlock?) {
164-
val rightBlock = currentBlock as? SqlRightPatternBlock
165-
rightBlock?.enableLastRight()
166-
}
167-
168171
private fun isNewGroup(childBlock: SqlBlock): Boolean {
169172
val isNewGroupType = childBlock.indent.indentLevel.isNewLineGroup()
170173
val lastGroup = blockBuilder.getLastGroupTopNodeIndexHistory()?.second
171174
val lastKeywordText =
172175
if (lastGroup?.indent?.indentLevel == IndentType.JOIN) {
173-
lastGroup.node.text
176+
lastGroup.getNodeText()
174177
} else {
175178
getLastGroupKeywordText(lastGroup)
176179
}
177180

178181
val isSetLineGroup =
179182
SqlKeywordUtil.isSetLineKeyword(
180-
childBlock.node.text,
183+
childBlock.getNodeText(),
181184
lastKeywordText,
182185
)
183186

@@ -201,7 +204,7 @@ open class SqlBlock(
201204
val isNewGroupType = childBlock.indent.indentLevel.isNewLineGroup()
202205
val lastKeywordText =
203206
if (lastGroup?.indent?.indentLevel == IndentType.JOIN) {
204-
lastGroup.node.text
207+
lastGroup.getNodeText()
205208
} else {
206209
getLastGroupKeywordText(lastGroup)
207210
}
@@ -229,7 +232,7 @@ open class SqlBlock(
229232
?.childBlocks
230233
?.lastOrNull { it.node.elementType == SqlTypes.KEYWORD }
231234
?.node
232-
?.text ?: lastGroup?.node?.text ?: ""
235+
?.text ?: lastGroup?.getNodeText() ?: ""
233236

234237
protected open fun updateSearchKeywordLevelHistory(
235238
childBlock: SqlBlock,
@@ -255,11 +258,36 @@ open class SqlBlock(
255258
return@setParentGroups lastGroupBlock
256259
}
257260
} else if (lastIndentLevel == childBlock.indent.indentLevel) {
258-
blockBuilder.removeLastGroupTopNodeIndexHistory()
259-
setParentGroups(
260-
childBlock,
261-
) { history ->
262-
return@setParentGroups lastGroupBlock.parentBlock
261+
// The AND following an OR will be a child of OR unless surrounded by a subgroup
262+
if (childBlock.getNodeText() == "and" && lastGroupBlock.getNodeText() == "or") {
263+
setParentGroups(
264+
childBlock,
265+
) { history ->
266+
return@setParentGroups lastGroupBlock
267+
}
268+
} else {
269+
if (childBlock.getNodeText() == "or" &&
270+
lastGroupBlock.getNodeText() == "and" &&
271+
lastGroupBlock.parentBlock?.getNodeText() == "or"
272+
) {
273+
val orParentIndex =
274+
blockBuilder.getGroupTopNodeIndex { block ->
275+
block is SqlKeywordGroupBlock && block.getNodeText() == "or"
276+
}
277+
blockBuilder.clearSubListGroupTopNodeIndexHistory(orParentIndex)
278+
setParentGroups(
279+
childBlock,
280+
) { history ->
281+
return@setParentGroups history.lastOrNull()?.second
282+
}
283+
} else {
284+
blockBuilder.removeLastGroupTopNodeIndexHistory()
285+
setParentGroups(
286+
childBlock,
287+
) { history ->
288+
return@setParentGroups lastGroupBlock.parentBlock
289+
}
290+
}
263291
}
264292
} else if (lastIndentLevel < childBlock.indent.indentLevel) {
265293
setParentGroups(
@@ -300,6 +328,7 @@ open class SqlBlock(
300328
return@setParentGroups lastGroupBlock.parentBlock
301329
}
302330
}
331+
303332
else -> {
304333
setParentGroups(
305334
childBlock,
@@ -322,7 +351,9 @@ open class SqlBlock(
322351
is SqlInlineSecondGroupBlock -> {
323352
if (childBlock.isEndCase) {
324353
val inlineIndex =
325-
blockBuilder.getGroupTopNodeIndexByIndentType(IndentType.INLINE)
354+
blockBuilder.getGroupTopNodeIndex { block ->
355+
block.indent.indentLevel == IndentType.INLINE
356+
}
326357
if (inlineIndex >= 0) {
327358
setParentGroups(
328359
childBlock,
@@ -357,8 +388,9 @@ open class SqlBlock(
357388
if (parentGroupBlock is SqlColumnDefinitionRawGroupBlock &&
358389
parentGroupBlock.columnName != ","
359390
) {
360-
parentGroupBlock.columnName = childBlock.node.text
361-
val columnDefinition = parentGroupBlock.parentBlock as? SqlColumnDefinitionGroupBlock
391+
parentGroupBlock.columnName = childBlock.getNodeText()
392+
val columnDefinition =
393+
parentGroupBlock.parentBlock as? SqlColumnDefinitionGroupBlock
362394
if (columnDefinition != null && columnDefinition.alignmentColumnName.length < parentGroupBlock.columnName.length) {
363395
columnDefinition.alignmentColumnName = parentGroupBlock.columnName
364396
}
@@ -385,7 +417,12 @@ open class SqlBlock(
385417
setParentGroups(
386418
childBlock,
387419
) { history ->
388-
return@setParentGroups history.last().second
420+
if (childBlock.conditionType.isEnd()) {
421+
val lastConditionLoopCommentBlock = blockBuilder.getConditionOrLoopBlocksLast()
422+
blockBuilder.removeConditionOrLoopBlockLast()
423+
return@setParentGroups lastConditionLoopCommentBlock
424+
}
425+
return@setParentGroups null
389426
}
390427
}
391428

@@ -406,7 +443,10 @@ open class SqlBlock(
406443
}
407444

408445
is SqlRightPatternBlock -> {
409-
val paramIndex = blockBuilder.getGroupTopNodeIndexByIndentType(IndentType.PARAM)
446+
val paramIndex =
447+
blockBuilder.getGroupTopNodeIndex { block ->
448+
block.indent.indentLevel == IndentType.PARAM
449+
}
410450
if (paramIndex >= 0) {
411451
setParentGroups(
412452
childBlock,
@@ -417,7 +457,10 @@ open class SqlBlock(
417457
return
418458
}
419459

420-
val leftIndex = blockBuilder.getGroupTopNodeIndexByIndentType(IndentType.SUB)
460+
val leftIndex =
461+
blockBuilder.getGroupTopNodeIndex { block ->
462+
block.indent.indentLevel == IndentType.SUB
463+
}
421464
if (leftIndex >= 0) {
422465
setParentGroups(
423466
childBlock,
@@ -472,7 +515,14 @@ open class SqlBlock(
472515
) {
473516
val parentGroup =
474517
getParentGroup(blockBuilder.getGroupTopNodeIndexHistory() as MutableList<Pair<Int, SqlBlock>>)
475-
childBlock.setParentGroupBlock(parentGroup)
518+
519+
// // The parent block for SqlElConditionLoopCommentBlock will be set later
520+
if (childBlock !is SqlElConditionLoopCommentBlock ||
521+
childBlock.conditionType.isEnd()
522+
) {
523+
childBlock.setParentGroupBlock(parentGroup)
524+
}
525+
476526
if (isNewGroup(childBlock) ||
477527
(childBlock is SqlSubGroupBlock) ||
478528
childBlock is SqlViewGroupBlock ||
@@ -504,8 +554,20 @@ open class SqlBlock(
504554
return blockUtil.getSubGroupBlock(lastGroup, child)
505555
}
506556

507-
SqlTypes.OTHER -> return SqlOtherBlock(child, wrap, alignment, spacingBuilder, blockBuilder.getLastGroup())
508-
SqlTypes.RIGHT_PAREN -> return SqlRightPatternBlock(child, wrap, alignment, spacingBuilder)
557+
SqlTypes.OTHER -> return SqlOtherBlock(
558+
child,
559+
wrap,
560+
alignment,
561+
spacingBuilder,
562+
blockBuilder.getLastGroup(),
563+
)
564+
565+
SqlTypes.RIGHT_PAREN -> return SqlRightPatternBlock(
566+
child,
567+
wrap,
568+
alignment,
569+
spacingBuilder,
570+
)
509571

510572
SqlTypes.COMMA -> {
511573
return blockUtil.getCommaGroupBlock(lastGroup, child)
@@ -575,7 +637,7 @@ open class SqlBlock(
575637
}
576638

577639
// Do not leave a space after the comment block of the bind variable
578-
if (child1 is SqlElBlockCommentBlock && child2 !is SqlCommentBlock) {
640+
if (child1 is SqlElBlockCommentBlock && child1 !is SqlElConditionLoopCommentBlock && child2 !is SqlCommentBlock) {
579641
return SqlCustomSpacingBuilder.nonSpacing
580642
}
581643

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/SqlColumnBlock.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class SqlColumnBlock(
5757
if (parentGroupDefinition == null) return 1
5858

5959
val groupMaxAlimentLen = parentGroupDefinition.alignmentColumnName.length
60-
val diffColumnName = groupMaxAlimentLen.minus(node.text.length)
60+
val diffColumnName = groupMaxAlimentLen.minus(getNodeText().length)
6161
return diffColumnName.plus(1)
6262
}
6363
return 1

0 commit comments

Comments
 (0)