Skip to content

Commit e2405b1

Browse files
authored
Merge pull request #344 from domaframework/feature/sql-format-support-injection-sql
Injected SQL Formatting Enhancement
2 parents 691ab91 + f6604a5 commit e2405b1

21 files changed

+274
-96
lines changed

src/main/kotlin/org/domaframework/doma/intellij/common/psi/PsiPatternUtil.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import com.intellij.psi.util.elementType
2727
import com.intellij.psi.util.prevLeafs
2828
import com.intellij.util.ProcessingContext
2929
import org.domaframework.doma.intellij.common.sql.directive.DirectiveCompletion
30+
import org.domaframework.doma.intellij.common.util.StringUtil.SINGLE_SPACE
3031
import org.domaframework.doma.intellij.psi.SqlCustomElCommentExpr
3132
import org.domaframework.doma.intellij.psi.SqlElClass
3233
import org.domaframework.doma.intellij.psi.SqlElIdExpr
@@ -135,7 +136,7 @@ object PsiPatternUtil {
135136
element: PsiElement,
136137
symbol: String,
137138
): String {
138-
val text = originalFile.containingFile?.text ?: " "
139+
val text = originalFile.containingFile?.text ?: SINGLE_SPACE
139140
val offset = element.textOffset
140141
val builder = StringBuilder()
141142
for (i in offset - 1 downTo 0) {

src/main/kotlin/org/domaframework/doma/intellij/common/sql/CleanElementText.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.domaframework.doma.intellij.common.sql
1717

1818
import org.domaframework.doma.intellij.common.util.StringUtil
19+
import org.domaframework.doma.intellij.common.util.StringUtil.SINGLE_SPACE
1920

2021
/**
2122
* Exclude extra strings and block symbols added by IntelliJ operations a
@@ -29,5 +30,5 @@ fun cleanString(str: String): String {
2930
// TODO: Temporary support when using operators.
3031
// Remove the "== a" element because it is attached to the end.
3132
// Make it possible to obtain the equilateral elements of the left side individually.
32-
.substringBefore(" ")
33+
.substringBefore(SINGLE_SPACE)
3334
}

src/main/kotlin/org/domaframework/doma/intellij/common/sql/directive/StaticDirectiveHandler.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import org.domaframework.doma.intellij.common.psi.PsiPatternUtil
2525
import org.domaframework.doma.intellij.common.sql.directive.collector.FunctionCallCollector
2626
import org.domaframework.doma.intellij.common.sql.directive.collector.StaticClassPackageCollector
2727
import org.domaframework.doma.intellij.common.sql.directive.collector.StaticPropertyCollector
28+
import org.domaframework.doma.intellij.common.util.StringUtil.SINGLE_SPACE
2829
import org.domaframework.doma.intellij.psi.SqlElClass
2930
import org.domaframework.doma.intellij.psi.SqlElStaticFieldAccessExpr
3031
import org.domaframework.doma.intellij.psi.SqlTypes
@@ -117,7 +118,7 @@ class StaticDirectiveHandler(
117118
val prev = PsiTreeUtil.prevLeaf(element, true)
118119
val staticFieldAccess =
119120
PsiTreeUtil.getParentOfType(prev, SqlElStaticFieldAccessExpr::class.java)
120-
val sqlElClassWords = PsiPatternUtil.getBindSearchWord(element.containingFile, element, " ")
121+
val sqlElClassWords = PsiPatternUtil.getBindSearchWord(element.containingFile, element, SINGLE_SPACE)
121122
return (
122123
staticFieldAccess != null && staticFieldAccess.elIdExprList.isEmpty()
123124
) ||
@@ -141,7 +142,7 @@ class StaticDirectiveHandler(
141142
.getChildOfType(prev, SqlElClass::class.java)
142143
?: PsiTreeUtil.getChildOfType(PsiTreeUtil.prevLeaf(element)?.parent, SqlElClass::class.java)
143144

144-
val sqlElClassWords = PsiPatternUtil.getBindSearchWord(element.containingFile, element, " ")
145+
val sqlElClassWords = PsiPatternUtil.getBindSearchWord(element.containingFile, element, SINGLE_SPACE)
145146
val sqlElClassName = PsiTreeUtil.getChildrenOfTypeAsList(clazzRef, PsiElement::class.java).joinToString("") { it.text }
146147
val fqdn = if (sqlElClassName.isNotEmpty()) sqlElClassName else sqlElClassWords.replace("@", "")
147148

src/main/kotlin/org/domaframework/doma/intellij/common/util/StringUtil.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package org.domaframework.doma.intellij.common.util
1717

1818
object StringUtil {
1919
const val LINE_SEPARATE: String = "\n"
20+
const val SINGLE_SPACE: String = " "
2021

2122
fun getSqlElClassText(text: String): String =
2223
text

src/main/kotlin/org/domaframework/doma/intellij/common/util/TypeUtil.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project
2020
import com.intellij.psi.PsiClassType
2121
import com.intellij.psi.PsiType
2222
import org.domaframework.doma.intellij.common.psi.PsiTypeChecker
23+
import org.domaframework.doma.intellij.common.util.StringUtil.SINGLE_SPACE
2324
import org.domaframework.doma.intellij.extension.getJavaClazz
2425
import org.domaframework.doma.intellij.extension.psi.getClassAnnotation
2526
import org.domaframework.doma.intellij.extension.psi.isDomain
@@ -79,13 +80,13 @@ object TypeUtil {
7980
* Checks if the given type is a valid Map<String, Object>.
8081
*/
8182
fun isValidMapType(type: PsiType?): Boolean {
82-
val canonical = type?.canonicalText?.replace(" ", "") ?: return false
83+
val canonical = type?.canonicalText?.replace(SINGLE_SPACE, "") ?: return false
8384
val expected =
8485
DomaClassName.MAP
8586
.getGenericParamCanonicalText(
8687
DomaClassName.STRING.className,
8788
DomaClassName.OBJECT.className,
88-
).replace(" ", "")
89+
).replace(SINGLE_SPACE, "")
8990
return canonical == expected
9091
}
9192

src/main/kotlin/org/domaframework/doma/intellij/contributor/sql/provider/SqlParameterCompletionProvider.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import org.domaframework.doma.intellij.common.util.ForDirectiveUtil
4343
import org.domaframework.doma.intellij.common.util.PluginLoggerUtil
4444
import org.domaframework.doma.intellij.common.util.SqlCompletionUtil.createMethodLookupElement
4545
import org.domaframework.doma.intellij.common.util.StringUtil
46+
import org.domaframework.doma.intellij.common.util.StringUtil.SINGLE_SPACE
4647
import org.domaframework.doma.intellij.common.validation.result.ValidationCompleteResult
4748
import org.domaframework.doma.intellij.contributor.sql.processor.SqlCompletionDirectiveBlockProcessor
4849
import org.domaframework.doma.intellij.contributor.sql.processor.SqlCompletionOtherBlockProcessor
@@ -207,7 +208,7 @@ class SqlParameterCompletionProvider : CompletionProvider<CompletionParameters>(
207208
val fqdn =
208209
StringUtil.getSqlElClassText(
209210
PsiPatternUtil
210-
.getBindSearchWord(originalFile, top, " "),
211+
.getBindSearchWord(originalFile, top, SINGLE_SPACE),
211212
)
212213
topElementType = getElementTypeByPrevSqlElClassWords(project, fqdn, topText)
213214
}

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

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
6666
import org.domaframework.doma.intellij.formatter.util.SqlBlockGenerator
6767
import org.domaframework.doma.intellij.psi.SqlTypes
6868

69-
class SqlFileBlock(
69+
open class SqlFileBlock(
7070
node: ASTNode,
7171
wrap: Wrap?,
7272
alignment: Alignment?,
@@ -221,7 +221,7 @@ class SqlFileBlock(
221221
return if (lastGroup is SqlWithCommonTableGroupBlock) {
222222
SqlWithCommonTableGroupBlock(child, defaultFormatCtx)
223223
} else {
224-
blockUtil.getBlockCommentBlock(child, createBlockCommentSpacingBuilder())
224+
blockUtil.getBlockCommentBlock(child, createBlockDirectiveCommentSpacingBuilder())
225225
}
226226
}
227227

@@ -416,15 +416,11 @@ class SqlFileBlock(
416416
}
417417

418418
/**
419-
* Creates a spacing builder specifically for block comments.
419+
* Creates a spacing builder specifically for directive block comments.
420420
*/
421-
private fun createBlockCommentSpacingBuilder(): SqlCustomSpacingBuilder =
421+
protected fun createBlockDirectiveCommentSpacingBuilder(): SqlCustomSpacingBuilder =
422422
SqlCustomSpacingBuilder()
423423
.withSpacing(
424-
SqlTypes.BLOCK_COMMENT_START,
425-
SqlTypes.BLOCK_COMMENT_CONTENT,
426-
Spacing.createSpacing(0, 0, 0, true, 0),
427-
).withSpacing(
428424
SqlTypes.BLOCK_COMMENT_START,
429425
SqlTypes.EL_ID_EXPR,
430426
Spacing.createSpacing(1, 1, 0, true, 0),
@@ -572,10 +568,6 @@ class SqlFileBlock(
572568
SqlTypes.EL_STATIC_FIELD_ACCESS_EXPR,
573569
SqlTypes.BLOCK_COMMENT_END,
574570
Spacing.createSpacing(1, 1, 0, true, 0),
575-
).withSpacing(
576-
SqlTypes.BLOCK_COMMENT_CONTENT,
577-
SqlTypes.BLOCK_COMMENT_END,
578-
Spacing.createSpacing(0, 0, 0, true, 0),
579571
)
580572

581573
/**

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

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,57 @@
1515
*/
1616
package org.domaframework.doma.intellij.formatter.block.comment
1717

18+
import com.intellij.formatting.Block
19+
import com.intellij.formatting.Spacing
1820
import com.intellij.lang.ASTNode
21+
import com.intellij.psi.PsiWhiteSpace
22+
import com.intellij.psi.formatter.common.AbstractBlock
1923
import com.intellij.psi.util.PsiTreeUtil
2024
import org.domaframework.doma.intellij.common.util.StringUtil
2125
import org.domaframework.doma.intellij.formatter.block.SqlBlock
26+
import org.domaframework.doma.intellij.formatter.block.SqlUnknownBlock
27+
import org.domaframework.doma.intellij.formatter.builder.SqlCustomSpacingBuilder
2228
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
29+
import org.domaframework.doma.intellij.psi.SqlTypes
2330

2431
open class SqlBlockCommentBlock(
2532
node: ASTNode,
26-
context: SqlBlockFormattingContext,
33+
private val customSpacingBuilder: SqlCustomSpacingBuilder,
34+
private val context: SqlBlockFormattingContext,
2735
) : SqlDefaultCommentBlock(
2836
node,
2937
context,
3038
) {
39+
override fun buildChildren(): MutableList<AbstractBlock> {
40+
val blocks = mutableListOf<AbstractBlock>()
41+
var child = node.firstChildNode
42+
while (child != null) {
43+
if (child !is PsiWhiteSpace) {
44+
val block = getBlock(child)
45+
blocks.add(block)
46+
}
47+
child = child.treeNext
48+
}
49+
return blocks
50+
}
51+
52+
override fun getBlock(child: ASTNode): SqlBlock {
53+
val elementType = child.elementType
54+
return when (elementType) {
55+
SqlTypes.BLOCK_COMMENT_START -> SqlCommentStartBlock(child, context)
56+
SqlTypes.BLOCK_COMMENT_END -> SqlCommentEndBlock(child, context)
57+
SqlTypes.BLOCK_COMMENT_CONTENT -> SqlCommentContentBlock(child, context)
58+
else -> SqlUnknownBlock(child, context)
59+
}
60+
}
61+
3162
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean =
3263
PsiTreeUtil.prevLeaf(node.psi)?.text?.contains(StringUtil.LINE_SEPARATE) == true
64+
65+
override fun getSpacing(
66+
child1: Block?,
67+
child2: Block,
68+
): Spacing? =
69+
customSpacingBuilder.getCustomSpacing(child1, child2)
70+
?: SqlCustomSpacingBuilder.normalSpacing
3371
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright Doma Tools Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.domaframework.doma.intellij.formatter.block.comment
17+
18+
import com.intellij.lang.ASTNode
19+
import org.domaframework.doma.intellij.formatter.block.SqlBlock
20+
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
21+
22+
class SqlCommentContentBlock(
23+
node: ASTNode,
24+
context: SqlBlockFormattingContext,
25+
) : SqlCommentBlock(node, context) {
26+
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean = false
27+
28+
override fun createBlockIndentLen(): Int = parentBlock?.indent?.indentLen ?: 1
29+
30+
override fun createGroupIndentLen(): Int = indent.indentLen
31+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright Doma Tools Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.domaframework.doma.intellij.formatter.block.comment
17+
18+
import com.intellij.lang.ASTNode
19+
import com.intellij.psi.PsiComment
20+
import com.intellij.psi.util.PsiTreeUtil
21+
import org.domaframework.doma.intellij.formatter.block.SqlBlock
22+
import org.domaframework.doma.intellij.formatter.util.SqlBlockFormattingContext
23+
24+
class SqlCommentEndBlock(
25+
node: ASTNode,
26+
context: SqlBlockFormattingContext,
27+
) : SqlCommentSeparateBlock(node, context) {
28+
override fun isSaveSpace(lastGroup: SqlBlock?): Boolean {
29+
parentBlock?.let { parent ->
30+
val contents =
31+
PsiTreeUtil.getChildOfType<PsiComment>(parent.node.psi, PsiComment::class.java)
32+
return contents != null
33+
}
34+
return false
35+
}
36+
}

0 commit comments

Comments
 (0)