Skip to content

Commit a461bcf

Browse files
committed
Move the logic for retrieving injected files to a utility class.
1 parent d81b9f5 commit a461bcf

File tree

5 files changed

+99
-44
lines changed

5 files changed

+99
-44
lines changed

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

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

1818
import com.intellij.lang.Language
19-
import com.intellij.lang.injection.InjectedLanguageManager
2019
import com.intellij.openapi.application.ApplicationManager
2120
import com.intellij.openapi.command.WriteCommandAction
2221
import com.intellij.openapi.fileEditor.FileEditorManager
@@ -150,7 +149,6 @@ class PsiDaoMethod(
150149
}
151150
// the injection part as a custom language file
152151
getSqlAnnotation()?.let { annotation ->
153-
InjectedLanguageManager.getInstance(psiProject)
154152
annotation.parameterList.children
155153
.firstOrNull { it is PsiNameValuePair }
156154
?.let { sql ->
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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.common.util
17+
18+
import com.intellij.lang.injection.InjectedLanguageManager
19+
import com.intellij.openapi.project.Project
20+
import com.intellij.psi.PsiFile
21+
import com.intellij.psi.PsiLiteralExpression
22+
import org.domaframework.doma.intellij.common.isJavaOrKotlinFileType
23+
24+
object InjectionSqlUtil {
25+
fun initInjectionElement(
26+
basePsiFile: PsiFile,
27+
project: Project,
28+
literal: PsiLiteralExpression,
29+
): PsiFile? =
30+
if (isJavaOrKotlinFileType(basePsiFile)) {
31+
val injectedLanguageManager = InjectedLanguageManager.getInstance(project)
32+
injectedLanguageManager
33+
.getInjectedPsiFiles(literal)
34+
?.firstOrNull()
35+
?.first as? PsiFile
36+
} else {
37+
null
38+
}
39+
40+
fun isInjectedSqlFile(source: PsiFile): Boolean {
41+
val injectedLanguageManager = InjectedLanguageManager.getInstance(source.project)
42+
return injectedLanguageManager.isInjectedFragment(source)
43+
}
44+
}

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

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ import com.intellij.psi.TokenType
2626
import com.intellij.psi.impl.source.codeStyle.PreFormatProcessor
2727
import com.intellij.psi.util.PsiTreeUtil
2828
import com.intellij.psi.util.elementType
29+
import org.domaframework.doma.intellij.common.util.InjectionSqlUtil.isInjectedSqlFile
2930
import org.domaframework.doma.intellij.common.util.PluginLoggerUtil
31+
import org.domaframework.doma.intellij.common.util.StringUtil
3032
import org.domaframework.doma.intellij.formatter.util.CreateQueryType
3133
import org.domaframework.doma.intellij.formatter.util.SqlKeywordUtil
3234
import org.domaframework.doma.intellij.formatter.visitor.SqlFormatVisitor
@@ -58,7 +60,10 @@ class SqlFormatPreProcessor : PreFormatProcessor {
5860
rangeToReformat: TextRange,
5961
): TextRange {
6062
// Turn on by default the code formatter that only runs when explicitly invoked by the user.
61-
if (source.language != SqlLanguage.INSTANCE) return rangeToReformat
63+
// Handle both direct SQL files and injected SQL in Java files
64+
if (source.language != SqlLanguage.INSTANCE && !isInjectedSqlFile(source)) {
65+
return rangeToReformat
66+
}
6267

6368
logging()
6469

@@ -151,7 +156,6 @@ class SqlFormatPreProcessor : PreFormatProcessor {
151156
element: PsiWhiteSpace,
152157
) {
153158
val singleSpace = " "
154-
val newLine = "\n"
155159
val range = element.textRange
156160
val originalText = document.getText(range)
157161
val nextElement = element.nextSibling
@@ -162,24 +166,28 @@ class SqlFormatPreProcessor : PreFormatProcessor {
162166
newText = originalText.replace(originalText, singleSpace)
163167
} else {
164168
newText =
165-
when (nextElement.elementType) {
166-
SqlTypes.LINE_COMMENT -> {
167-
if (nextElementText.startsWith(newLine)) {
168-
originalText.replace(originalText, singleSpace)
169-
} else if (originalText.contains(newLine)) {
170-
originalText.replace(Regex("\\s*\\n\\s*"), newLine)
171-
} else {
172-
originalText.replace(originalText, singleSpace)
169+
if (element.prevSibling == null) {
170+
""
171+
} else {
172+
when (nextElement.elementType) {
173+
SqlTypes.LINE_COMMENT -> {
174+
if (nextElementText.startsWith(StringUtil.LINE_SEPARATE)) {
175+
originalText.replace(originalText, singleSpace)
176+
} else if (originalText.contains(StringUtil.LINE_SEPARATE)) {
177+
originalText.replace(Regex("\\s*\\n\\s*"), StringUtil.LINE_SEPARATE)
178+
} else {
179+
originalText.replace(originalText, singleSpace)
180+
}
173181
}
174-
}
175182

176-
else -> {
177-
if (nextElementText.contains(newLine) == true) {
178-
originalText.replace(originalText, singleSpace)
179-
} else if (originalText.contains(newLine)) {
180-
originalText.replace(Regex("\\s*\\n\\s*"), newLine)
181-
} else {
182-
originalText.replace(originalText, newLine)
183+
else -> {
184+
if (nextElementText.contains(StringUtil.LINE_SEPARATE) == true) {
185+
originalText.replace(originalText, singleSpace)
186+
} else if (originalText.contains(StringUtil.LINE_SEPARATE)) {
187+
originalText.replace(Regex("\\s*\\n\\s*"), StringUtil.LINE_SEPARATE)
188+
} else {
189+
originalText.replace(originalText, StringUtil.LINE_SEPARATE)
190+
}
183191
}
184192
}
185193
}
@@ -264,8 +272,8 @@ class SqlFormatPreProcessor : PreFormatProcessor {
264272
prevElement: PsiElement?,
265273
text: String,
266274
): String =
267-
if (prevElement?.text?.contains("\n") == false) {
268-
"\n$text"
275+
if (prevElement?.text?.contains(StringUtil.LINE_SEPARATE) == false) {
276+
"${StringUtil.LINE_SEPARATE}$text"
269277
} else {
270278
text
271279
}

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

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,24 @@
1515
*/
1616
package org.domaframework.doma.intellij.formatter.processor
1717

18+
import com.intellij.lang.injection.InjectedLanguageManager
1819
import com.intellij.openapi.application.ApplicationManager
1920
import com.intellij.openapi.command.WriteCommandAction
21+
import com.intellij.openapi.editor.Document
2022
import com.intellij.openapi.project.Project
2123
import com.intellij.openapi.util.TextRange
2224
import com.intellij.psi.PsiDocumentManager
2325
import com.intellij.psi.PsiElement
2426
import com.intellij.psi.PsiFile
2527
import com.intellij.psi.codeStyle.CodeStyleSettings
2628
import com.intellij.psi.impl.source.codeStyle.PostFormatProcessor
29+
import org.domaframework.doma.intellij.common.util.InjectionSqlUtil.isInjectedSqlFile
30+
import org.domaframework.doma.intellij.common.util.StringUtil
2731
import org.domaframework.doma.intellij.setting.SqlLanguage
2832

2933
class SqlPostProcessor : PostFormatProcessor {
3034
companion object {
31-
private const val FILE_END_PADDING = " \n"
35+
private const val FILE_END_PADDING = " ${StringUtil.LINE_SEPARATE}"
3236
}
3337

3438
private val trailingSpacesRegex = Regex(" +(\r?\n)")
@@ -43,12 +47,13 @@ class SqlPostProcessor : PostFormatProcessor {
4347
rangeToReformat: TextRange,
4448
settings: CodeStyleSettings,
4549
): TextRange {
46-
if (!isSqlFile(source)) {
50+
if (!isSqlFile(source) || isInjectedSqlFile(source)) {
4751
return rangeToReformat
4852
}
4953

50-
val document = getDocument(source) ?: return rangeToReformat
51-
val processedText = processDocumentText(document.text)
54+
val originalDocument = getDocument(source)
55+
val document = originalDocument ?: source.fileDocument
56+
val processedText = processDocumentText(document.text, originalDocument != null)
5257

5358
if (document.text == processedText) {
5459
return rangeToReformat
@@ -62,18 +67,26 @@ class SqlPostProcessor : PostFormatProcessor {
6267

6368
private fun getDocument(source: PsiFile) = PsiDocumentManager.getInstance(source.project).getDocument(source)
6469

65-
private fun processDocumentText(originalText: String): String {
70+
private fun processDocumentText(
71+
originalText: String,
72+
existsOriginalDocument: Boolean,
73+
): String {
6674
val withoutTrailingSpaces = removeTrailingSpaces(originalText)
67-
return ensureProperFileEnding(withoutTrailingSpaces)
75+
return ensureProperFileEnding(withoutTrailingSpaces, existsOriginalDocument)
6876
}
6977

7078
private fun removeTrailingSpaces(text: String): String = text.replace(trailingSpacesRegex, "$1")
7179

72-
private fun ensureProperFileEnding(text: String): String = text.trimEnd() + FILE_END_PADDING
80+
private fun ensureProperFileEnding(
81+
text: String,
82+
isEndSpace: Boolean,
83+
): String =
84+
text.trimEnd() +
85+
if (isEndSpace) FILE_END_PADDING else ""
7386

7487
private fun updateDocument(
7588
project: Project,
76-
document: com.intellij.openapi.editor.Document,
89+
document: Document,
7790
newText: String,
7891
) {
7992
ApplicationManager.getApplication().invokeAndWait {

src/main/kotlin/org/domaframework/doma/intellij/inspection/sql/visitor/SqlVisitorBase.kt

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@
1515
*/
1616
package org.domaframework.doma.intellij.inspection.sql.visitor
1717

18-
import com.intellij.lang.injection.InjectedLanguageManager
1918
import com.intellij.openapi.project.Project
2019
import com.intellij.psi.PsiFile
2120
import com.intellij.psi.PsiLiteralExpression
22-
import org.domaframework.doma.intellij.common.isJavaOrKotlinFileType
21+
import org.domaframework.doma.intellij.common.util.InjectionSqlUtil
2322
import org.domaframework.doma.intellij.psi.SqlVisitor
2423

2524
open class SqlVisitorBase : SqlVisitor() {
@@ -31,16 +30,9 @@ open class SqlVisitorBase : SqlVisitor() {
3130
project: Project,
3231
literal: PsiLiteralExpression,
3332
): PsiFile? =
34-
when (isJavaOrKotlinFileType(basePsiFile)) {
35-
true -> {
36-
val injectedLanguageManager =
37-
InjectedLanguageManager.getInstance(project)
38-
injectedLanguageManager
39-
.getInjectedPsiFiles(literal)
40-
?.firstOrNull()
41-
?.first as? PsiFile
42-
}
43-
44-
false -> null
45-
}
33+
InjectionSqlUtil.initInjectionElement(
34+
basePsiFile,
35+
project,
36+
literal,
37+
)
4638
}

0 commit comments

Comments
 (0)