Skip to content

Commit 7b2c80d

Browse files
authored
Merge pull request #435 from domaframework/fix/sql-format-top-keyword-space
Add Formatting Support for Table Modification Queries
2 parents d45b6ba + 77daacb commit 7b2c80d

27 files changed

+431
-128
lines changed

src/main/java/org/domaframework/doma/intellij/tokens/SqlKeywordTokenUtil.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class SqlKeywordTokenUtil {
3535
"between",
3636
"breadth",
3737
"by",
38+
"cascade",
3839
"case",
3940
"change",
4041
"check",
@@ -95,6 +96,7 @@ public class SqlKeywordTokenUtil {
9596
"recursive",
9697
"references",
9798
"rename",
99+
"restrict",
98100
"returning",
99101
"right",
100102
"row",

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,10 @@ open class SqlFileBlock(
462462
val childBlock1: SqlBlock? = child1 as? SqlBlock
463463
val childBlock2: SqlBlock = child2 as SqlBlock
464464

465+
if (childBlock1 == null) {
466+
return SqlCustomSpacingBuilder.nonSpacing
467+
}
468+
465469
// The end of a line comment element is a newline, so just add a space for the indent.
466470
if (childBlock1 is SqlLineCommentBlock) {
467471
return SqlCustomSpacingBuilder().getSpacing(childBlock2)
@@ -544,7 +548,7 @@ open class SqlFileBlock(
544548
}
545549
}
546550

547-
if (childBlock1?.node?.elementType == SqlTypes.DOT ||
551+
if (childBlock1.node.elementType == SqlTypes.DOT ||
548552
childBlock2.node.elementType == SqlTypes.DOT
549553
) {
550554
return SqlCustomSpacingBuilder.nonSpacing
@@ -588,7 +592,7 @@ open class SqlFileBlock(
588592
}
589593

590594
is SqlFunctionParamBlock -> {
591-
return if (childBlock1?.node?.elementType in listOf(SqlTypes.FUNCTION_NAME, SqlTypes.WORD)) {
595+
return if (childBlock1.node.elementType in listOf(SqlTypes.FUNCTION_NAME, SqlTypes.WORD)) {
592596
SqlCustomSpacingBuilder.nonSpacing
593597
} else {
594598
SqlCustomSpacingBuilder.normalSpacing
@@ -617,7 +621,7 @@ open class SqlFileBlock(
617621
?.let { return it }
618622
}
619623

620-
if (childBlock1 is SqlBlock && (childBlock2 is SqlCommaBlock || childBlock2 is SqlColumnRawGroupBlock)) {
624+
if (childBlock2 is SqlCommaBlock || childBlock2 is SqlColumnRawGroupBlock) {
621625
SqlCustomSpacingBuilder()
622626
.getSpacingWithIndentComma(childBlock1, childBlock2)
623627
?.let { return it }

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import org.domaframework.doma.intellij.formatter.block.group.keyword.insert.SqlI
2727
import org.domaframework.doma.intellij.formatter.block.group.keyword.insert.SqlInsertValueGroupBlock
2828
import org.domaframework.doma.intellij.formatter.block.group.keyword.second.SqlFromGroupBlock
2929
import org.domaframework.doma.intellij.formatter.block.group.keyword.second.SqlSecondKeywordBlock
30+
import org.domaframework.doma.intellij.formatter.block.group.keyword.second.SqlTableModifySecondGroupBlock
3031
import org.domaframework.doma.intellij.formatter.block.group.keyword.second.SqlValuesGroupBlock
3132
import org.domaframework.doma.intellij.formatter.block.group.keyword.update.SqlUpdateColumnGroupBlock
3233
import org.domaframework.doma.intellij.formatter.block.group.keyword.update.SqlUpdateSetGroupBlock
@@ -144,6 +145,16 @@ open class SqlCommaBlock(
144145
val parentIndent = firstChild?.indent ?: parent.indent
145146
parentIndent.groupIndentLen.plus(1)
146147
}
148+
is SqlTableModifySecondGroupBlock -> {
149+
val grand = parent.parentBlock
150+
if (grand is SqlElConditionLoopCommentBlock ||
151+
parent.childBlocks.firstOrNull() is SqlElConditionLoopCommentBlock
152+
) {
153+
parent.indent.indentLen.plus(2)
154+
} else {
155+
parent.indent.indentLen
156+
}
157+
}
147158
else -> {
148159
// No indent after ORDER BY within function parameters
149160
val grand = parent.parentBlock
@@ -181,7 +192,8 @@ open class SqlCommaBlock(
181192
if (conditionParent is SqlFunctionParamBlock) {
182193
return false
183194
}
184-
return TypeUtil.isExpectedClassType(EXPECTED_TYPES, parent)
195+
return TypeUtil.isExpectedClassType(EXPECTED_TYPES, parent) ||
196+
childBlocks.firstOrNull() is SqlElConditionLoopCommentBlock
185197
}
186198
return false
187199
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package org.domaframework.doma.intellij.formatter.block.conflict
1818
import com.intellij.lang.ASTNode
1919
import org.domaframework.doma.intellij.formatter.block.SqlBlock
2020
import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlKeywordGroupBlock
21+
import org.domaframework.doma.intellij.formatter.block.group.keyword.second.SqlTableModifySecondGroupBlock
2122
import org.domaframework.doma.intellij.formatter.util.IndentType
2223
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
2324

@@ -36,7 +37,7 @@ class SqlDoGroupBlock(
3637

3738
override fun setParentGroupBlock(lastGroup: SqlBlock?) {
3839
super.setParentGroupBlock(lastGroup)
39-
indent.indentLen = 0
40+
indent.indentLen = createBlockIndentLen()
4041
indent.groupIndentLen = getNodeText().length
4142
}
4243

@@ -46,5 +47,13 @@ class SqlDoGroupBlock(
4647
}
4748
}
4849

50+
override fun createBlockIndentLen(): Int {
51+
val prevBlock = prevBlocks.lastOrNull()
52+
if (prevBlock is SqlTableModifySecondGroupBlock) {
53+
return prevBlock.indent.indentLen
54+
}
55+
return 0
56+
}
57+
4958
override fun isSaveSpace(lastGroup: SqlBlock?) = true
5059
}

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/column/SqlColumnRawGroupBlock.kt

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ package org.domaframework.doma.intellij.formatter.block.group.column
1717

1818
import com.intellij.lang.ASTNode
1919
import org.domaframework.doma.intellij.formatter.block.SqlBlock
20+
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
21+
import org.domaframework.doma.intellij.formatter.block.group.keyword.second.SqlTableModifySecondGroupBlock
2022
import org.domaframework.doma.intellij.formatter.block.group.keyword.top.SqlSelectQueryGroupBlock
2123
import org.domaframework.doma.intellij.formatter.block.group.keyword.update.SqlUpdateColumnGroupBlock
2224
import org.domaframework.doma.intellij.formatter.block.group.keyword.with.SqlWithQueryGroupBlock
@@ -56,15 +58,31 @@ class SqlColumnRawGroupBlock(
5658
}
5759

5860
override fun createBlockIndentLen(): Int =
59-
if (parentBlock is SqlWithQueryGroupBlock) {
60-
parentBlock
61-
?.childBlocks
62-
?.dropLast(1)
63-
?.lastOrNull()
64-
?.indent
65-
?.indentLen ?: offset
66-
} else {
67-
parentBlock?.indent?.groupIndentLen?.plus(1) ?: offset
61+
when (parentBlock) {
62+
is SqlWithQueryGroupBlock -> {
63+
parentBlock
64+
?.childBlocks
65+
?.dropLast(1)
66+
?.lastOrNull()
67+
?.indent
68+
?.indentLen ?: offset
69+
}
70+
71+
is SqlTableModifySecondGroupBlock -> {
72+
parentBlock?.let { parent ->
73+
val grand = parent.parentBlock
74+
if (grand is SqlElConditionLoopCommentBlock ||
75+
parent.childBlocks.firstOrNull() is SqlElConditionLoopCommentBlock
76+
) {
77+
parent.indent.indentLen.plus(2)
78+
} else {
79+
parent.indent.indentLen
80+
}
81+
} ?: offset
82+
}
83+
84+
else ->
85+
parentBlock?.indent?.groupIndentLen?.plus(1) ?: offset
6886
}
6987

7088
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean = !isFirstColumnGroup

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,9 @@ open class SqlKeywordGroupBlock(
176176
} ?: return 1
177177
}
178178

179-
override fun createGroupIndentLen(): Int = indent.indentLen.plus(topKeywordBlocks.sumOf { it.getNodeText().length.plus(1) }.minus(1))
179+
override fun createGroupIndentLen(): Int = indent.indentLen.plus(getTotalTopKeywordLength())
180+
181+
fun getTotalTopKeywordLength(): Int = topKeywordBlocks.sumOf { it.getNodeText().length.plus(1) }.minus(1)
180182

181183
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean {
182184
val conditionLastGroup =

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

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package org.domaframework.doma.intellij.formatter.block.group.keyword.condition
1818
import com.intellij.lang.ASTNode
1919
import org.domaframework.doma.intellij.formatter.block.SqlBlock
2020
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
21+
import org.domaframework.doma.intellij.formatter.block.group.keyword.create.SqlCreateKeywordGroupBlock
2122
import org.domaframework.doma.intellij.formatter.block.group.keyword.option.SqlSecondOptionKeywordGroupBlock
2223
import org.domaframework.doma.intellij.formatter.block.group.keyword.second.SqlWhereGroupBlock
2324
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlSubGroupBlock
@@ -49,22 +50,23 @@ class SqlConditionKeywordGroupBlock(
4950

5051
// If AND appears after OR, change it so that it is right-justified.
5152
override fun createBlockIndentLen(): Int {
52-
parentBlock?.let { parent ->
53-
val groupLen = parent.indent.groupIndentLen
54-
return if (parent is SqlElConditionLoopCommentBlock) {
55-
parent.indent.groupIndentLen
56-
} else if (parent is SqlSubGroupBlock) {
57-
if (getNodeText() == "and") {
58-
groupLen
59-
} else {
60-
groupLen.plus(1)
61-
}
62-
} else {
63-
return parent.indent.groupIndentLen.minus(getNodeText().length)
64-
}
65-
} ?: return 1
53+
val parent = parentBlock ?: return 1
54+
val groupLen = parent.indent.groupIndentLen
55+
56+
return when (parent) {
57+
is SqlElConditionLoopCommentBlock -> parent.indent.groupIndentLen
58+
is SqlSubGroupBlock -> calculateSubGroupIndent(groupLen)
59+
else -> parent.indent.groupIndentLen - getNodeText().length
60+
}
6661
}
6762

63+
private fun calculateSubGroupIndent(groupLen: Int): Int =
64+
if (getNodeText() == "and") {
65+
groupLen
66+
} else {
67+
groupLen + 1
68+
}
69+
6870
override fun createGroupIndentLen(): Int {
6971
parentBlock?.let { parent ->
7072
if (parent is SqlWhereGroupBlock) {
@@ -74,4 +76,11 @@ class SqlConditionKeywordGroupBlock(
7476
}
7577
return 0
7678
}
79+
80+
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean {
81+
if (lastGroup is SqlCreateKeywordGroupBlock) {
82+
return false
83+
}
84+
return super.isSaveSpace(lastGroup)
85+
}
7786
}

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ import com.intellij.lang.ASTNode
1919
import org.domaframework.doma.intellij.formatter.block.SqlBlock
2020
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
2121
import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlKeywordGroupBlock
22-
import org.domaframework.doma.intellij.formatter.block.group.keyword.create.SqlCreateTableColumnDefinitionRawGroupBlock
22+
import org.domaframework.doma.intellij.formatter.block.group.keyword.create.SqlCreateKeywordGroupBlock
23+
import org.domaframework.doma.intellij.formatter.block.group.keyword.second.SqlTableModifySecondGroupBlock
24+
import org.domaframework.doma.intellij.formatter.block.group.keyword.top.SqlTableModificationKeyword
2325
import org.domaframework.doma.intellij.formatter.util.IndentType
2426
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
2527

@@ -44,11 +46,14 @@ class SqlExistsGroupBlock(
4446

4547
override fun createGroupIndentLen(): Int {
4648
val parentGroupIndent = parentBlock?.indent?.groupIndentLen ?: 0
47-
return topKeywordBlocks.sumOf { it.getNodeText().length.plus(1) }.plus(parentGroupIndent).minus(1)
49+
return getTotalTopKeywordLength().plus(parentGroupIndent)
4850
}
4951

5052
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean {
51-
if (lastGroup is SqlCreateTableColumnDefinitionRawGroupBlock) {
53+
if (lastGroup is SqlTableModificationKeyword ||
54+
lastGroup is SqlTableModifySecondGroupBlock ||
55+
lastGroup is SqlCreateKeywordGroupBlock
56+
) {
5257
return false
5358
}
5459
return super.isSaveSpace(lastGroup)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright Doma Tools Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.domaframework.doma.intellij.formatter.block.group.keyword.second
17+
18+
import com.intellij.lang.ASTNode
19+
import org.domaframework.doma.intellij.formatter.block.SqlBlock
20+
import org.domaframework.doma.intellij.formatter.block.group.column.SqlColumnRawGroupBlock
21+
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
22+
23+
class SqlTableModifySecondGroupBlock(
24+
node: ASTNode,
25+
context: SqlBlockFormattingContext,
26+
) : SqlSecondKeywordBlock(
27+
node,
28+
context,
29+
) {
30+
override fun createBlockIndentLen(): Int {
31+
val prevBlock = prevBlocks.lastOrNull()
32+
if (prevBlock is SqlTableModifySecondGroupBlock) {
33+
return prevBlock.indent.indentLen
34+
}
35+
36+
return super.createBlockIndentLen()
37+
}
38+
39+
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean = parentBlock !is SqlColumnRawGroupBlock
40+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright Doma Tools Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.domaframework.doma.intellij.formatter.block.group.keyword.top
17+
18+
import com.intellij.lang.ASTNode
19+
import org.domaframework.doma.intellij.formatter.block.SqlBlock
20+
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
21+
import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlKeywordGroupBlock
22+
import org.domaframework.doma.intellij.formatter.util.IndentType
23+
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
24+
25+
class SqlTableModificationKeyword(
26+
node: ASTNode,
27+
context: SqlBlockFormattingContext,
28+
) : SqlTopQueryGroupBlock(
29+
node,
30+
context,
31+
) {
32+
override fun setParentGroupBlock(lastGroup: SqlBlock?) {
33+
super.setParentGroupBlock(lastGroup)
34+
indent.indentLen = createBlockIndentLen()
35+
indent.groupIndentLen = createGroupIndentLen()
36+
}
37+
38+
override fun createBlockIndentLen(): Int {
39+
return parentBlock?.let { parent ->
40+
val rootBlock =
41+
if (parent is SqlElConditionLoopCommentBlock) {
42+
parent.tempParentBlock
43+
} else if (parent.indent.indentLevel == IndentType.FILE) {
44+
null
45+
} else {
46+
parent
47+
}
48+
49+
return if (rootBlock is SqlKeywordGroupBlock) {
50+
rootBlock.getTotalTopKeywordLength().minus(getNodeText().length)
51+
} else {
52+
rootBlock?.indent?.groupIndentLen ?: 0
53+
}
54+
} ?: 0
55+
}
56+
57+
override fun createGroupIndentLen(): Int =
58+
parentBlock?.let { parent ->
59+
if (parent is SqlElConditionLoopCommentBlock) {
60+
parent.indent.indentLen
61+
} else {
62+
getTotalTopKeywordLength()
63+
}
64+
} ?: getTotalTopKeywordLength()
65+
}

0 commit comments

Comments
 (0)