Skip to content

Commit df06d2d

Browse files
committed
Enhance SQL block comment formatting and parsing logic
1 parent 7b2c80d commit df06d2d

File tree

7 files changed

+245
-257
lines changed

7 files changed

+245
-257
lines changed

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ import com.intellij.lang.ASTNode
2121
import com.intellij.psi.formatter.common.AbstractBlock
2222
import org.domaframework.doma.intellij.formatter.block.SqlBlock
2323
import org.domaframework.doma.intellij.formatter.block.SqlUnknownBlock
24+
import org.domaframework.doma.intellij.formatter.block.expr.SqlElSymbolBlock
2425
import org.domaframework.doma.intellij.formatter.builder.SqlCustomSpacingBuilder
2526
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
2627
import org.domaframework.doma.intellij.psi.SqlTypes
2728

2829
open class SqlBlockCommentBlock(
2930
node: ASTNode,
30-
private val customSpacingBuilder: SqlCustomSpacingBuilder,
3131
private val context: SqlBlockFormattingContext,
3232
) : SqlDefaultCommentBlock(
3333
node,
@@ -41,16 +41,15 @@ open class SqlBlockCommentBlock(
4141
SqlTypes.BLOCK_COMMENT_START -> SqlCommentStartBlock(child, context)
4242
SqlTypes.BLOCK_COMMENT_END -> SqlCommentEndBlock(child, context)
4343
SqlTypes.BLOCK_COMMENT_CONTENT -> SqlCommentContentBlock(child, context)
44+
SqlTypes.EL_PARSER_LEVEL_COMMENT -> SqlElSymbolBlock(child, context)
4445
else -> SqlUnknownBlock(child, context)
4546
}
4647
}
4748

48-
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean = hasLineBreakBefore()
49+
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean = true
4950

5051
override fun getSpacing(
5152
child1: Block?,
5253
child2: Block,
53-
): Spacing? =
54-
customSpacingBuilder.getCustomSpacing(child1, child2)
55-
?: SqlCustomSpacingBuilder.normalSpacing
54+
): Spacing? = SqlCustomSpacingBuilder.nonSpacing
5655
}

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

Lines changed: 50 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +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.PsiElement
2122
import com.intellij.psi.formatter.common.AbstractBlock
2223
import com.intellij.psi.util.PsiTreeUtil
2324
import com.intellij.psi.util.elementType
@@ -55,32 +56,25 @@ open class SqlElBlockCommentBlock(
5556
val directiveType: SqlElCommentDirectiveType = initDirectiveType()
5657

5758
private fun initDirectiveType(): SqlElCommentDirectiveType {
58-
val element = this.node.psi
59+
val element = node.psi
5960
val contentElement = PsiTreeUtil.firstChild(element).nextSibling
6061

61-
if (contentElement is SqlElIfDirective ||
62+
return when {
63+
isConditionOrLoopDirective(contentElement) -> SqlElCommentDirectiveType.CONDITION_LOOP
64+
contentElement.elementType == SqlTypes.HASH -> SqlElCommentDirectiveType.EMBEDDED
65+
contentElement.elementType == SqlTypes.EL_EXPAND -> SqlElCommentDirectiveType.EXPAND
66+
contentElement.elementType == SqlTypes.EL_POPULATE -> SqlElCommentDirectiveType.POPULATE
67+
contentElement.elementType == SqlTypes.CARET -> SqlElCommentDirectiveType.LITERAL
68+
else -> SqlElCommentDirectiveType.NORMAL
69+
}
70+
}
71+
72+
private fun isConditionOrLoopDirective(contentElement: PsiElement?): Boolean =
73+
contentElement is SqlElIfDirective ||
6274
contentElement is SqlElForDirective ||
6375
contentElement is SqlElElseifDirective ||
6476
contentElement.elementType == SqlTypes.EL_ELSE ||
6577
contentElement.elementType == SqlTypes.EL_END
66-
) {
67-
return SqlElCommentDirectiveType.CONDITION_LOOP
68-
}
69-
if (contentElement.elementType == SqlTypes.HASH) {
70-
return SqlElCommentDirectiveType.EMBEDDED
71-
}
72-
if (contentElement.elementType == SqlTypes.EL_EXPAND) {
73-
return SqlElCommentDirectiveType.EXPAND
74-
}
75-
if (contentElement.elementType == SqlTypes.EL_POPULATE) {
76-
return SqlElCommentDirectiveType.POPULATE
77-
}
78-
if (contentElement.elementType == SqlTypes.CARET) {
79-
return SqlElCommentDirectiveType.LITERAL
80-
}
81-
82-
return SqlElCommentDirectiveType.NORMAL
83-
}
8478

8579
override fun buildChildren(): MutableList<AbstractBlock> = buildChildBlocks { getBlock(it) }
8680

@@ -91,103 +85,67 @@ open class SqlElBlockCommentBlock(
9185
->
9286
SqlOperationBlock(child, context)
9387

94-
SqlTypes.EL_EQ_EXPR, SqlTypes.EL_NE_EXPR, SqlTypes.EL_GE_EXPR, SqlTypes.EL_GT_EXPR, SqlTypes.EL_LE_EXPR, SqlTypes.EL_LT_EXPR,
95-
SqlTypes.EL_AND_EXPR, SqlTypes.EL_OR_EXPR, SqlTypes.EL_NOT_EXPR,
96-
SqlTypes.EL_ADD_EXPR, SqlTypes.EL_SUBTRACT_EXPR, SqlTypes.EL_MULTIPLY_EXPR, SqlTypes.EL_DIVIDE_EXPR, SqlTypes.EL_MOD_EXPR,
88+
SqlTypes.EL_EQ_EXPR, SqlTypes.EL_NE_EXPR, SqlTypes.EL_GE_EXPR, SqlTypes.EL_GT_EXPR,
89+
SqlTypes.EL_LE_EXPR, SqlTypes.EL_LT_EXPR, SqlTypes.EL_AND_EXPR, SqlTypes.EL_OR_EXPR,
90+
SqlTypes.EL_NOT_EXPR, SqlTypes.EL_ADD_EXPR, SqlTypes.EL_SUBTRACT_EXPR,
91+
SqlTypes.EL_MULTIPLY_EXPR, SqlTypes.EL_DIVIDE_EXPR, SqlTypes.EL_MOD_EXPR,
9792
->
98-
SqlElBlockCommentBlock(
99-
child,
100-
context,
101-
createBlockDirectiveCommentSpacingBuilder(),
102-
)
103-
104-
SqlTypes.EL_FIELD_ACCESS_EXPR ->
105-
SqlElFieldAccessBlock(
106-
child,
107-
context,
108-
)
93+
SqlElBlockCommentBlock(child, context, createBlockDirectiveCommentSpacingBuilder())
10994

95+
SqlTypes.EL_FIELD_ACCESS_EXPR -> SqlElFieldAccessBlock(child, context)
11096
SqlTypes.BLOCK_COMMENT_START -> SqlCommentStartBlock(child, context)
111-
11297
SqlTypes.BLOCK_COMMENT_END -> SqlCommentEndBlock(child, context)
113-
114-
SqlTypes.EL_STATIC_FIELD_ACCESS_EXPR ->
115-
SqlElStaticFieldAccessBlock(
116-
child,
117-
context,
118-
)
119-
120-
SqlTypes.EL_FUNCTION_CALL_EXPR ->
121-
SqlElFunctionCallBlock(
122-
child,
123-
context,
124-
)
125-
126-
SqlTypes.BLOCK_COMMENT_CONTENT ->
127-
SqlBlockCommentBlock(child, createBlockCommentSpacingBuilder(), context)
128-
98+
SqlTypes.EL_STATIC_FIELD_ACCESS_EXPR -> SqlElStaticFieldAccessBlock(child, context)
99+
SqlTypes.EL_FUNCTION_CALL_EXPR -> SqlElFunctionCallBlock(child, context)
100+
SqlTypes.BLOCK_COMMENT_CONTENT -> SqlBlockCommentBlock(child, context)
129101
else -> SqlUnknownBlock(child, context)
130102
}
131103

132-
protected fun createBlockCommentSpacingBuilder(): SqlCustomSpacingBuilder =
133-
SqlCustomSpacingBuilder()
134-
.withSpacing(
135-
SqlTypes.BLOCK_COMMENT_START,
136-
SqlTypes.BLOCK_COMMENT_CONTENT,
137-
Spacing.createSpacing(1, 1, 0, false, 0),
138-
)
104+
protected fun createBlockCommentSpacingBuilder(): SqlCustomSpacingBuilder {
105+
val noSpacing = Spacing.createSpacing(0, 0, 0, false, 0)
106+
val singleSpace = Spacing.createSpacing(1, 1, 0, false, 0)
107+
108+
return SqlCustomSpacingBuilder()
109+
.withSpacing(SqlTypes.BLOCK_COMMENT_START, SqlTypes.BLOCK_COMMENT_CONTENT, singleSpace)
110+
.withSpacing(SqlTypes.BLOCK_COMMENT_START, SqlTypes.EL_PARSER_LEVEL_COMMENT, noSpacing)
111+
.withSpacing(SqlTypes.EL_PARSER_LEVEL_COMMENT, SqlTypes.BLOCK_COMMENT_CONTENT, noSpacing)
112+
}
139113

140114
override fun createBlockDirectiveCommentSpacingBuilder(): SqlCustomSpacingBuilder = createBlockCommentSpacingBuilder()
141115

142116
override fun getSpacing(
143117
child1: Block?,
144118
child2: Block,
145119
): Spacing? =
146-
customSpacingBuilder?.getCustomSpacing(child1, child2) ?: spacingBuilder.getSpacing(
147-
this,
148-
child1,
149-
child2,
150-
)
120+
customSpacingBuilder?.getCustomSpacing(child1, child2)
121+
?: spacingBuilder.getSpacing(this, child1, child2)
151122

152123
override fun isLeaf(): Boolean = false
153124

154-
override fun createBlockIndentLen(): Int {
125+
override fun createBlockIndentLen(): Int =
155126
parentBlock?.let { parent ->
156-
return when (parent) {
127+
when (parent) {
157128
is SqlElConditionLoopCommentBlock -> parent.indent.groupIndentLen
158-
is SqlSubQueryGroupBlock -> {
159-
if (parent.getChildBlocksDropLast().isEmpty()) {
160-
if (isConditionLoopDirectiveRegisteredBeforeParent()) {
161-
parent.indent.groupIndentLen
162-
} else {
163-
parent.indent.groupIndentLen
164-
}
165-
} else if (parent.isFirstLineComment) {
166-
parent.indent.groupIndentLen.minus(2)
167-
} else {
168-
parent.indent.groupIndentLen
169-
}
170-
}
129+
is SqlSubQueryGroupBlock -> calculateSubQueryIndent(parent)
171130
is SqlValuesGroupBlock -> parent.indent.indentLen
172-
is SqlKeywordGroupBlock -> parent.indent.groupIndentLen.plus(1)
131+
is SqlKeywordGroupBlock -> parent.indent.groupIndentLen + 1
173132
else -> parent.indent.groupIndentLen
174133
}
134+
} ?: 0
135+
136+
private fun calculateSubQueryIndent(parent: SqlSubQueryGroupBlock): Int =
137+
when {
138+
parent.getChildBlocksDropLast().isEmpty() -> parent.indent.groupIndentLen
139+
parent.isFirstLineComment -> parent.indent.groupIndentLen - 2
140+
else -> parent.indent.groupIndentLen
175141
}
176-
return 0
177-
}
178142

179143
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean =
180144
parentBlock?.let { parent ->
181-
isConditionLoopDirectiveRegisteredBeforeParent() ||
182-
(
183-
(
184-
parent is SqlWithQuerySubGroupBlock ||
185-
parent is SqlValuesGroupBlock ||
186-
parent is SqlElConditionLoopCommentBlock
187-
) &&
188-
parent.childBlocks
189-
.dropLast(1)
190-
.none { it !is SqlElConditionLoopCommentBlock }
191-
)
145+
isConditionLoopDirectiveRegisteredBeforeParent() || isParentWithOnlyConditionLoopBlocks(parent)
192146
} == true
147+
148+
private fun isParentWithOnlyConditionLoopBlocks(parent: SqlBlock): Boolean =
149+
(parent is SqlWithQuerySubGroupBlock || parent is SqlValuesGroupBlock || parent is SqlElConditionLoopCommentBlock) &&
150+
parent.childBlocks.dropLast(1).none { it !is SqlElConditionLoopCommentBlock }
193151
}

0 commit comments

Comments
 (0)