Skip to content

Commit 6a26654

Browse files
authored
Merge pull request #409 from domaframework/fix/sql-formatter-incorrect-formatting-function-in-condition-directive
Formatting of SQL Function Parameters with Keyword Elements
2 parents 7b39e02 + 638527b commit 6a26654

File tree

15 files changed

+184
-35
lines changed

15 files changed

+184
-35
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ open class SqlBlock(
139139
val firstConditionBlock = (prevChildren?.firstOrNull() as? SqlElConditionLoopCommentBlock)
140140
val endBlock = firstConditionBlock?.conditionEnd
141141
if (endBlock == null) return false
142-
val lastBlock = prevChildren.lastOrNull()
142+
val lastBlock = prevBlocks.lastOrNull()
143143

144144
return endBlock.node.startOffset > (lastBlock?.node?.startOffset ?: 0)
145145
}

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ import com.intellij.formatting.Wrap
2626
import com.intellij.lang.ASTNode
2727
import com.intellij.psi.PsiWhiteSpace
2828
import com.intellij.psi.formatter.common.AbstractBlock
29+
import com.intellij.psi.util.PsiTreeUtil
30+
import com.intellij.psi.util.elementType
31+
import com.intellij.psi.util.nextLeaf
32+
import com.intellij.psi.util.nextLeafs
2933
import org.domaframework.doma.intellij.common.util.TypeUtil
34+
import org.domaframework.doma.intellij.formatter.block.comma.SqlCommaBlock
3035
import org.domaframework.doma.intellij.formatter.block.comment.SqlCommentBlock
3136
import org.domaframework.doma.intellij.formatter.block.comment.SqlDefaultCommentBlock
3237
import org.domaframework.doma.intellij.formatter.block.comment.SqlElBlockCommentBlock
@@ -220,8 +225,23 @@ open class SqlFileBlock(
220225
}
221226
}
222227

223-
SqlTypes.FUNCTION_NAME ->
224-
return SqlFunctionGroupBlock(child, defaultFormatCtx)
228+
SqlTypes.FUNCTION_NAME -> {
229+
val notWhiteSpaceElement =
230+
child.psi.nextLeafs
231+
.takeWhile { it is PsiWhiteSpace }
232+
.lastOrNull()
233+
?.nextLeaf(true)
234+
if (notWhiteSpaceElement?.elementType == SqlTypes.LEFT_PAREN ||
235+
PsiTreeUtil.nextLeaf(child.psi)?.elementType == SqlTypes.LEFT_PAREN
236+
) {
237+
return SqlFunctionGroupBlock(child, defaultFormatCtx)
238+
}
239+
return SqlKeywordBlock(
240+
child,
241+
IndentType.ATTACHED,
242+
defaultFormatCtx,
243+
)
244+
}
225245

226246
SqlTypes.WORD -> {
227247
return if (lastGroup is SqlWithQueryGroupBlock) {

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/comma/SqlArrayCommaBlock.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package org.domaframework.doma.intellij.formatter.block.comma
1818
import com.intellij.lang.ASTNode
1919
import com.intellij.psi.formatter.common.AbstractBlock
2020
import org.domaframework.doma.intellij.formatter.block.SqlBlock
21-
import org.domaframework.doma.intellij.formatter.block.SqlCommaBlock
2221
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
2322
import org.domaframework.doma.intellij.formatter.util.IndentType
2423
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/SqlCommaBlock.kt renamed to src/main/kotlin/org/domaframework/doma/intellij/formatter/block/comma/SqlCommaBlock.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.domaframework.doma.intellij.formatter.block
16+
package org.domaframework.doma.intellij.formatter.block.comma
1717

1818
import com.intellij.lang.ASTNode
1919
import com.intellij.psi.formatter.common.AbstractBlock
2020
import org.domaframework.doma.intellij.common.util.TypeUtil
21+
import org.domaframework.doma.intellij.formatter.block.SqlBlock
2122
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
2223
import org.domaframework.doma.intellij.formatter.block.group.column.SqlColumnRawGroupBlock
2324
import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlKeywordGroupBlock
@@ -135,8 +136,15 @@ open class SqlCommaBlock(
135136
}
136137
return parentIndentLen.plus(1)
137138
} else {
138-
if (parent is SqlValuesGroupBlock) return parent.indent.indentLen
139-
return parent.indent.groupIndentLen.plus(1)
139+
return when (parent) {
140+
is SqlValuesGroupBlock -> parent.indent.indentLen
141+
is SqlElConditionLoopCommentBlock -> {
142+
val firstChild = parent.childBlocks.findLast { it is SqlFunctionParamBlock && it.endPatternBlock == null }
143+
val parentIndent = firstChild?.indent ?: parent.indent
144+
parentIndent.groupIndentLen.plus(1)
145+
}
146+
else -> parent.indent.groupIndentLen.plus(1)
147+
}
140148
}
141149
}
142150
return 1

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/group/subgroup/SqlFunctionParamBlock.kt

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import com.intellij.lang.ASTNode
1919
import org.domaframework.doma.intellij.formatter.block.SqlBlock
2020
import org.domaframework.doma.intellij.formatter.block.comment.SqlDefaultCommentBlock
2121
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
22+
import org.domaframework.doma.intellij.formatter.block.expr.SqlElAtSignBlock
23+
import org.domaframework.doma.intellij.formatter.block.expr.SqlElSymbolBlock
24+
import org.domaframework.doma.intellij.formatter.block.other.SqlOtherBlock
2225
import org.domaframework.doma.intellij.formatter.block.word.SqlFunctionGroupBlock
2326
import org.domaframework.doma.intellij.formatter.util.IndentType
2427
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
@@ -79,22 +82,45 @@ class SqlFunctionParamBlock(
7982
}
8083

8184
override fun createGroupIndentLen(): Int {
82-
val parentFunctionName = parentBlock as? SqlFunctionGroupBlock
83-
parentFunctionName?.let { parent ->
84-
return parent.indent.groupIndentLen
85-
.plus(getNodeText().length)
86-
}
87-
85+
val parentGroupIndent = parentBlock?.indent?.groupIndentLen ?: 0
8886
val prevChildrenDropLast =
8987
prevChildren?.dropLast(1)?.filter {
9088
it !is SqlDefaultCommentBlock &&
9189
it.node.elementType != SqlTypes.DOT
9290
}
9391
?: emptyList()
92+
val parentText =
93+
if (parentBlock is SqlElConditionLoopCommentBlock) {
94+
val grand = parentBlock?.parentBlock
95+
grand?.getNodeText() ?: ""
96+
} else {
97+
""
98+
}
9499
val prevLength =
95100
prevChildrenDropLast
96-
.sumOf { it.getNodeText().length }
97-
.plus(getNodeText().length)
98-
return prevLength.plus(prevChildrenDropLast.count()).plus(1)
101+
.sumOf {
102+
it.getChildrenTextLen().plus(it.getNodeText().length)
103+
}.plus(getNodeText().length)
104+
105+
// Avoid unnecessary spaces when operators are consecutive
106+
val consecutiveSymbolCount =
107+
calculateConsecutiveSymbolCount(prevChildrenDropLast)
108+
val spaces = prevChildrenDropLast.count().minus(consecutiveSymbolCount)
109+
return prevLength.plus(spaces).plus(parentText.length).plus(parentGroupIndent)
110+
}
111+
112+
private fun calculateConsecutiveSymbolCount(prevChildrenDropLast: List<SqlBlock>): Int {
113+
var count = 0
114+
var total = 0
115+
for (block in prevChildrenDropLast) {
116+
if (block is SqlOtherBlock || block is SqlElAtSignBlock || block is SqlElSymbolBlock) {
117+
count++
118+
} else {
119+
if (count > 1) total++
120+
count = 0
121+
}
122+
}
123+
if (count > 1) total += count
124+
return total
99125
}
100126
}

src/main/kotlin/org/domaframework/doma/intellij/formatter/block/word/SqlFunctionGroupBlock.kt

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ class SqlFunctionGroupBlock(
3737
indent.groupIndentLen = createGroupIndentLen()
3838
}
3939

40-
override fun createBlockIndentLen(): Int {
40+
override fun createBlockIndentLen(): Int = parentBlock?.indent?.groupIndentLen ?: 0
41+
42+
override fun createGroupIndentLen(): Int {
43+
var baseIndent = 0
4144
parentBlock?.let { parent ->
4245
val children = prevChildren.dropLast(1).filter { it !is SqlDefaultCommentBlock }
4346
val prevBlocksLength =
@@ -55,15 +58,14 @@ class SqlFunctionGroupBlock(
5558
},
5659
)
5760
}.plus(parent.indent.groupIndentLen)
58-
return if (parent is SqlSubGroupBlock) {
59-
// parent.indent.groupIndentLen
60-
prevBlocksLength
61-
} else {
62-
prevBlocksLength.plus(1)
63-
}
61+
baseIndent =
62+
if (parent is SqlSubGroupBlock) {
63+
// parent.indent.groupIndentLen
64+
prevBlocksLength
65+
} else {
66+
prevBlocksLength.plus(1)
67+
}
6468
}
65-
return 0
69+
return baseIndent.plus(getNodeText().length)
6670
}
67-
68-
override fun createGroupIndentLen(): Int = indent.indentLen.plus(getNodeText().length)
6971
}

src/main/kotlin/org/domaframework/doma/intellij/formatter/handler/CommaRawClauseHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ package org.domaframework.doma.intellij.formatter.handler
1717

1818
import com.intellij.lang.ASTNode
1919
import org.domaframework.doma.intellij.formatter.block.SqlBlock
20-
import org.domaframework.doma.intellij.formatter.block.SqlCommaBlock
2120
import org.domaframework.doma.intellij.formatter.block.comma.SqlArrayCommaBlock
21+
import org.domaframework.doma.intellij.formatter.block.comma.SqlCommaBlock
2222
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
2323
import org.domaframework.doma.intellij.formatter.block.group.column.SqlColumnRawGroupBlock
2424
import org.domaframework.doma.intellij.formatter.block.group.keyword.SqlKeywordGroupBlock

src/main/kotlin/org/domaframework/doma/intellij/formatter/handler/NotQueryGroupHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ package org.domaframework.doma.intellij.formatter.handler
1717

1818
import com.intellij.lang.ASTNode
1919
import org.domaframework.doma.intellij.formatter.block.SqlBlock
20-
import org.domaframework.doma.intellij.formatter.block.SqlCommaBlock
20+
import org.domaframework.doma.intellij.formatter.block.comma.SqlCommaBlock
2121
import org.domaframework.doma.intellij.formatter.block.comment.SqlElConditionLoopCommentBlock
2222
import org.domaframework.doma.intellij.formatter.block.conflict.SqlConflictClauseBlock
2323
import org.domaframework.doma.intellij.formatter.block.conflict.SqlConflictExpressionSubGroupBlock

src/main/kotlin/org/domaframework/doma/intellij/formatter/processor/SqlFormatPreProcessor.kt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class SqlFormatPreProcessor : PreFormatProcessor {
111111
}
112112

113113
SqlTypes.LEFT_PAREN -> {
114-
newKeyword = getNewLineString(it.prevSibling, getUpperText(it))
114+
newKeyword = getNewLineLeftParenString(it.prevSibling, getUpperText(it))
115115
}
116116

117117
SqlTypes.RIGHT_PAREN -> {
@@ -233,6 +233,22 @@ class SqlFormatPreProcessor : PreFormatProcessor {
233233
}
234234
}
235235

236+
private fun getNewLineLeftParenString(
237+
prevElement: PsiElement?,
238+
text: String,
239+
): String =
240+
if (prevElement?.elementType == SqlTypes.BLOCK_COMMENT ||
241+
(
242+
prevElement?.text?.contains(LINE_SEPARATE) == false &&
243+
prevElement.prevSibling != null &&
244+
prevElement.elementType != SqlTypes.FUNCTION_NAME
245+
)
246+
) {
247+
"$LINE_SEPARATE$text"
248+
} else {
249+
text
250+
}
251+
236252
private fun getNewLineString(
237253
prevElement: PsiElement?,
238254
text: String,

src/main/kotlin/org/domaframework/doma/intellij/formatter/util/SqlBlockGenerator.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,18 @@ class SqlBlockGenerator(
220220
}
221221
}
222222
"from" -> {
223-
SqlFromGroupBlock(
224-
child,
225-
sqlBlockFormattingCtx,
226-
)
223+
if (lastGroupBlock is SqlSubGroupBlock) {
224+
SqlKeywordBlock(
225+
child,
226+
IndentType.ATTACHED,
227+
sqlBlockFormattingCtx,
228+
)
229+
} else {
230+
SqlFromGroupBlock(
231+
child,
232+
sqlBlockFormattingCtx,
233+
)
234+
}
227235
}
228236
"where" -> {
229237
SqlWhereGroupBlock(

0 commit comments

Comments
 (0)