@@ -24,8 +24,8 @@ import com.intellij.psi.PsiFile
2424import com.intellij.psi.PsiWhiteSpace
2525import com.intellij.psi.TokenType
2626import com.intellij.psi.impl.source.codeStyle.PreFormatProcessor
27+ import com.intellij.psi.util.PsiTreeUtil
2728import com.intellij.psi.util.elementType
28- import com.intellij.psi.util.prevLeafs
2929import org.domaframework.doma.intellij.common.util.PluginLoggerUtil
3030import org.domaframework.doma.intellij.formatter.util.CreateQueryType
3131import org.domaframework.doma.intellij.formatter.util.SqlKeywordUtil
@@ -35,6 +35,19 @@ import org.domaframework.doma.intellij.setting.SqlLanguage
3535import org.jetbrains.kotlin.psi.psiUtil.startOffset
3636
3737class SqlFormatPreProcessor : PreFormatProcessor {
38+ private val targetElementTypes =
39+ listOf (
40+ SqlTypes .KEYWORD ,
41+ SqlTypes .LEFT_PAREN ,
42+ SqlTypes .RIGHT_PAREN ,
43+ SqlTypes .BLOCK_COMMENT ,
44+ SqlTypes .LINE_COMMENT ,
45+ SqlTypes .WORD ,
46+ SqlTypes .COMMA ,
47+ SqlTypes .BLOCK_COMMENT ,
48+ SqlTypes .OTHER ,
49+ )
50+
3851 override fun process (
3952 node : ASTNode ,
4053 rangeToReformat : TextRange ,
@@ -71,17 +84,15 @@ class SqlFormatPreProcessor : PreFormatProcessor {
7184 when (it.elementType) {
7285 SqlTypes .KEYWORD -> {
7386 keywordIndex--
74- newKeyword = getKeywordNewText(index, it, createQueryType, keywordList )
87+ newKeyword = getKeywordNewText(it )
7588 }
7689
7790 SqlTypes .LEFT_PAREN -> {
7891 newKeyword =
7992 if (createQueryType == CreateQueryType .TABLE ) {
8093 getNewLineString(it.prevSibling, getUpperText(it))
8194 } else if (keywordIndex > 0 ) {
82- if (replaceKeywordList[keywordIndex - 1 ].text.lowercase() == " insert" ||
83- replaceKeywordList[keywordIndex - 1 ].text.lowercase() == " into"
84- ) {
95+ if (listOf (" insert" , " into" , " all" ).contains(replaceKeywordList[keywordIndex - 1 ].text.lowercase())) {
8596 getNewLineString(it.prevSibling, getUpperText(it))
8697 } else {
8798 getUpperText(it)
@@ -93,12 +104,7 @@ class SqlFormatPreProcessor : PreFormatProcessor {
93104
94105 SqlTypes .RIGHT_PAREN -> {
95106 newKeyword =
96- getRightPatternNewText(
97- it,
98- newKeyword,
99- replaceKeywordList[keywordIndex - 1 ],
100- createQueryType,
101- )
107+ getRightPatternNewText(it)
102108 }
103109
104110 SqlTypes .WORD -> {
@@ -112,40 +118,7 @@ class SqlFormatPreProcessor : PreFormatProcessor {
112118 document.deleteString(textRangeStart, textRangeEnd)
113119 document.insertString(textRangeStart, newKeyword)
114120 } else {
115- // Remove spaces after newlines to reset indentation
116- val nextSibling = it.nextSibling
117- if (nextSibling.elementType == SqlTypes .BLOCK_COMMENT ) {
118- removeSpacesAroundNewline(document, it.textRange)
119- } else if (keywordIndex < replaceKeywordList.size) {
120- val nextElement = replaceKeywordList[keywordIndex]
121- if (isNewLineOnlyCreateTable(nextSibling) && createQueryType == CreateQueryType .TABLE ) {
122- removeSpacesAroundNewline(document, it.textRange)
123- } else if (isSubGroupFirstElement(nextElement)) {
124- document.deleteString(textRangeStart, textRangeEnd)
125- } else if (isCreateViewAs(replaceKeywordList[keywordIndex], createQueryType)) {
126- removeSpacesAroundNewline(document, it.textRange)
127- } else {
128- val isNewLineGroup =
129- SqlKeywordUtil .Companion .getIndentType(nextElement.text ? : " " ).isNewLineGroup()
130- val isSetLineKeyword =
131- if (keywordIndex > 0 ) {
132- SqlKeywordUtil .Companion .isSetLineKeyword(
133- nextElement.text,
134- replaceKeywordList[keywordIndex - 1 ].text,
135- )
136- } else {
137- false
138- }
139-
140- if (isNewLineGroup && ! isSetLineKeyword || keywordList[index].elementType == SqlTypes .COMMA ) {
141- removeSpacesAroundNewline(document, it.textRange)
142- } else {
143- document.replaceString(textRangeStart, textRangeEnd, " " )
144- }
145- }
146- } else {
147- removeSpacesAroundNewline(document, it.textRange)
148- }
121+ removeSpacesAroundNewline(document, it as PsiWhiteSpace )
149122 }
150123 }
151124
@@ -156,68 +129,62 @@ class SqlFormatPreProcessor : PreFormatProcessor {
156129
157130 private fun removeSpacesAroundNewline (
158131 document : Document ,
159- range : TextRange ,
132+ element : PsiWhiteSpace ,
160133 ) {
134+ val singleSpace = " "
135+ val newLine = " \n "
136+ val range = element.textRange
161137 val originalText = document.getText(range)
162- val newText = originalText.replace(Regex (" \\ s*\\ n\\ s*" ), " \n " )
138+ val nextElement = element.nextSibling
139+ val nextElementText = nextElement?.let { document.getText(it.textRange) } ? : " "
140+
141+ var newText = " "
142+ if (! targetElementTypes.contains(nextElement?.elementType)) {
143+ newText = originalText.replace(originalText, singleSpace)
144+ } else {
145+ newText =
146+ when (nextElement.elementType) {
147+ SqlTypes .LINE_COMMENT -> {
148+ if (nextElementText.startsWith(newLine)) {
149+ originalText.replace(originalText, singleSpace)
150+ } else if (originalText.contains(newLine)) {
151+ originalText.replace(Regex (" \\ s*\\ n\\ s*" ), newLine)
152+ } else {
153+ originalText.replace(originalText, singleSpace)
154+ }
155+ }
156+
157+ else -> {
158+ if (nextElementText.contains(newLine) == true ) {
159+ originalText.replace(originalText, singleSpace)
160+ } else if (originalText.contains(newLine)) {
161+ originalText.replace(Regex (" \\ s*\\ n\\ s*" ), newLine)
162+ } else {
163+ originalText.replace(originalText, newLine)
164+ }
165+ }
166+ }
167+ }
163168 document.replaceString(range.startOffset, range.endOffset, newText)
164169 }
165170
166171 /* *
167172 * Checks for special case keyword elements and specific combinations of keywords with line breaks and capitalization only
168173 */
169- private fun getKeywordNewText (
170- index : Int ,
171- element : PsiElement ,
172- createQueryType : CreateQueryType ,
173- keywordList : List <PsiElement >,
174- ): String =
175- if (element.text.lowercase() == " end" ) {
176- getNewLineString(element.prevSibling, getUpperText(element))
177- } else if (isCreateViewAs(element, createQueryType)) {
178- getNewLineString(element.prevSibling, getUpperText(element))
179- } else if (isSubGroupFirstElement(element)) {
180- getUpperText(element)
181- } else if (SqlKeywordUtil .Companion .getIndentType(element.text).isNewLineGroup()) {
182- if (index > 0 &&
183- SqlKeywordUtil .Companion .isSetLineKeyword(
184- element.text,
185- keywordList[index - 1 ].text,
186- )
187- ) {
188- getUpperText(element)
189- } else {
190- getNewLineString(element.prevSibling, getUpperText(element))
191- }
174+ private fun getKeywordNewText (element : PsiElement ): String {
175+ val keywordText = element.text.lowercase()
176+ val upperText = getUpperText(element)
177+ return if (SqlKeywordUtil .getIndentType(keywordText).isNewLineGroup()) {
178+ val prevElement = PsiTreeUtil .prevLeaf(element)
179+ getNewLineString(prevElement, upperText)
192180 } else {
193- getUpperText(element)
181+ upperText
194182 }
183+ }
195184
196- private fun getRightPatternNewText (
197- element : PsiElement ,
198- keyword : String ,
199- nextKeyword : PsiElement ,
200- createQueryType : CreateQueryType ,
201- ): String {
202- var newKeyword = keyword
185+ private fun getRightPatternNewText (element : PsiElement ): String {
203186 val elementText = element.text
204- if (createQueryType == CreateQueryType .TABLE ) {
205- val prefixElements =
206- getElementsBeforeKeyword(element.prevLeafs.toList()) { it.elementType == SqlTypes .LEFT_PAREN }
207- val containsColumnRaw =
208- prefixElements.findLast { isColumnDefinedRawElementType(it) } != null
209- newKeyword =
210- if (containsColumnRaw) {
211- getNewLineString(element.prevSibling, elementText)
212- } else {
213- elementText
214- }
215- } else if (nextKeyword.text.lowercase() == " set" ) {
216- newKeyword = getNewLineString(element.prevSibling, elementText)
217- } else {
218- newKeyword = elementText
219- }
220- return newKeyword
187+ return getNewLineString(element.prevSibling, elementText)
221188 }
222189
223190 private fun getWordNewText (
@@ -248,18 +215,6 @@ class SqlFormatPreProcessor : PreFormatProcessor {
248215 }
249216 }
250217
251- private fun isCreateViewAs (
252- element : PsiElement ,
253- createQueryType : CreateQueryType ,
254- ): Boolean =
255- element.text.lowercase() == " as" &&
256- createQueryType == CreateQueryType .VIEW
257-
258- private fun isColumnDefinedRawElementType (element : PsiElement ): Boolean =
259- element.elementType == SqlTypes .WORD ||
260- element.elementType == SqlTypes .KEYWORD ||
261- element.elementType == SqlTypes .COMMA
262-
263218 private fun getCreateQueryGroup (
264219 keywordList : List <PsiElement >,
265220 index : Int ,
@@ -286,19 +241,6 @@ class SqlFormatPreProcessor : PreFormatProcessor {
286241 return attachmentKeywordType
287242 }
288243
289- /* *
290- * The column definition elements of Create Table, "(", "WORD", and ")" must be line breaks
291- */
292- private fun isNewLineOnlyCreateTable (nextElement : PsiElement ): Boolean =
293- nextElement.elementType == SqlTypes .LEFT_PAREN ||
294- nextElement.elementType == SqlTypes .RIGHT_PAREN ||
295- nextElement.elementType == SqlTypes .WORD
296-
297- fun <T > getElementsBeforeKeyword (
298- elements : List <T >,
299- isLeft : (T ) -> Boolean ,
300- ): List <T > = elements.takeWhile { element -> ! isLeft(element) }
301-
302244 private fun getNewLineString (
303245 prevElement : PsiElement ? ,
304246 text : String ,
@@ -316,10 +258,6 @@ class SqlFormatPreProcessor : PreFormatProcessor {
316258 element.text
317259 }
318260
319- private fun isSubGroupFirstElement (element : PsiElement ): Boolean =
320- getElementsBeforeKeyword(element.prevLeafs.toList()) { it.elementType == SqlTypes .LEFT_PAREN }
321- .findLast { it !is PsiWhiteSpace } == null
322-
323261 private fun logging () {
324262 PluginLoggerUtil .Companion .countLogging(
325263 this ::class .java.simpleName,
0 commit comments