Skip to content

Commit bd4ea51

Browse files
committed
Refactor SQL formatting classes to improve spacing and indentation handling for various SQL constructs
1 parent 3e3fce3 commit bd4ea51

File tree

10 files changed

+147
-81
lines changed

10 files changed

+147
-81
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ open class SqlBlock(
8282

8383
fun getChildBlocksDropLast(
8484
dropIndex: Int = 1,
85-
skipCommentBlock: Boolean = false,
85+
skipCommentBlock: Boolean = true,
8686
): List<SqlBlock> {
8787
val children = childBlocks.dropLast(dropIndex)
8888
if (skipCommentBlock) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ open class SqlCommaBlock(
5858
SqlFunctionParamBlock::class,
5959
SqlWithColumnGroupBlock::class,
6060
SqlKeywordGroupBlock::class,
61+
SqlElConditionLoopCommentBlock::class,
6162
)
6263

6364
private val PARENT_INDENT_SYNC_TYPES =

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

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,17 @@ class SqlFileBlock(
7878
enableFormat,
7979
formatMode,
8080
) {
81+
override val indent =
82+
ElementIndent(
83+
IndentType.FILE,
84+
0,
85+
0,
86+
)
87+
88+
override fun setParentGroupBlock(lastGroup: SqlBlock?) {
89+
super.setParentGroupBlock(null)
90+
}
91+
8192
private val blocks = mutableListOf<AbstractBlock>()
8293

8394
private val blockBuilder = SqlBlockBuilder()
@@ -446,11 +457,21 @@ class SqlFileBlock(
446457

447458
if (childBlock1 is SqlWhitespaceBlock && childBlock2.parentBlock is SqlElConditionLoopCommentBlock) {
448459
val child1 = childBlock2.parentBlock as SqlElConditionLoopCommentBlock
449-
SqlCustomSpacingBuilder().getSpacingElDirectiveComment(child1, childBlock2)?.let { return it }
460+
SqlCustomSpacingBuilder()
461+
.getSpacingElDirectiveComment(child1, childBlock2)
462+
?.let { return it }
450463
}
451464

452-
if (childBlock1 is SqlElBlockCommentBlock) {
453-
SqlCustomSpacingBuilder().getSpacingElDirectiveComment(childBlock1, childBlock2)?.let { return it }
465+
if (childBlock1 is SqlElBlockCommentBlock && childBlock2 !is SqlRightPatternBlock) {
466+
SqlCustomSpacingBuilder()
467+
.getSpacingElDirectiveComment(childBlock1, childBlock2)
468+
?.let { return it }
469+
}
470+
471+
if (childBlock2 is SqlRightPatternBlock) {
472+
return SqlCustomSpacingBuilder().getSpacingRightPattern(
473+
childBlock2,
474+
)
454475
}
455476

456477
if (childBlock2 is SqlWithColumnGroupBlock) {
@@ -467,7 +488,11 @@ class SqlFileBlock(
467488
}
468489

469490
if (childBlock2 is SqlElBlockCommentBlock) {
470-
if (TypeUtil.isExpectedClassType(SqlRightPatternBlock.NOT_INSERT_SPACE_TYPES, childBlock1)) {
491+
if (TypeUtil.isExpectedClassType(
492+
SqlRightPatternBlock.NOT_INDENT_EXPECTED_TYPES,
493+
childBlock1,
494+
)
495+
) {
471496
return SqlCustomSpacingBuilder.nonSpacing
472497
}
473498
return when (childBlock1) {
@@ -530,7 +555,9 @@ class SqlFileBlock(
530555
}
531556

532557
// Create Table Column Definition Raw Group Block
533-
CreateTableUtil.getColumnDefinitionRawGroupSpacing(childBlock1, childBlock2)?.let { return it }
558+
CreateTableUtil
559+
.getColumnDefinitionRawGroupSpacing(childBlock1, childBlock2)
560+
?.let { return it }
534561

535562
when (childBlock2) {
536563
is SqlColumnDefinitionRawGroupBlock ->
@@ -539,18 +566,16 @@ class SqlFileBlock(
539566
childBlock2,
540567
)?.let { return it }
541568

542-
is SqlRightPatternBlock -> return SqlCustomSpacingBuilder().getSpacingRightPattern(
543-
childBlock2,
544-
)
545-
546569
is SqlColumnBlock ->
547570
SqlCustomSpacingBuilder()
548571
.getSpacingColumnDefinition(childBlock2)
549572
?.let { return it }
550573
}
551574

552575
if (childBlock1 is SqlBlock && (childBlock2 is SqlCommaBlock || childBlock2 is SqlColumnRawGroupBlock)) {
553-
SqlCustomSpacingBuilder().getSpacingWithIndentComma(childBlock1, childBlock2)?.let { return it }
576+
SqlCustomSpacingBuilder()
577+
.getSpacingWithIndentComma(childBlock1, childBlock2)
578+
?.let { return it }
554579
}
555580

556581
val spacing: Spacing? = customSpacingBuilder?.getCustomSpacing(childBlock1, childBlock2)

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

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlKeywordG
2424
import org.domaframework.doma.intellij.formatter.block.group.keyword.condition.SqlConditionalExpressionGroupBlock
2525
import org.domaframework.doma.intellij.formatter.block.group.keyword.create.SqlCreateTableColumnDefinitionGroupBlock
2626
import org.domaframework.doma.intellij.formatter.block.group.keyword.insert.SqlInsertColumnGroupBlock
27+
import org.domaframework.doma.intellij.formatter.block.group.keyword.second.SqlValuesGroupBlock
2728
import org.domaframework.doma.intellij.formatter.block.group.keyword.update.SqlUpdateColumnGroupBlock
2829
import org.domaframework.doma.intellij.formatter.block.group.keyword.update.SqlUpdateSetGroupBlock
2930
import org.domaframework.doma.intellij.formatter.block.group.keyword.update.SqlUpdateValueGroupBlock
@@ -49,10 +50,25 @@ open class SqlRightPatternBlock(
4950
context.enableFormat,
5051
context.formatMode,
5152
) {
52-
var preSpaceRight = false
53+
enum class LineBreakAndSpacingType {
54+
NONE, // No line break and no spacing
55+
LINE_BREAK, // Line break only
56+
SPACING, // Spacing only
57+
LINE_BREAK_AND_SPACING, // Both line break and spacing
58+
}
59+
60+
private var preSpaceRight = false
61+
var lineBreakAndSpacingType: LineBreakAndSpacingType = LineBreakAndSpacingType.NONE
5362

5463
companion object {
55-
val NOT_INSERT_SPACE_TYPES =
64+
private val INDENT_EXPECTED_TYPES =
65+
listOf(
66+
SqlUpdateColumnGroupBlock::class,
67+
SqlUpdateValueGroupBlock::class,
68+
SqlCreateTableColumnDefinitionGroupBlock::class,
69+
)
70+
71+
val NOT_INDENT_EXPECTED_TYPES =
5672
listOf(
5773
SqlFunctionParamBlock::class,
5874
SqlInsertColumnGroupBlock::class,
@@ -61,13 +77,6 @@ open class SqlRightPatternBlock(
6177
SqlConditionalExpressionGroupBlock::class,
6278
)
6379

64-
private val INDENT_EXPECTED_TYPES =
65-
listOf(
66-
SqlUpdateColumnGroupBlock::class,
67-
SqlUpdateValueGroupBlock::class,
68-
SqlCreateTableColumnDefinitionGroupBlock::class,
69-
)
70-
7180
val NEW_LINE_EXPECTED_TYPES =
7281
listOf(
7382
SqlUpdateColumnGroupBlock::class,
@@ -78,7 +87,7 @@ open class SqlRightPatternBlock(
7887
SqlWithQuerySubGroupBlock::class,
7988
)
8089

81-
private val NEW_LINE_EXCLUDE_TYPES =
90+
val NOT_NEW_LINE_EXPECTED_TYPES =
8291
listOf(
8392
SqlDataTypeParamBlock::class,
8493
SqlConditionalExpressionGroupBlock::class,
@@ -93,11 +102,16 @@ open class SqlRightPatternBlock(
93102
private fun enableLastRight() {
94103
parentBlock?.let { parent ->
95104
// Check if parent is in the notInsertSpaceClassList
96-
if (isExpectedClassType(NOT_INSERT_SPACE_TYPES, parent)) {
105+
if (isExpectedClassType(NOT_INDENT_EXPECTED_TYPES, parent)) {
97106
preSpaceRight = false
98107
return
99108
}
100-
if (isExpectedClassType(INDENT_EXPECTED_TYPES, parent)) {
109+
if (isExpectedClassType(
110+
INDENT_EXPECTED_TYPES,
111+
parent,
112+
) ||
113+
parent.childBlocks.firstOrNull() is SqlValuesGroupBlock
114+
) {
101115
preSpaceRight = true
102116
return
103117
}
@@ -146,36 +160,68 @@ open class SqlRightPatternBlock(
146160
override fun buildChildren(): MutableList<AbstractBlock> = mutableListOf()
147161

148162
override fun createBlockIndentLen(): Int {
149-
if (preSpaceRight) return 1
150-
151163
parentBlock?.let { parent ->
164+
if ((
165+
isExpectedClassType(NEW_LINE_EXPECTED_TYPES, parent) ||
166+
parent.getChildBlocksDropLast().firstOrNull() is SqlValuesGroupBlock
167+
) &&
168+
preSpaceRight
169+
) {
170+
return parent.indent.indentLen
171+
}
172+
if (preSpaceRight) return 1
152173
return parent.indent.indentLen
153174
} ?: return 0
154175
}
155176

156177
override fun isLeaf(): Boolean = true
157178

158179
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean {
159-
if (preSpaceRight) return false
160-
161180
parentBlock?.let { parent ->
162-
if ((
163-
isExpectedClassType(NEW_LINE_EXPECTED_TYPES, parent) ||
164-
isExpectedClassType(NEW_LINE_EXPECTED_TYPES, parent.parentBlock)
165-
) &&
166-
!isExpectedClassType(NEW_LINE_EXCLUDE_TYPES, parent)
181+
if (isExpectedClassType(NEW_LINE_EXPECTED_TYPES, parent) ||
182+
parent.childBlocks.firstOrNull() is SqlValuesGroupBlock
167183
) {
184+
lineBreakAndSpacingType =
185+
if (preSpaceRight) {
186+
LineBreakAndSpacingType.LINE_BREAK_AND_SPACING
187+
} else {
188+
LineBreakAndSpacingType.LINE_BREAK
189+
}
168190
return true
169191
}
170192

171193
if (parent is SqlSubGroupBlock) {
172194
val firstChild =
173-
parent.getChildBlocksDropLast(skipCommentBlock = true).firstOrNull()
195+
parent.getChildBlocksDropLast().firstOrNull()
174196
if (firstChild is SqlKeywordGroupBlock) {
175-
return firstChild.indent.indentLevel != IndentType.TOP
197+
val lineBreak =
198+
firstChild.indent.indentLevel != IndentType.TOP &&
199+
!isExpectedClassType(NOT_NEW_LINE_EXPECTED_TYPES, parent)
200+
lineBreakAndSpacingType =
201+
if (lineBreak) {
202+
if (preSpaceRight) {
203+
LineBreakAndSpacingType.LINE_BREAK_AND_SPACING
204+
} else {
205+
LineBreakAndSpacingType.LINE_BREAK
206+
}
207+
} else {
208+
if (preSpaceRight) {
209+
LineBreakAndSpacingType.SPACING
210+
} else {
211+
LineBreakAndSpacingType.NONE
212+
}
213+
}
214+
215+
return lineBreak
176216
}
177217
}
178218
}
219+
lineBreakAndSpacingType =
220+
if (preSpaceRight) {
221+
LineBreakAndSpacingType.SPACING
222+
} else {
223+
LineBreakAndSpacingType.NONE
224+
}
179225
return false
180226
}
181227
}

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,15 @@
1515
*/
1616
package org.domaframework.doma.intellij.formatter.block.conflict
1717

18-
enum class OnConflictKeywordType {
19-
CONFLICT,
20-
CONSTRAINT,
21-
UNKNOWN,
18+
enum class OnConflictKeywordType(
19+
private val keyword: String,
20+
) {
21+
CONFLICT("conflict"),
22+
CONSTRAINT("constraint"),
23+
UNKNOWN("unknown"),
24+
;
25+
26+
companion object {
27+
fun of(keyword: String): OnConflictKeywordType = entries.find { it.keyword == keyword } ?: UNKNOWN
28+
}
2229
}

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/SqlKeywordGroupBlock.kt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,20 @@ open class SqlKeywordGroupBlock(
3939

4040
fun updateTopKeywordBlocks(block: SqlBlock) {
4141
val lastChild =
42-
getChildBlocksDropLast(skipCommentBlock = true).lastOrNull()
42+
getChildBlocksDropLast().lastOrNull()
4343
val topKeywordTypes =
4444
listOf(
4545
SqlKeywordBlock::class,
4646
SqlKeywordGroupBlock::class,
4747
)
4848

49-
if (lastChild == null || TypeUtil.isExpectedClassType(topKeywordTypes, lastChild) && canAddTopKeyword) {
49+
if (lastChild == null ||
50+
TypeUtil.isExpectedClassType(
51+
topKeywordTypes,
52+
lastChild,
53+
) &&
54+
canAddTopKeyword
55+
) {
5056
topKeywordBlocks.add(block)
5157
} else {
5258
canAddTopKeyword = false
@@ -168,5 +174,9 @@ open class SqlKeywordGroupBlock(
168174

169175
override fun createGroupIndentLen(): Int = indent.indentLen.plus(topKeywordBlocks.sumOf { it.getNodeText().length.plus(1) }.minus(1))
170176

171-
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean = true
177+
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean {
178+
val prevWord = prevBlocks.lastOrNull()
179+
return !SqlKeywordUtil.isSetLineKeyword(this.getNodeText(), prevWord?.getNodeText() ?: "") &&
180+
!SqlKeywordUtil.isSetLineKeyword(this.getNodeText(), lastGroup?.getNodeText() ?: "")
181+
}
172182
}

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/subgroup/SqlSubGroupBlock.kt

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ abstract class SqlSubGroupBlock(
4343
node,
4444
context,
4545
) {
46+
companion object {
47+
private val NEW_LINE_EXPECTED_TYPES =
48+
listOf(
49+
SqlWithQueryGroupBlock::class,
50+
SqlWithCommonTableGroupBlock::class,
51+
SqlWithColumnGroupBlock::class,
52+
SqlCreateViewGroupBlock::class,
53+
)
54+
}
55+
4656
open val offset = 1
4757

4858
// TODO Even if the first element of a subgroup is a comment,
@@ -112,14 +122,7 @@ abstract class SqlSubGroupBlock(
112122
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean {
113123
lastGroup?.let { lastBlock ->
114124
if (lastBlock is SqlJoinQueriesGroupBlock) return true
115-
val expectedTypes =
116-
listOf(
117-
SqlWithQueryGroupBlock::class,
118-
SqlWithCommonTableGroupBlock::class,
119-
SqlWithColumnGroupBlock::class,
120-
SqlCreateViewGroupBlock::class,
121-
)
122-
return TypeUtil.isExpectedClassType(expectedTypes, lastBlock.parentBlock)
125+
return TypeUtil.isExpectedClassType(NEW_LINE_EXPECTED_TYPES, lastBlock.parentBlock)
123126
}
124127
return false
125128
}

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

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -141,27 +141,10 @@ class SqlCustomSpacingBuilder {
141141
return normalSpacing
142142
}
143143

144-
fun getSpacingRightPattern(block: SqlRightPatternBlock): Spacing? {
145-
val parentBlock = block.parentBlock
146-
147-
if (block.isSaveSpace(null)) {
148-
return getSpacing(block)
149-
}
150-
151-
if (TypeUtil.isExpectedClassType(SqlRightPatternBlock.NEW_LINE_EXPECTED_TYPES, parentBlock)) {
152-
return getSpacing(block)
144+
fun getSpacingRightPattern(block: SqlRightPatternBlock): Spacing? =
145+
when (block.lineBreakAndSpacingType) {
146+
SqlRightPatternBlock.LineBreakAndSpacingType.NONE, SqlRightPatternBlock.LineBreakAndSpacingType.LINE_BREAK -> nonSpacing
147+
SqlRightPatternBlock.LineBreakAndSpacingType.SPACING -> normalSpacing
148+
SqlRightPatternBlock.LineBreakAndSpacingType.LINE_BREAK_AND_SPACING -> getSpacing(block)
153149
}
154-
155-
if (parentBlock is SqlParallelListBlock) {
156-
val lastKeywordGroup = parentBlock.getChildBlocksDropLast().lastOrNull()
157-
return if (lastKeywordGroup is SqlKeywordGroupBlock) {
158-
normalSpacing
159-
} else {
160-
nonSpacing
161-
}
162-
}
163-
164-
if (parentBlock is SqlDataTypeParamBlock || !block.preSpaceRight) return nonSpacing
165-
return normalSpacing
166-
}
167150
}

src/main/kotlin/org/domaframework/doma/intellij/formatter/processor/SqlSetParentGroupProcessor.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,6 @@ class SqlSetParentGroupProcessor(
341341
childBlock,
342342
blockBuilder,
343343
)
344-
345-
if (lastGroupBlock is SqlCommaBlock) {
346-
blockBuilder.removeLastGroupTopNodeIndexHistory()
347-
}
348344
setParentGroups(context) { history ->
349345
if (childBlock.conditionType.isEnd() || childBlock.conditionType.isElse()) {
350346
// remove self and previous conditional directive block

0 commit comments

Comments
 (0)