diff --git a/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/SqlBlock.kt b/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/SqlBlock.kt index b4a9facb..8baa2450 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/SqlBlock.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/SqlBlock.kt @@ -357,6 +357,38 @@ open class SqlBlock( return builder } + protected fun calculatePrevBlocksLength( + children: List, + parent: SqlBlock, + ): Int { + // Add the parent's text length to the indentation if the parent is a conditional loop directive. + val directiveParentIndent = + if (parent is SqlElConditionLoopCommentBlock) { + parent.parentBlock + ?.getNodeText() + ?.length ?: 0 + } else { + 0 + } + + return children + .filter { it !is SqlDefaultCommentBlock && it !is SqlElConditionLoopCommentBlock } + .sumOf { prev -> + prev + .getChildrenTextLen() + .plus( + if (prev.node.elementType == SqlTypes.DOT || + prev.node.elementType == SqlTypes.RIGHT_PAREN + ) { + 0 + } else { + prev.getNodeText().length.plus(1) + }, + ) + }.plus(parent.indent.groupIndentLen) + .plus(directiveParentIndent) + } + /** * Returns the child indentation for the block. * diff --git a/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/condition/SqlConditionKeywordGroupBlock.kt b/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/condition/SqlConditionKeywordGroupBlock.kt index 18277162..6d6be7c8 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/condition/SqlConditionKeywordGroupBlock.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/condition/SqlConditionKeywordGroupBlock.kt @@ -19,6 +19,7 @@ import com.intellij.lang.ASTNode import org.domaframework.doma.intellij.formatter.block.SqlBlock import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock import org.domaframework.doma.intellij.formatter.block.group.keyword.option.SqlSecondOptionKeywordGroupBlock +import org.domaframework.doma.intellij.formatter.block.group.keyword.second.SqlWhereGroupBlock import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlSubGroupBlock import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext @@ -63,4 +64,14 @@ class SqlConditionKeywordGroupBlock( } } ?: return 1 } + + override fun createGroupIndentLen(): Int { + parentBlock?.let { parent -> + if (parent is SqlWhereGroupBlock) { + return indent.indentLen.plus(getNodeText().length) + } + return super.createGroupIndentLen() + } + return 0 + } } diff --git a/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/condition/SqlConditionalExpressionGroupBlock.kt b/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/condition/SqlConditionalExpressionGroupBlock.kt index d4fcb177..9a95441f 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/condition/SqlConditionalExpressionGroupBlock.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/condition/SqlConditionalExpressionGroupBlock.kt @@ -62,7 +62,7 @@ class SqlConditionalExpressionGroupBlock( } groupIndentLen + directiveParentTextLen } else { - parent.indent.groupIndentLen.plus(1) + calculatePrevBlocksLength(prevBlocks, parent).plus(1) } } ?: offset diff --git a/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/option/SqlInGroupBlock.kt b/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/option/SqlInGroupBlock.kt index c36e24ae..1e429f24 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/option/SqlInGroupBlock.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/keyword/option/SqlInGroupBlock.kt @@ -17,12 +17,10 @@ package org.domaframework.doma.intellij.formatter.block.group.keyword.option import com.intellij.lang.ASTNode import org.domaframework.doma.intellij.formatter.block.SqlBlock -import org.domaframework.doma.intellij.formatter.block.comment.SqlDefaultCommentBlock import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlKeywordGroupBlock import org.domaframework.doma.intellij.formatter.util.IndentType import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext -import org.domaframework.doma.intellij.psi.SqlTypes class SqlInGroupBlock( node: ASTNode, @@ -45,28 +43,7 @@ class SqlInGroupBlock( ) { return parent.indent.indentLen } - val prevChildren = this.prevBlocks - val children = prevChildren.filter { it !is SqlDefaultCommentBlock } - val firstChild = children.firstOrNull() - val sumChildren = - if (firstChild is SqlElConditionLoopCommentBlock) { - children.drop(1).dropLastWhile { it == this } - } else { - children - } - - val dotCount = sumChildren.count { it.node.elementType == SqlTypes.DOT } - val parentText = (parent as? SqlElConditionLoopCommentBlock)?.parentBlock?.getNodeText()?.length ?: 0 - - return sumChildren - .sumOf { prev -> - prev - .getChildrenTextLen() - .plus(prev.getNodeText().length.plus(1)) - }.minus(dotCount * 2) - .plus(parent.indent.groupIndentLen) - .plus(parentText) - .plus(1) + return calculatePrevBlocksLength(prevBlocks, parent).plus(1) } return 0 } diff --git a/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/word/SqlFunctionGroupBlock.kt b/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/word/SqlFunctionGroupBlock.kt index bbe8d724..036b309f 100644 --- a/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/word/SqlFunctionGroupBlock.kt +++ b/src/main/kotlin/org/domaframework/doma/intellij/formatter/block/word/SqlFunctionGroupBlock.kt @@ -50,25 +50,6 @@ class SqlFunctionGroupBlock( return baseIndent.plus(getNodeText().length) } - private fun calculatePrevBlocksLength( - children: List, - parent: SqlBlock, - ): Int = - children - .sumOf { prev -> - prev - .getChildrenTextLen() - .plus( - if (prev.node.elementType == SqlTypes.DOT || - prev.node.elementType == SqlTypes.RIGHT_PAREN - ) { - 0 - } else { - prev.getNodeText().length.plus(1) - }, - ) - }.plus(parent.indent.groupIndentLen) - private fun calculateBaseIndent( parent: SqlBlock, prevBlocksLength: Int, diff --git a/src/test/kotlin/org/domaframework/doma/intellij/formatter/SqlFormatterTest.kt b/src/test/kotlin/org/domaframework/doma/intellij/formatter/SqlFormatterTest.kt index 078c4d7a..ce035893 100644 --- a/src/test/kotlin/org/domaframework/doma/intellij/formatter/SqlFormatterTest.kt +++ b/src/test/kotlin/org/domaframework/doma/intellij/formatter/SqlFormatterTest.kt @@ -166,6 +166,10 @@ class SqlFormatterTest : BasePlatformTestCase() { formatSqlFile("WithDelete.sql", "WithDelete$formatDataPrefix.sql") } + fun testDeleteWithSubQuery() { + formatSqlFile("DeleteWithSubQuery.sql", "DeleteWithSubQuery$formatDataPrefix.sql") + } + fun testNestedDirectivesFormatter() { formatSqlFile("NestedDirectives.sql", "NestedDirectives$formatDataPrefix.sql") } diff --git a/src/test/testData/sql/formatter/DeleteWithSubQuery.sql b/src/test/testData/sql/formatter/DeleteWithSubQuery.sql new file mode 100644 index 00000000..b79297f0 --- /dev/null +++ b/src/test/testData/sql/formatter/DeleteWithSubQuery.sql @@ -0,0 +1,11 @@ +DELETE FROM user_session s + WHERE s.count = ( SELECT COUNT(*) + FROM user u + WHERE u.id = /* id */1 + AND u.session_id = u.id + AND u.time_stamp < /* current */'2099-12-31 00:00:00' ) + OR EXISTS ( SELECT u.id + FROM user u + WHERE u.id = /* id */1 +AND u.session_id = u.id +AND u.time_stamp < /* current */'2099-12-31 00:00:00') \ No newline at end of file diff --git a/src/test/testData/sql/formatter/DeleteWithSubQuery_format.sql b/src/test/testData/sql/formatter/DeleteWithSubQuery_format.sql new file mode 100644 index 00000000..9786eb04 --- /dev/null +++ b/src/test/testData/sql/formatter/DeleteWithSubQuery_format.sql @@ -0,0 +1,11 @@ +DELETE FROM user_session s + WHERE s.count = ( SELECT COUNT(*) + FROM user u + WHERE u.id = /* id */1 + AND u.session_id = u.id + AND u.time_stamp < /* current */'2099-12-31 00:00:00' ) + OR EXISTS ( SELECT u.id + FROM user u + WHERE u.id = /* id */1 + AND u.session_id = u.id + AND u.time_stamp < /* current */'2099-12-31 00:00:00' )