@@ -65,23 +65,19 @@ open class SqlBlock(
6565 open val childBlocks = mutableListOf<SqlBlock >()
6666 open var prevBlocks = emptyList<SqlBlock >()
6767
68- fun getChildrenTextLen (): Int =
69- childBlocks.sumOf { child ->
70- val children =
71- child.childBlocks.filter { it !is SqlDefaultCommentBlock }
72- if (children.isNotEmpty()) {
73- child
74- .getChildrenTextLen()
75- .plus(child.getNodeText().length)
76- } else if (child.node.elementType == SqlTypes .DOT ||
77- child.node.elementType == SqlTypes .RIGHT_PAREN
78- ) {
79- // Since elements do not include surrounding spaces, they should be excluded from the character count.
80- 0
81- } else {
82- child.getNodeText().length.plus(1 )
83- }
68+ fun getChildrenTextLen (): Int = childBlocks.sumOf { child -> calculateChildTextLength(child) }
69+
70+ private fun calculateChildTextLength (child : SqlBlock ): Int {
71+ val nonCommentChildren = child.childBlocks.filterNot { it is SqlDefaultCommentBlock }
72+
73+ return when {
74+ nonCommentChildren.isNotEmpty() -> child.getChildrenTextLen() + child.getNodeText().length
75+ isExcludedFromTextLength(child) -> 0
76+ else -> child.getNodeText().length + 1
8477 }
78+ }
79+
80+ private fun isExcludedFromTextLength (block : SqlBlock ): Boolean = block.node.elementType in setOf (SqlTypes .DOT , SqlTypes .RIGHT_PAREN )
8581
8682 fun getChildBlocksDropLast (
8783 dropIndex : Int = 1,
@@ -122,34 +118,48 @@ open class SqlBlock(
122118
123119 fun isEnableFormat (): Boolean = enableFormat
124120
125- open fun isSaveSpace (lastGroup : SqlBlock ? ): Boolean {
121+ open fun isSaveSpace (lastGroup : SqlBlock ? ): Boolean =
126122 parentBlock?.let { parent ->
127- if (parent is SqlElConditionLoopCommentBlock ) {
128- val prevBlock =
129- prevBlocks.lastOrNull { it !is SqlDefaultCommentBlock }
130- return prevBlock is SqlElConditionLoopCommentBlock &&
131- (prevBlock.conditionType.isElse() || prevBlock.conditionType.isEnd()) ||
132- parent.childBlocks.dropLast(1 ).isEmpty()
133- }
134- // Checks for non-breaking keyword combinations, ignoring comment blocks
135- if (parent is SqlNewGroupBlock ) {
136- val prevWord = prevBlocks.lastOrNull { it !is SqlCommentBlock }
137- if (SqlKeywordUtil .isSetLineKeyword(getNodeText(), parent.getNodeText()) ||
138- SqlKeywordUtil .isSetLineKeyword(getNodeText(), prevWord?.getNodeText() ? : " " )
139- ) {
140- return false
141- }
142- // Breaks a line if it is a child of itself or preceded by a condition/loop directive
143- return childBlocks.lastOrNull() is SqlElConditionLoopCommentBlock ||
144- (
145- prevBlocks.lastOrNull() is SqlElConditionLoopCommentBlock &&
146- prevBlocks
147- .last()
148- .node.psi.startOffset > parent.node.psi.startOffset
149- )
123+ when (parent) {
124+ is SqlElConditionLoopCommentBlock -> shouldSaveSpaceForConditionLoop(parent)
125+ is SqlNewGroupBlock -> shouldSaveSpaceForNewGroup(parent)
126+ else -> false
150127 }
128+ } ? : false
129+
130+ private fun shouldSaveSpaceForConditionLoop (parent : SqlElConditionLoopCommentBlock ): Boolean {
131+ val prevBlock = prevBlocks.lastOrNull { it !is SqlDefaultCommentBlock }
132+ val isPrevBlockElseOrEnd =
133+ prevBlock is SqlElConditionLoopCommentBlock &&
134+ (prevBlock.conditionType.isElse() || prevBlock.conditionType.isEnd())
135+ val hasNoChildrenExceptLast = parent.childBlocks.dropLast(1 ).isEmpty()
136+
137+ return isPrevBlockElseOrEnd || hasNoChildrenExceptLast
138+ }
139+
140+ private fun shouldSaveSpaceForNewGroup (parent : SqlNewGroupBlock ): Boolean {
141+ val prevWord = prevBlocks.lastOrNull { it !is SqlCommentBlock }
142+
143+ if (isNonBreakingKeywordCombination(parent, prevWord)) {
144+ return false
151145 }
152- return false
146+
147+ return isFollowedByConditionLoop() || isPrecededByConditionLoop(parent)
148+ }
149+
150+ private fun isNonBreakingKeywordCombination (
151+ parent : SqlNewGroupBlock ,
152+ prevWord : SqlBlock ? ,
153+ ): Boolean =
154+ SqlKeywordUtil .isSetLineKeyword(getNodeText(), parent.getNodeText()) ||
155+ SqlKeywordUtil .isSetLineKeyword(getNodeText(), prevWord?.getNodeText() ? : " " )
156+
157+ private fun isFollowedByConditionLoop (): Boolean = childBlocks.lastOrNull() is SqlElConditionLoopCommentBlock
158+
159+ private fun isPrecededByConditionLoop (parent : SqlNewGroupBlock ): Boolean {
160+ val lastPrevBlock = prevBlocks.lastOrNull()
161+ return lastPrevBlock is SqlElConditionLoopCommentBlock &&
162+ lastPrevBlock.node.psi.startOffset > parent.node.psi.startOffset
153163 }
154164
155165 /* *
@@ -193,11 +203,15 @@ open class SqlBlock(
193203 */
194204 override fun getChildIndent (): Indent ? =
195205 if (isEnableFormat()) {
196- Indent .getSpaceIndent(4 )
206+ Indent .getSpaceIndent(DEFAULT_INDENT_SIZE )
197207 } else {
198208 Indent .getSpaceIndent(0 )
199209 }
200210
211+ companion object {
212+ private const val DEFAULT_INDENT_SIZE = 4
213+ }
214+
201215 /* *
202216 * Determines whether the block is a leaf node.
203217 */
0 commit comments