@@ -19,13 +19,27 @@ import com.intellij.lang.injection.InjectedLanguageManager
1919import com.intellij.openapi.util.TextRange
2020import com.intellij.psi.PsiElement
2121import com.intellij.psi.PsiFile
22- import com.intellij.psi.PsiLiteralExpression
2322import com.intellij.psi.codeStyle.CodeStyleSettings
2423import org.domaframework.doma.intellij.common.dao.getDaoClass
2524import org.domaframework.doma.intellij.common.isJavaOrKotlinFileType
2625import org.domaframework.doma.intellij.common.isSupportFileType
26+ import org.domaframework.doma.intellij.common.util.InjectionSqlUtil
2727import org.domaframework.doma.intellij.formatter.visitor.DaoInjectionSqlVisitor
28+ import org.domaframework.doma.intellij.formatter.visitor.FormattingTask
2829
30+ /* *
31+ * Post-processor for SQL injection formatting.
32+ *
33+ * This processor handles SQL formatting in two contexts:
34+ * 1. **File formatting**: When formatting entire DAO files (Java/Kotlin) containing SQL annotations
35+ * 2. **Code formatting**: When formatting injected SQL fragments within string literals
36+ *
37+ * The context is determined by checking:
38+ * - If the source is an injected fragment (`InjectedLanguageManager.isInjectedFragment()` returns true),
39+ * it's being called from code formatting for a specific SQL string literal
40+ * - If the source is a regular DAO file (Java/Kotlin with @Dao annotation),
41+ * it's being called from file formatting to process all SQL strings in the file
42+ */
2943class SqlInjectionPostProcessor : SqlPostProcessor () {
3044 override fun processElement (
3145 element : PsiElement ,
@@ -37,49 +51,55 @@ class SqlInjectionPostProcessor : SqlPostProcessor() {
3751 rangeToReformat : TextRange ,
3852 settings : CodeStyleSettings ,
3953 ): TextRange {
40- if (! shouldProcessFile (source)) {
54+ if (! isProcessFile (source)) {
4155 return rangeToReformat
4256 }
4357
4458 val manager = InjectedLanguageManager .getInstance(source.project)
4559 if (manager.isInjectedFragment(source)) {
46- processInjectedFragment(source, manager )
60+ processInjectedFragment(source)
4761 } else {
4862 processRegularFile(source)
4963 }
5064
5165 return rangeToReformat
5266 }
5367
54- private fun shouldProcessFile (source : PsiFile ): Boolean {
68+ private fun isProcessFile (source : PsiFile ): Boolean {
5569 val manager = InjectedLanguageManager .getInstance(source.project)
5670 val isInjectedSql = if (isSupportFileType(source)) manager.isInjectedFragment(source) else false
5771 val isDaoFile = isJavaOrKotlinFileType(source) && getDaoClass(source) != null
5872
5973 return isInjectedSql || isDaoFile
6074 }
6175
62- private fun processInjectedFragment (
63- source : PsiFile ,
64- manager : InjectedLanguageManager ,
65- ) {
66- val host = manager.getInjectionHost (source) as ? PsiLiteralExpression ? : return
67- val hostDaoFile = host.containingFile
76+ /* *
77+ * Processes all SQL injections in a DAO file during file formatting.
78+ * This is called when formatting an entire DAO file containing SQL annotations.
79+ */
80+ private fun processInjectedFragment (source : PsiFile ) {
81+ val host = InjectionSqlUtil .getLiteralExpressionHost(source) ? : return
6882 val originalText = host.value?.toString() ? : return
6983
70- val visitor = DaoInjectionSqlVisitor (hostDaoFile, source.project)
71- val formattingTask = DaoInjectionSqlVisitor . FormattingTask (host, originalText)
84+ val visitor = DaoInjectionSqlVisitor (source.project)
85+ val formattingTask = FormattingTask (host, originalText, host.isTextBlock )
7286
73- visitor.replaceHostStringLiteral(formattingTask) { text ->
87+ visitor.convertExpressionToTextBlock(formattingTask.expression)
88+ visitor.processFormattingTask(formattingTask) { text ->
7489 processDocumentText(text)
7590 }
7691 }
7792
93+ /* *
94+ * Processes injected SQL fragments during code formatting.
95+ * This is called when formatting a specific SQL string literal within a DAO file.
96+ */
7897 private fun processRegularFile (source : PsiFile ) {
79- val visitor = DaoInjectionSqlVisitor (source, source .project)
98+ val visitor = DaoInjectionSqlVisitor (source.project)
8099 source.accept(visitor)
81-
82- visitor.processAll { text ->
100+ visitor.processAllTextBlock()
101+ source.accept(visitor)
102+ visitor.processAllReFormat { text ->
83103 processDocumentText(text)
84104 }
85105 }
0 commit comments