Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ open class SqlBlock(
var indentLevel: IndentType,
/**
* The number of indentation spaces for this element.
*
* Returns `0` if there is no line break.
*/
var indentLen: Int,
/**
* Indentation baseline applied to the group itself.
*
* Even if the group does not start on a new line,
* it determines and applies indentation to the group based on factors such as the number of preceding characters.
*/
Expand All @@ -81,6 +83,48 @@ open class SqlBlock(

private fun isExcludedFromTextLength(block: SqlBlock): Boolean = block.node.elementType in setOf(SqlTypes.DOT, SqlTypes.RIGHT_PAREN)

/**
* Checks if a conditional loop directive is registered before the parent block.
*
* @note
* If the next element after a conditional directive is not a conditional directive block,
* the directive becomes a child of the next element block.
* Therefore, if the first element in [childBlocks] is a conditional directive,
* it can be determined that—syntactically—the conditional directive was placed immediately before the current block.
*/
protected fun isConditionLoopDirectiveRegisteredBeforeParent(): Boolean {
val firstPrevBlock = (prevBlocks.lastOrNull() as? SqlElConditionLoopCommentBlock)
parentBlock?.let { parent ->
return firstPrevBlock != null &&
firstPrevBlock.conditionEnd != null &&
firstPrevBlock.node.startOffset > parent.node.startOffset
}
return false
}

/**
* Determines if this is the element immediately after a conditional loop directive.
*
* @note
* The parent conditional loop directive becomes a child of the element immediately after the conditional loop directive.
* In the following case, "%if" is a child of "status", and the following "=" and "'pending'" are children of "%if".
* Therefore, set the condition to break line only when the parent of the conditional loop directive is a group block.
*
* @example
* ```sql
* WHERE
* /*%if status == "pending" */
* status = 'pending'
* ```
*/
protected fun isElementAfterConditionLoopDirective(): Boolean =
(parentBlock as? SqlElConditionLoopCommentBlock)?.let { parent ->
parent.childBlocks.firstOrNull() == this &&
(parent.parentBlock is SqlNewGroupBlock || parent.parentBlock is SqlElConditionLoopCommentBlock)
} == true

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

fun getChildBlocksDropLast(
dropIndex: Int = 1,
skipCommentBlock: Boolean = true,
Expand Down Expand Up @@ -121,31 +165,17 @@ open class SqlBlock(
fun isEnableFormat(): Boolean = enableFormat

open fun isSaveSpace(lastGroup: SqlBlock?): Boolean =
parentBlock?.let { parent ->
when (parent) {
is SqlElConditionLoopCommentBlock -> shouldSaveSpaceForConditionLoop(parent)
is SqlNewGroupBlock -> shouldSaveSpaceForNewGroup(parent)
else -> false
when (lastGroup) {
is SqlNewGroupBlock -> shouldSaveSpaceForNewGroup(lastGroup)
else -> {
shouldSaveSpaceForConditionLoop()
}
} == true

private fun shouldSaveSpaceForConditionLoop(parent: SqlElConditionLoopCommentBlock): Boolean {
val prevBlock = prevBlocks.lastOrNull { it !is SqlDefaultCommentBlock }
val isPrevBlockElseOrEnd =
prevBlock is SqlElConditionLoopCommentBlock &&
(prevBlock.conditionType.isElse() || prevBlock.conditionType.isEnd())
val hasNoChildrenExceptLast = parent.childBlocks.dropLast(1).isEmpty()
if (parent.conditionType.isElse()) {
return prevBlocks.isEmpty()
}

val isConditionDirectiveParentGroup =
parent.parentBlock?.let { grand ->
grand is SqlNewGroupBlock
} == true

return isPrevBlockElseOrEnd || (hasNoChildrenExceptLast && isConditionDirectiveParentGroup)
}
private fun shouldSaveSpaceForConditionLoop(): Boolean =
isConditionLoopDirectiveRegisteredBeforeParent() ||
isElementAfterConditionLoopDirective() ||
isFirstChildConditionLoopDirective()

private fun shouldSaveSpaceForNewGroup(parent: SqlNewGroupBlock): Boolean {
val prevWord = prevBlocks.lastOrNull { it !is SqlCommentBlock }
Expand Down Expand Up @@ -174,6 +204,8 @@ open class SqlBlock(

/**
* Creates the indentation length for the block.
*
* @return The number of spaces to use for indentation
*/
open fun createBlockIndentLen(): Int = 0

Expand All @@ -183,18 +215,24 @@ open class SqlBlock(

/**
* Creates a spacing builder for custom spacing rules.
*
* @return A new instance of SqlCustomSpacingBuilder
*/
protected open fun createSpacingBuilder(): SqlCustomSpacingBuilder = SqlCustomSpacingBuilder()

override fun buildChildren(): List<Block?>? = emptyList()

/**
* Determines whether to adjust the indentation on pressing Enter.
*
* @return true if indentation should be adjusted on Enter, false otherwise
*/
fun isAdjustIndentOnEnter(): Boolean = formatMode == FormattingMode.ADJUST_INDENT_ON_ENTER && !isEnableFormat()

/**
* Returns the indentation for the block.
*
* @return The indent to apply to this block, or null if no indentation should be applied
*/
override fun getIndent(): Indent? =
if (isAdjustIndentOnEnter()) {
Expand All @@ -210,6 +248,8 @@ open class SqlBlock(

/**
* Returns the child indentation for the block.
*
* @return The indent to apply to child blocks
*/
override fun getChildIndent(): Indent? =
if (isEnableFormat()) {
Expand All @@ -224,6 +264,8 @@ open class SqlBlock(

/**
* Determines whether the block is a leaf node.
*
* @return true if this block has no child nodes, false otherwise
*/
override fun isLeaf(): Boolean = myNode.firstChildNode == null
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ open class SqlCommaBlock(
super.setParentGroupBlock(lastGroup)
indent.indentLevel = IndentType.COMMA
indent.indentLen = createBlockIndentLen()
indent.groupIndentLen = indent.indentLen.plus(getNodeText().length)
indent.groupIndentLen = createGroupIndentLen()
}

override fun setParentPropertyBlock(lastGroup: SqlBlock?) {
Expand Down Expand Up @@ -142,6 +142,8 @@ open class SqlCommaBlock(
return 1
}

override fun createGroupIndentLen(): Int = indent.indentLen.plus(1)

override fun isSaveSpace(lastGroup: SqlBlock?): Boolean {
if (parentBlock is SqlConditionalExpressionGroupBlock) return false
return TypeUtil.isExpectedClassType(EXPECTED_TYPES, parentBlock)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ import org.domaframework.doma.intellij.formatter.block.word.SqlFunctionGroupBloc
import org.domaframework.doma.intellij.formatter.block.word.SqlTableBlock
import org.domaframework.doma.intellij.formatter.block.word.SqlWordBlock
import org.domaframework.doma.intellij.formatter.builder.SqlBlockBuilder
import org.domaframework.doma.intellij.formatter.builder.SqlBlockRelationBuilder
import org.domaframework.doma.intellij.formatter.builder.SqlCustomSpacingBuilder
import org.domaframework.doma.intellij.formatter.handler.CreateClauseHandler
import org.domaframework.doma.intellij.formatter.processor.SqlSetParentGroupProcessor
import org.domaframework.doma.intellij.formatter.util.IndentType
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
import org.domaframework.doma.intellij.formatter.util.SqlBlockGenerator
Expand Down Expand Up @@ -96,7 +96,7 @@ open class SqlFileBlock(
private val blocks = mutableListOf<AbstractBlock>()

private val blockBuilder = SqlBlockBuilder()
private val parentSetProcessor = SqlSetParentGroupProcessor(blockBuilder)
private val blockRelationBuilder = SqlBlockRelationBuilder(blockBuilder)
private val blockUtil = SqlBlockGenerator(this, isEnableFormat(), formatMode)

private val pendingCommentBlocks = mutableListOf<SqlBlock>()
Expand Down Expand Up @@ -150,6 +150,7 @@ open class SqlFileBlock(
formatMode,
)
val lastGroup = blockBuilder.getLastGroupTopNodeIndexHistory()
val lastGroupFilteredDirective = blockBuilder.getLastGroupFilterDirective()
return when (child.elementType) {
SqlTypes.KEYWORD -> {
return blockUtil.getKeywordBlock(
Expand Down Expand Up @@ -218,10 +219,20 @@ open class SqlFileBlock(
}

SqlTypes.BLOCK_COMMENT -> {
val tempBlock =
blockUtil.getBlockCommentBlock(
child,
createBlockDirectiveCommentSpacingBuilder(),
)
if (tempBlock !is SqlElConditionLoopCommentBlock) {
if (lastGroup is SqlWithQueryGroupBlock || lastGroupFilteredDirective is SqlWithQueryGroupBlock) {
return SqlWithCommonTableGroupBlock(child, defaultFormatCtx)
}
}
return if (lastGroup is SqlWithCommonTableGroupBlock) {
SqlWithCommonTableGroupBlock(child, defaultFormatCtx)
} else {
blockUtil.getBlockCommentBlock(child, createBlockDirectiveCommentSpacingBuilder())
tempBlock
}
}

Expand Down Expand Up @@ -309,7 +320,7 @@ open class SqlFileBlock(
val lastGroupBlock = blockBuilder.getLastGroupTopNodeIndexHistory()
val lastIndentLevel = lastGroupBlock?.indent?.indentLevel
if (lastGroupBlock == null || lastIndentLevel == null) {
parentSetProcessor.updateGroupBlockAddGroup(
blockRelationBuilder.updateGroupBlockAddGroup(
childBlock,
)
return
Expand All @@ -319,81 +330,81 @@ open class SqlFileBlock(

when (childBlock) {
is SqlKeywordGroupBlock -> {
parentSetProcessor.updateKeywordGroupBlockParentAndAddGroup(
blockRelationBuilder.updateKeywordGroupBlockParentAndAddGroup(
lastGroupBlock,
lastIndentLevel,
childBlock,
)
}

is SqlColumnDefinitionRawGroupBlock -> {
parentSetProcessor.updateColumnDefinitionRawGroupBlockParentAndAddGroup(
blockRelationBuilder.updateColumnDefinitionRawGroupBlockParentAndAddGroup(
lastGroupBlock,
lastIndentLevel,
childBlock,
)
}

is SqlColumnRawGroupBlock -> {
parentSetProcessor.updateColumnRawGroupBlockParentAndAddGroup(
blockRelationBuilder.updateColumnRawGroupBlockParentAndAddGroup(
lastGroupBlock,
childBlock,
)
}

is SqlInlineGroupBlock -> {
// case-end
parentSetProcessor.updateGroupBlockParentAndAddGroup(
blockRelationBuilder.updateGroupBlockParentAndAddGroup(
childBlock,
)
}

is SqlInlineSecondGroupBlock -> {
parentSetProcessor.updateInlineSecondGroupBlockParentAndAddGroup(
blockRelationBuilder.updateInlineSecondGroupBlockParentAndAddGroup(
childBlock,
)
}

is SqlColumnBlock -> {
parentSetProcessor.updateGroupBlockParentAndAddGroup(
blockRelationBuilder.updateGroupBlockParentAndAddGroup(
childBlock,
)
}

is SqlElConditionLoopCommentBlock -> {
parentSetProcessor.updateConditionLoopCommentBlockParent(
blockRelationBuilder.updateConditionLoopCommentBlockParent(
lastGroupBlock,
childBlock,
)
}

is SqlWordBlock, is SqlOtherBlock -> {
parentSetProcessor.updateGroupBlockParentAndAddGroup(
blockRelationBuilder.updateGroupBlockParentAndAddGroup(
childBlock,
)
}

is SqlSubGroupBlock -> {
parentSetProcessor.updateSubGroupBlockParent(
blockRelationBuilder.updateSubGroupBlockParent(
lastGroupBlock,
childBlock,
)
}

is SqlRightPatternBlock -> {
parentSetProcessor.updateSqlRightPatternBlockParent(
blockRelationBuilder.updateSqlRightPatternBlockParent(
childBlock,
)
}

is SqlElSymbolBlock -> {
parentSetProcessor.updateGroupBlockParentAndAddGroup(
blockRelationBuilder.updateGroupBlockParentAndAddGroup(
childBlock,
)
}

is SqlDataTypeBlock -> {
parentSetProcessor.updateGroupBlockParentAndAddGroup(
blockRelationBuilder.updateGroupBlockParentAndAddGroup(
childBlock,
)
}
Expand All @@ -402,13 +413,13 @@ open class SqlFileBlock(
if (lastGroupBlock is SqlCommaBlock) {
blockBuilder.removeLastGroupTopNodeIndexHistory()
}
parentSetProcessor.updateGroupBlockParentAndAddGroup(
blockRelationBuilder.updateGroupBlockParentAndAddGroup(
childBlock,
)
}

else -> {
parentSetProcessor.updateGroupBlockParentAndAddGroup(
blockRelationBuilder.updateGroupBlockParentAndAddGroup(
childBlock,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlDataTyp
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlFunctionParamBlock
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlSubGroupBlock
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlSubQueryGroupBlock
import org.domaframework.doma.intellij.formatter.block.group.subgroup.SqlValuesParamGroupBlock
import org.domaframework.doma.intellij.formatter.util.IndentType
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext

Expand Down Expand Up @@ -136,7 +137,7 @@ open class SqlRightPatternBlock(
}

// Default case
preSpaceRight = false
preSpaceRight = parentBlock is SqlValuesParamGroupBlock
}

override val indent =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,5 @@ abstract class SqlCommentBlock(
return 0
}

override fun createGroupIndentLen(): Int = 0
override fun createGroupIndentLen(): Int = indent.indentLen
}
Loading
Loading