Skip to content

Commit 2c55788

Browse files
committed
Implement formatting rules for syntax handling array-type parameters
1 parent f8ba20a commit 2c55788

File tree

18 files changed

+460
-107
lines changed

18 files changed

+460
-107
lines changed

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,19 @@ open class SqlBlock(
123123
(parent.parentBlock is SqlNewGroupBlock || parent.parentBlock is SqlElConditionLoopCommentBlock)
124124
} == true
125125

126-
protected fun isElementAfterConditionLoopEnd(): Boolean =
127-
(
126+
protected fun isElementAfterConditionLoopEnd(): Boolean {
127+
val prevChildren =
128128
prevBlocks
129-
.lastOrNull()
129+
.firstOrNull()
130130
?.childBlocks
131-
?.firstOrNull() as? SqlElConditionLoopCommentBlock
132-
)?.conditionEnd != null
131+
132+
val firstConditionBlock = (prevChildren?.firstOrNull() as? SqlElConditionLoopCommentBlock)
133+
val endBlock = firstConditionBlock?.conditionEnd
134+
if (endBlock == null) return false
135+
val lastBlock = prevChildren.lastOrNull()
136+
137+
return endBlock.node.startOffset > (lastBlock?.node?.startOffset ?: 0)
138+
}
133139

134140
protected fun isFirstChildConditionLoopDirective(): Boolean = childBlocks.firstOrNull() is SqlElConditionLoopCommentBlock
135141

@@ -265,7 +271,7 @@ open class SqlBlock(
265271
/**
266272
* Creates a spacing builder specifically for directive block comments.
267273
*/
268-
protected fun createBlockDirectiveCommentSpacingBuilder(): SqlCustomSpacingBuilder =
274+
protected open fun createBlockDirectiveCommentSpacingBuilder(): SqlCustomSpacingBuilder =
269275
SqlCustomSpacingBuilder()
270276
.withSpacing(
271277
SqlTypes.BLOCK_COMMENT_START,

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

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@ import org.domaframework.doma.intellij.formatter.block.group.keyword.update.SqlU
4848
import org.domaframework.doma.intellij.formatter.block.group.keyword.with.SqlWithColumnGroupBlock
4949
import org.domaframework.doma.intellij.formatter.block.group.keyword.with.SqlWithCommonTableGroupBlock
5050
import org.domaframework.doma.intellij.formatter.block.group.keyword.with.SqlWithQueryGroupBlock
51+
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlArrayListGroupBlock
5152
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlDataTypeParamBlock
5253
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlFunctionParamBlock
5354
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlSubGroupBlock
5455
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlSubQueryGroupBlock
5556
import org.domaframework.doma.intellij.formatter.block.other.SqlEscapeBlock
5657
import org.domaframework.doma.intellij.formatter.block.other.SqlOtherBlock
5758
import org.domaframework.doma.intellij.formatter.block.word.SqlAliasBlock
59+
import org.domaframework.doma.intellij.formatter.block.word.SqlArrayWordBlock
5860
import org.domaframework.doma.intellij.formatter.block.word.SqlFunctionGroupBlock
5961
import org.domaframework.doma.intellij.formatter.block.word.SqlTableBlock
6062
import org.domaframework.doma.intellij.formatter.block.word.SqlWordBlock
@@ -106,14 +108,14 @@ open class SqlFileBlock(
106108
if (isLeaf) return mutableListOf()
107109

108110
var child = node.firstChildNode
109-
var prevNonWhiteSpaceNode: ASTNode? = null
111+
var prevNonWhiteSpaceNode: SqlBlock? = null
110112
blockBuilder.addGroupTopNodeIndexHistory(this)
111113
while (child != null) {
112114
val lastBlock = blocks.lastOrNull()
113115
val lastGroup = blockBuilder.getLastGroupTopNodeIndexHistory()
114116
if (child !is PsiWhiteSpace) {
115-
val childBlock = getBlock(child)
116-
prevNonWhiteSpaceNode = child
117+
val childBlock = getBlock(child, prevNonWhiteSpaceNode)
118+
prevNonWhiteSpaceNode = childBlock
117119
updateCommentParentAndIdent(childBlock)
118120
updateBlockParentAndLAddGroup(childBlock)
119121
updateWhiteSpaceInclude(lastBlock, childBlock, lastGroup)
@@ -141,7 +143,10 @@ open class SqlFileBlock(
141143
/**
142144
* Creates a block for the given child AST node.
143145
*/
144-
override fun getBlock(child: ASTNode): SqlBlock {
146+
private fun getBlock(
147+
child: ASTNode,
148+
prevBlock: SqlBlock?,
149+
): SqlBlock {
145150
val defaultFormatCtx =
146151
SqlBlockFormattingContext(
147152
wrap,
@@ -182,10 +187,17 @@ open class SqlFileBlock(
182187
} else {
183188
val escapeStrings = listOf("\"", "`", "[", "]")
184189
if (escapeStrings.contains(child.text)) {
185-
SqlEscapeBlock(
186-
child,
187-
defaultFormatCtx,
188-
)
190+
if (child.text == "[" && prevBlock is SqlArrayWordBlock) {
191+
SqlArrayListGroupBlock(
192+
child,
193+
defaultFormatCtx,
194+
)
195+
} else {
196+
SqlEscapeBlock(
197+
child,
198+
defaultFormatCtx,
199+
)
200+
}
189201
} else {
190202
SqlOtherBlock(
191203
child,
@@ -379,6 +391,25 @@ open class SqlFileBlock(
379391
)
380392
}
381393

394+
is SqlEscapeBlock -> {
395+
val index =
396+
if (lastGroupBlock is SqlArrayListGroupBlock) {
397+
blockBuilder.getGroupTopNodeIndex {
398+
it is SqlArrayListGroupBlock
399+
}
400+
} else {
401+
-1
402+
}
403+
blockRelationBuilder.updateGroupBlockParentAndAddGroup(
404+
childBlock,
405+
)
406+
if (lastGroupBlock is SqlArrayListGroupBlock) {
407+
if (index >= 0) {
408+
blockBuilder.clearSubListGroupTopNodeIndexHistory(index)
409+
}
410+
}
411+
}
412+
382413
is SqlWordBlock, is SqlOtherBlock -> {
383414
blockRelationBuilder.updateGroupBlockParentAndAddGroup(
384415
childBlock,
@@ -462,6 +493,10 @@ open class SqlFileBlock(
462493
)
463494
}
464495

496+
if (childBlock1 is SqlArrayWordBlock && childBlock2 is SqlArrayListGroupBlock) {
497+
return SqlCustomSpacingBuilder.nonSpacing
498+
}
499+
465500
if (childBlock2 is SqlWithColumnGroupBlock) {
466501
return SqlCustomSpacingBuilder.normalSpacing
467502
}
@@ -495,6 +530,10 @@ open class SqlFileBlock(
495530
SqlCustomSpacingBuilder().getSpacing(childBlock2)
496531
}
497532

533+
is SqlArrayListGroupBlock -> {
534+
SqlCustomSpacingBuilder.nonSpacing
535+
}
536+
498537
else -> SqlCustomSpacingBuilder.normalSpacing
499538
}
500539
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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.comma
17+
18+
import com.intellij.lang.ASTNode
19+
import com.intellij.psi.formatter.common.AbstractBlock
20+
import org.domaframework.doma.intellij.formatter.block.SqlBlock
21+
import org.domaframework.doma.intellij.formatter.block.SqlCommaBlock
22+
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
23+
import org.domaframework.doma.intellij.formatter.util.IndentType
24+
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
25+
26+
class SqlArrayCommaBlock(
27+
node: ASTNode,
28+
context: SqlBlockFormattingContext,
29+
) : SqlCommaBlock(
30+
node,
31+
context,
32+
) {
33+
override val indent =
34+
ElementIndent(
35+
IndentType.NONE,
36+
0,
37+
0,
38+
)
39+
40+
override fun setParentGroupBlock(lastGroup: SqlBlock?) {
41+
super.setParentGroupBlock(lastGroup)
42+
indent.indentLevel = IndentType.NONE
43+
indent.indentLen = createBlockIndentLen()
44+
indent.groupIndentLen = createGroupIndentLen()
45+
}
46+
47+
override fun buildChildren(): MutableList<AbstractBlock> = mutableListOf()
48+
49+
override fun createBlockIndentLen(): Int = 0
50+
51+
override fun createGroupIndentLen(): Int = indent.indentLen.plus(1)
52+
53+
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean = parentBlock is SqlElConditionLoopCommentBlock
54+
}

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

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ package org.domaframework.doma.intellij.formatter.block.comment
1818
import com.intellij.formatting.Block
1919
import com.intellij.formatting.Spacing
2020
import com.intellij.lang.ASTNode
21-
import com.intellij.psi.PsiWhiteSpace
2221
import com.intellij.psi.formatter.common.AbstractBlock
23-
import com.intellij.psi.util.PsiTreeUtil
24-
import org.domaframework.doma.intellij.common.util.StringUtil
2522
import org.domaframework.doma.intellij.formatter.block.SqlBlock
2623
import org.domaframework.doma.intellij.formatter.block.SqlUnknownBlock
2724
import org.domaframework.doma.intellij.formatter.builder.SqlCustomSpacingBuilder
@@ -36,18 +33,7 @@ open class SqlBlockCommentBlock(
3633
node,
3734
context,
3835
) {
39-
override fun buildChildren(): MutableList<AbstractBlock> {
40-
val blocks = mutableListOf<AbstractBlock>()
41-
var child = node.firstChildNode
42-
while (child != null) {
43-
if (child !is PsiWhiteSpace) {
44-
val block = getBlock(child)
45-
blocks.add(block)
46-
}
47-
child = child.treeNext
48-
}
49-
return blocks
50-
}
36+
override fun buildChildren(): MutableList<AbstractBlock> = buildChildBlocks { getBlock(it) }
5137

5238
override fun getBlock(child: ASTNode): SqlBlock {
5339
val elementType = child.elementType
@@ -59,8 +45,7 @@ open class SqlBlockCommentBlock(
5945
}
6046
}
6147

62-
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean =
63-
PsiTreeUtil.prevLeaf(node.psi)?.text?.contains(StringUtil.LINE_SEPARATE) == true
48+
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean = hasLineBreakBefore()
6449

6550
override fun getSpacing(
6651
child1: Block?,

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

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
package org.domaframework.doma.intellij.formatter.block.comment
1717

1818
import com.intellij.lang.ASTNode
19+
import com.intellij.psi.PsiWhiteSpace
1920
import com.intellij.psi.formatter.common.AbstractBlock
21+
import com.intellij.psi.util.PsiTreeUtil
22+
import org.domaframework.doma.intellij.common.util.StringUtil
2023
import org.domaframework.doma.intellij.formatter.block.SqlBlock
2124
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlSubGroupBlock
2225
import org.domaframework.doma.intellij.formatter.util.IndentType
@@ -33,11 +36,16 @@ abstract class SqlCommentBlock(
3336
context.enableFormat,
3437
context.formatMode,
3538
) {
39+
companion object {
40+
const val DEFAULT_INDENT = 0
41+
const val SINGLE_INDENT = 1
42+
}
43+
3644
override val indent =
3745
ElementIndent(
3846
IndentType.NONE,
39-
0,
40-
0,
47+
DEFAULT_INDENT,
48+
DEFAULT_INDENT,
4149
)
4250

4351
override fun setParentGroupBlock(lastGroup: SqlBlock?) {
@@ -53,14 +61,29 @@ abstract class SqlCommentBlock(
5361

5462
override fun createBlockIndentLen(): Int {
5563
parentBlock?.let { parent ->
56-
if (parent.parentBlock !is SqlSubGroupBlock ||
57-
parent.parentBlock?.childBlocks?.size != 1
58-
) {
64+
if (shouldInheritParentIndent(parent)) {
5965
return parent.indent.indentLen
6066
}
6167
}
62-
return 0
68+
return DEFAULT_INDENT
6369
}
6470

6571
override fun createGroupIndentLen(): Int = indent.indentLen
72+
73+
protected open fun shouldInheritParentIndent(parent: SqlBlock): Boolean =
74+
parent.parentBlock !is SqlSubGroupBlock || parent.parentBlock?.childBlocks?.size != 1
75+
76+
fun hasLineBreakBefore(): Boolean = PsiTreeUtil.prevLeaf(node.psi)?.text?.contains(StringUtil.LINE_SEPARATE) == true
77+
78+
protected fun buildChildBlocks(blockProvider: (ASTNode) -> SqlBlock): MutableList<AbstractBlock> {
79+
val blocks = mutableListOf<AbstractBlock>()
80+
var child = node.firstChildNode
81+
while (child != null) {
82+
if (child !is PsiWhiteSpace) {
83+
blocks.add(blockProvider(child))
84+
}
85+
child = child.treeNext
86+
}
87+
return blocks
88+
}
6689
}

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

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ package org.domaframework.doma.intellij.formatter.block.comment
1717

1818
import com.intellij.lang.ASTNode
1919
import com.intellij.psi.formatter.common.AbstractBlock
20-
import com.intellij.psi.util.PsiTreeUtil
21-
import org.domaframework.doma.intellij.common.util.StringUtil
2220
import org.domaframework.doma.intellij.formatter.block.SqlBlock
2321
import org.domaframework.doma.intellij.formatter.util.IndentType
2422
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
@@ -27,15 +25,19 @@ abstract class SqlDefaultCommentBlock(
2725
node: ASTNode,
2826
context: SqlBlockFormattingContext,
2927
) : SqlCommentBlock(node, context) {
28+
companion object {
29+
private const val FILE_TOP_THRESHOLD = 2
30+
}
31+
3032
/**
3133
* If this block is the last element, the indentation update process is not called,
3234
* so set the default indentation to 1.
3335
*/
3436
override val indent =
3537
ElementIndent(
3638
IndentType.NONE,
37-
1,
38-
1,
39+
SINGLE_INDENT,
40+
SINGLE_INDENT,
3941
)
4042

4143
override fun buildChildren(): MutableList<AbstractBlock> = mutableListOf()
@@ -50,16 +52,18 @@ abstract class SqlDefaultCommentBlock(
5052
baseBlock: SqlBlock,
5153
groupBlockCount: Int,
5254
) {
53-
indent.indentLen =
54-
if (isSaveSpace(parentBlock)) {
55-
baseBlock.indent.indentLen
56-
} else if (groupBlockCount <= 2) {
57-
// If it is the top of the file, the indent number should be 0.
58-
0
59-
} else {
60-
1
61-
}
55+
indent.indentLen = calculateIndentForUpdate(baseBlock, groupBlockCount)
6256
}
6357

64-
override fun isSaveSpace(lastGroup: SqlBlock?) = PsiTreeUtil.prevLeaf(node.psi)?.text?.contains(StringUtil.LINE_SEPARATE) == true
58+
private fun calculateIndentForUpdate(
59+
baseBlock: SqlBlock,
60+
groupBlockCount: Int,
61+
): Int =
62+
when {
63+
isSaveSpace(parentBlock) -> baseBlock.indent.indentLen
64+
groupBlockCount <= FILE_TOP_THRESHOLD -> DEFAULT_INDENT
65+
else -> SINGLE_INDENT
66+
}
67+
68+
override fun isSaveSpace(lastGroup: SqlBlock?) = hasLineBreakBefore()
6569
}

0 commit comments

Comments
 (0)