@@ -49,36 +49,32 @@ class DaoInjectionSqlVisitor(
4949 val injected: PsiFile ? = InjectionSqlUtil .initInjectionElement(element, project, expression)
5050 if (injected != null ) {
5151 // Format SQL and store the task
52- val formattedSql = formatInjectedSql(injected)
52+ val originalSqlText = injected.text
53+ val normalizedSql = normalizeIndentation(originalSqlText)
54+ val formattedSql = formatAsTemporarySqlFile(normalizedSql)
55+ val finalSql = reapplyOriginalIndentation(formattedSql, originalSqlText)
56+
5357 val originalText = expression.value?.toString() ? : return
54- if (formattedSql != originalText) {
55- formattingTasks.add(FormattingTask (expression, formattedSql ))
58+ if (finalSql != originalText) {
59+ formattingTasks.add(FormattingTask (expression, finalSql ))
5660 }
5761 }
5862 }
5963
60- fun processAll () {
64+ fun processAll (removeSpace : ( String , Boolean ) -> String ) {
6165 if (formattingTasks.isEmpty()) return
6266
6367 // Apply all formatting tasks in a single write action
6468 WriteCommandAction .runWriteCommandAction(project, " Format Injected SQL" , null , {
6569 // Sort by text range in descending order to maintain offsets
6670 formattingTasks.sortedByDescending { it.expression.textRange.startOffset }.forEach { task ->
6771 if (task.expression.isValid) {
68- replaceHostStringLiteral(task.expression, task.formattedText)
72+ replaceHostStringLiteral(task.expression, task.formattedText, removeSpace )
6973 }
7074 }
7175 })
7276 }
7377
74- private fun formatInjectedSql (injectedFile : PsiFile ): String =
75- try {
76- val originalSqlText = injectedFile.text
77- formatAsTemporarySqlFile(originalSqlText)
78- } catch (_: Exception ) {
79- injectedFile.text
80- }
81-
8278 /* *
8379 * Execute formatting as a temporary SQL file
8480 */
@@ -107,16 +103,18 @@ class DaoInjectionSqlVisitor(
107103 private fun replaceHostStringLiteral (
108104 literalExpression : PsiLiteralExpression ,
109105 formattedSqlText : String ,
106+ removeSpace : (String , Boolean ) -> String ,
110107 ) {
111108 try {
112- // Create new string literal
113- val newLiteralText = createFormattedLiteralText(formattedSqlText)
109+ val normalizedSql = normalizeIndentation(formattedSqlText)
110+ val newLiteralText = createFormattedLiteralText(normalizedSql)
111+ val removeSpaceText = removeSpace(newLiteralText, false )
114112
115113 // Replace PSI element
116114 val elementFactory =
117115 com.intellij.psi.JavaPsiFacade
118116 .getElementFactory(project)
119- val newLiteral = elementFactory.createExpressionFromText(newLiteralText , literalExpression)
117+ val newLiteral = elementFactory.createExpressionFromText(removeSpaceText , literalExpression)
120118 val manager = PsiDocumentManager .getInstance(literalExpression.project)
121119 val document = manager.getDocument(literalExpression.containingFile) ? : return
122120 document.replaceString(literalExpression.textRange.startOffset, literalExpression.textRange.endOffset, newLiteral.text)
@@ -125,11 +123,40 @@ class DaoInjectionSqlVisitor(
125123 }
126124 }
127125
126+ private fun normalizeIndentation (sqlText : String ): String {
127+ val lines = sqlText.lines()
128+ val minIndent =
129+ lines
130+ .filter { it.isNotBlank() }
131+ .minOfOrNull { it.indexOfFirst { char -> ! char.isWhitespace() } } ? : 0
132+
133+ return lines.joinToString(StringUtil .LINE_SEPARATE ) { line ->
134+ if (line.isBlank()) line else line.drop(minIndent)
135+ }
136+ }
137+
128138 /* *
129139 * Create appropriate Java string literal from formatted SQL
130140 */
131141 private fun createFormattedLiteralText (formattedSqlText : String ): String {
132142 val lines = formattedSqlText.split(StringUtil .LINE_SEPARATE )
133143 return " \"\"\" ${StringUtil .LINE_SEPARATE }${lines.joinToString(StringUtil .LINE_SEPARATE )} \"\"\" "
134144 }
145+
146+ private fun reapplyOriginalIndentation (
147+ formattedSql : String ,
148+ originalSql : String ,
149+ ): String {
150+ val originalLines = originalSql.lines()
151+ val formattedLines = formattedSql.lines()
152+
153+ val originalIndent =
154+ originalLines
155+ .firstOrNull { it.isNotBlank() }
156+ ?.takeWhile { it.isWhitespace() } ? : " "
157+
158+ return formattedLines.joinToString(StringUtil .LINE_SEPARATE ) { line ->
159+ if (line.isBlank()) line else originalIndent + line
160+ }
161+ }
135162}
0 commit comments