@@ -26,32 +26,27 @@ import com.intellij.formatting.Wrap
2626import com.intellij.lang.ASTNode
2727import com.intellij.psi.PsiWhiteSpace
2828import com.intellij.psi.formatter.common.AbstractBlock
29- import com.intellij.psi.util.PsiTreeUtil
30- import org.domaframework.doma.intellij.common.util.TypeUtil.isExpectedClassType
3129import org.domaframework.doma.intellij.formatter.block.comment.SqlBlockCommentBlock
3230import org.domaframework.doma.intellij.formatter.block.comment.SqlCommentBlock
3331import org.domaframework.doma.intellij.formatter.block.comment.SqlLineCommentBlock
34- import org.domaframework.doma.intellij.formatter.block.conflict.SqlConflictClauseBlock
35- import org.domaframework.doma.intellij.formatter.block.conflict.SqlDoGroupBlock
3632import org.domaframework.doma.intellij.formatter.block.expr.SqlElBlockCommentBlock
3733import org.domaframework.doma.intellij.formatter.block.expr.SqlElConditionLoopCommentBlock
3834import org.domaframework.doma.intellij.formatter.block.expr.SqlElSymbolBlock
3935import org.domaframework.doma.intellij.formatter.block.group.SqlNewGroupBlock
4036import org.domaframework.doma.intellij.formatter.block.group.column.SqlColumnBlock
4137import org.domaframework.doma.intellij.formatter.block.group.column.SqlColumnDefinitionRawGroupBlock
4238import org.domaframework.doma.intellij.formatter.block.group.column.SqlColumnRawGroupBlock
43- import org.domaframework.doma.intellij.formatter.block.group.column.SqlDataTypeBlock
4439import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlInlineGroupBlock
4540import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlInlineSecondGroupBlock
4641import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlKeywordGroupBlock
47- import org.domaframework.doma.intellij.formatter.block.group.keyword.create.SqlCreateTableColumnDefinitionGroupBlock
48- import org.domaframework.doma.intellij.formatter.block.group.keyword.insert.SqlInsertColumnGroupBlock
4942import org.domaframework.doma.intellij.formatter.block.group.keyword.update.SqlUpdateColumnAssignmentSymbolBlock
5043import org.domaframework.doma.intellij.formatter.block.group.keyword.update.SqlUpdateSetGroupBlock
44+ import org.domaframework.doma.intellij.formatter.block.group.keyword.with.SqlWithColumnGroupBlock
45+ import org.domaframework.doma.intellij.formatter.block.group.keyword.with.SqlWithCommonTableGroupBlock
46+ import org.domaframework.doma.intellij.formatter.block.group.keyword.with.SqlWithQueryGroupBlock
5147import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlDataTypeParamBlock
5248import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlFunctionParamBlock
53- import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlParallelListBlock
54- import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlRightPatternBlock
49+ import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlSubGroupBlock
5550import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlSubQueryGroupBlock
5651import org.domaframework.doma.intellij.formatter.builder.SqlBlockBuilder
5752import org.domaframework.doma.intellij.formatter.builder.SqlCustomSpacingBuilder
@@ -93,6 +88,7 @@ open class SqlBlock(
9388 val blocks = mutableListOf<AbstractBlock >()
9489 open var parentBlock: SqlBlock ? = null
9590 open val childBlocks = mutableListOf<SqlBlock >()
91+
9692 open val indent: ElementIndent =
9793 ElementIndent (
9894 IndentType .FILE ,
@@ -118,8 +114,6 @@ open class SqlBlock(
118114 // This method can be overridden to set additional properties on the parent block if needed.
119115 }
120116
121- open val isNeedWhiteSpace: Boolean = true
122-
123117 open fun addChildBlock (childBlock : SqlBlock ) {
124118 childBlocks.add(childBlock)
125119 }
@@ -137,10 +131,10 @@ open class SqlBlock(
137131 val lastGroup = blockBuilder.getLastGroupTopNodeIndexHistory()
138132 if (child !is PsiWhiteSpace ) {
139133 val childBlock = getBlock(child)
140- updateWhiteSpaceInclude(lastBlock, childBlock, lastGroup)
141134 prevNonWhiteSpaceNode = child
142135 updateCommentParentAndIdent(childBlock)
143136 updateBlockParentAndLAddGroup(childBlock)
137+ updateWhiteSpaceInclude(lastBlock, childBlock, lastGroup)
144138 blocks.add(childBlock)
145139 } else {
146140 if (lastBlock !is SqlLineCommentBlock ) {
@@ -195,88 +189,15 @@ open class SqlBlock(
195189 }
196190 }
197191
192+ open fun isSaveSpace (lastGroup : SqlBlock ? ): Boolean = false
193+
198194 /* *
199195 * Determines whether to retain the space (newline) based on the last registered group or the class of the currently checked element.
200196 */
201197 private fun isSaveWhiteSpace (
202198 childBlock : SqlBlock ,
203199 lastGroup : SqlBlock ? ,
204- ): Boolean {
205- val child = childBlock.node
206-
207- if (! childBlock.isNeedWhiteSpace) return false
208-
209- val expectedClassTypes =
210- listOf (
211- SqlElConditionLoopCommentBlock ::class ,
212- SqlInsertColumnGroupBlock ::class ,
213- SqlColumnDefinitionRawGroupBlock ::class ,
214- SqlCreateTableColumnDefinitionGroupBlock ::class ,
215- SqlUpdateColumnAssignmentSymbolBlock ::class ,
216- SqlDoGroupBlock ::class ,
217- )
218-
219- if (isExpectedClassType(expectedClassTypes, childBlock)) return true
220-
221- if (isNewLineSqlComment(child, childBlock)) return true
222-
223- if (lastGroup is SqlConflictClauseBlock ) return false
224- if (childBlock is SqlColumnRawGroupBlock ) {
225- return ! childBlock.isFirstColumnGroup
226- }
227-
228- return (
229- isNewLineGroupBlockAfterRegistrationChild(childBlock, lastGroup) ||
230- (childBlock is SqlRightPatternBlock && childBlock.isNewLine(lastGroup))
231- )
232- }
233-
234- /* *
235- * Retains the block only for comments that are broken down.
236- */
237- private fun isNewLineSqlComment (
238- child : ASTNode ,
239- childBlock : SqlBlock ,
240- ): Boolean {
241- val commentBlockType =
242- listOf (
243- SqlLineCommentBlock ::class ,
244- SqlBlockCommentBlock ::class ,
245- )
246- val prevSpace = PsiTreeUtil .prevLeaf(child.psi)
247- return isExpectedClassType(
248- commentBlockType,
249- childBlock,
250- ) &&
251- prevSpace?.text?.contains(" \n " ) == true
252- }
253-
254- /* *
255- * Determines whether a newline is required after registering itself as a child of the parent block.
256- */
257- private fun isNewLineGroupBlockAfterRegistrationChild (
258- childBlock : SqlBlock ,
259- lastGroup : SqlBlock ? ,
260- ): Boolean {
261- fun isParallelListRawChild (): Boolean =
262- childBlock is SqlCommaBlock &&
263- (
264- lastGroup is SqlParallelListBlock ||
265- lastGroup?.parentBlock is SqlParallelListBlock
266- )
267-
268- if (isParallelListRawChild()) return false
269-
270- if (parentSetProcessor.isNewGroupAndNotSetLineKeywords(childBlock, lastGroup)) {
271- return if (lastGroup is SqlSubQueryGroupBlock ) {
272- val lastGroupChildren = lastGroup.childBlocks
273- (lastGroupChildren.isNotEmpty() && lastGroupChildren.drop(1 ).isNotEmpty())
274- } else {
275- true
276- }
277- }
278- return false
279- }
200+ ): Boolean = childBlock.isSaveSpace(lastGroup)
280201
281202 /* *
282203 * Updates the parent block or registers itself as a new group block based on the class of the target block.
@@ -349,8 +270,8 @@ open class SqlBlock(
349270 )
350271 }
351272
352- is SqlSubQueryGroupBlock -> {
353- parentSetProcessor.updateGroupBlockParentAndAddGroup (
273+ is SqlSubGroupBlock -> {
274+ parentSetProcessor.updateSubGroupBlockParent (
354275 childBlock,
355276 )
356277 }
@@ -395,6 +316,8 @@ open class SqlBlock(
395316 */
396317 open fun createBlockIndentLen (): Int = 0
397318
319+ open fun createGroupIndentLen (): Int = 0
320+
398321 /* *
399322 * Creates a block for the given child AST node.
400323 */
@@ -449,13 +372,27 @@ open class SqlBlock(
449372 )
450373
451374 SqlTypes .COMMA -> {
452- return blockUtil.getCommaGroupBlock(lastGroup, child)
375+ return if (lastGroup is SqlWithQueryGroupBlock ) {
376+ SqlWithCommonTableGroupBlock (child, defaultFormatCtx)
377+ } else {
378+ blockUtil.getCommaGroupBlock(lastGroup, child)
379+ }
453380 }
454381
455- SqlTypes .WORD -> return blockUtil.getWordBlock(lastGroup, child)
382+ SqlTypes .WORD -> {
383+ return if (lastGroup is SqlWithQueryGroupBlock ) {
384+ SqlWithCommonTableGroupBlock (child, defaultFormatCtx)
385+ } else {
386+ blockUtil.getWordBlock(lastGroup, child)
387+ }
388+ }
456389
457390 SqlTypes .BLOCK_COMMENT -> {
458- return blockUtil.getBlockCommentBlock(child, createBlockCommentSpacingBuilder())
391+ return if (lastGroup is SqlWithCommonTableGroupBlock ) {
392+ SqlWithCommonTableGroupBlock (child, defaultFormatCtx)
393+ } else {
394+ blockUtil.getBlockCommentBlock(child, createBlockCommentSpacingBuilder())
395+ }
459396 }
460397
461398 SqlTypes .LINE_COMMENT ->
@@ -555,6 +492,14 @@ open class SqlBlock(
555492 return SqlCustomSpacingBuilder ().getSpacing(child2)
556493 }
557494
495+ if (child2 is SqlWithColumnGroupBlock ) {
496+ return SqlCustomSpacingBuilder .normalSpacing
497+ }
498+
499+ if (child1 is SqlSubGroupBlock && child2 is SqlSubGroupBlock ) {
500+ return SqlCustomSpacingBuilder .nonSpacing
501+ }
502+
558503 // Do not leave a space after the comment block of the bind variable
559504 if (child1 is SqlElBlockCommentBlock && child1 !is SqlElConditionLoopCommentBlock && child2 !is SqlCommentBlock ) {
560505 return SqlCustomSpacingBuilder .nonSpacing
@@ -587,6 +532,9 @@ open class SqlBlock(
587532 }
588533
589534 if (child2 is SqlNewGroupBlock ) {
535+ if (child1 is SqlSubGroupBlock && child2.indent.indentLevel == IndentType .ATTACHED ) {
536+ return SqlCustomSpacingBuilder .nonSpacing
537+ }
590538 when (child2) {
591539 is SqlSubQueryGroupBlock -> {
592540 if (child1 is SqlNewGroupBlock ) {
0 commit comments