From af930b8364e99a84c1f51a5ae09427bde16974f9 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Sat, 28 Apr 2018 15:48:24 +0300 Subject: [PATCH] Review and fix raw string quotes inserting and remove (KT-2582) - Add more tests - Fix inserting close quotes after multiline string in file end - Use parent instead of parentOfType where possible - Add bunch files #KT-2582 Fixed --- idea/src/META-INF/plugin.xml.172 | 2 + idea/src/META-INF/plugin.xml.173 | 2 + idea/src/META-INF/plugin.xml.182 | 2 + idea/src/META-INF/plugin.xml.as31 | 2 + idea/src/META-INF/plugin.xml.as32 | 2 + .../editor/KotlinRawStringBackspaceHandler.kt | 6 +-- .../editor/KotlinRawStringTypedHandler.kt | 46 +++++++++++-------- .../backspaceHandler/rawStringDelete.kt | 2 +- .../backspaceHandler/rawStringDelete.kt.after | 2 +- .../backspaceHandler/rawStringInCloseQuote.kt | 1 + .../rawStringInCloseQuote.kt.after | 1 + .../backspaceHandler/rawStringInOpenQuote.kt | 1 + .../rawStringInOpenQuote.kt.after | 1 + .../kotlin/idea/editor/TypedHandlerTest.kt | 40 +++++++++++++++- .../BackspaceHandlerTestGenerated.java | 15 ++++++ 15 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 idea/testData/editor/backspaceHandler/rawStringInCloseQuote.kt create mode 100644 idea/testData/editor/backspaceHandler/rawStringInCloseQuote.kt.after create mode 100644 idea/testData/editor/backspaceHandler/rawStringInOpenQuote.kt create mode 100644 idea/testData/editor/backspaceHandler/rawStringInOpenQuote.kt.after diff --git a/idea/src/META-INF/plugin.xml.172 b/idea/src/META-INF/plugin.xml.172 index 3dedcd701e4..a47e4c5e90e 100644 --- a/idea/src/META-INF/plugin.xml.172 +++ b/idea/src/META-INF/plugin.xml.172 @@ -586,6 +586,7 @@ + + diff --git a/idea/src/META-INF/plugin.xml.173 b/idea/src/META-INF/plugin.xml.173 index 92f44b0b6a6..a4194405983 100644 --- a/idea/src/META-INF/plugin.xml.173 +++ b/idea/src/META-INF/plugin.xml.173 @@ -587,6 +587,7 @@ + + diff --git a/idea/src/META-INF/plugin.xml.182 b/idea/src/META-INF/plugin.xml.182 index 31a0249849b..c698bbb2d4f 100644 --- a/idea/src/META-INF/plugin.xml.182 +++ b/idea/src/META-INF/plugin.xml.182 @@ -587,6 +587,7 @@ + + diff --git a/idea/src/META-INF/plugin.xml.as31 b/idea/src/META-INF/plugin.xml.as31 index 9fd9279a8df..9f20ef0f078 100644 --- a/idea/src/META-INF/plugin.xml.as31 +++ b/idea/src/META-INF/plugin.xml.as31 @@ -586,6 +586,7 @@ + + diff --git a/idea/src/META-INF/plugin.xml.as32 b/idea/src/META-INF/plugin.xml.as32 index 53a9f3d769d..baf4d8c654c 100644 --- a/idea/src/META-INF/plugin.xml.as32 +++ b/idea/src/META-INF/plugin.xml.as32 @@ -586,6 +586,7 @@ + + diff --git a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringBackspaceHandler.kt b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringBackspaceHandler.kt index 60bb29c0ca1..be22b87c2aa 100644 --- a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringBackspaceHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringBackspaceHandler.kt @@ -21,7 +21,6 @@ import com.intellij.codeInsight.editorActions.BackspaceHandlerDelegate import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.RangeMarker import com.intellij.psi.PsiFile -import com.intellij.psi.util.parentOfType import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtStringTemplateExpression @@ -39,8 +38,8 @@ class KotlinRawStringBackspaceHandler : BackspaceHandlerDelegate() { val offset = editor.caretModel.offset val psiElement = file.findElementAt(offset) ?: return - psiElement.parentOfType(KtStringTemplateExpression::class)?.let { - if (it.text == "\"\"\"\"\"\"") { + psiElement.parent?.let { + if (it is KtStringTemplateExpression && it.text == "\"\"\"\"\"\"") { if (editor.caretModel.offset == it.textOffset + 3) { rangeMarker = editor.document.createRangeMarker(it.textRange) } @@ -54,6 +53,7 @@ class KotlinRawStringBackspaceHandler : BackspaceHandlerDelegate() { rangeMarker = null return true } + return false } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringTypedHandler.kt b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringTypedHandler.kt index 5b0dcebda58..c9934dcd3e0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringTypedHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/editor/KotlinRawStringTypedHandler.kt @@ -22,40 +22,46 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.fileTypes.FileType import com.intellij.openapi.project.Project import com.intellij.psi.PsiFile -import com.intellij.psi.util.PsiTreeUtil +import com.intellij.psi.impl.source.tree.LeafPsiElement +import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtStringTemplateExpression class KotlinRawStringTypedHandler : TypedHandlerDelegate() { override fun beforeCharTyped(c: Char, project: Project, editor: Editor, file: PsiFile, fileType: FileType): Result { + if (c != '"') { + return Result.CONTINUE + } if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_QUOTE) { return Result.CONTINUE } if (file !is KtFile) { return Result.CONTINUE } - if (c != '"') { - return Result.CONTINUE - } + // A quote is typed after 2 other quotes val offset = editor.caretModel.offset - // Check for caret at end of document - if (offset < editor.document.textLength) { - val psiElement = file.findElementAt(offset) ?: return Result.CONTINUE - if (PsiTreeUtil.getParentOfType(psiElement, KtStringTemplateExpression::class.java) != null) { - return Result.CONTINUE - } + if (offset < 2) { + return Result.CONTINUE } - val text = editor.document.text - if (offset >= 2) - if (text[offset - 1] == '"') - if (text[offset - 2] == '"') { - editor.document.insertString(offset, "\"\"\"\"") - editor.caretModel.currentCaret.moveToOffset(offset + 1) - return Result.STOP - } + val openQuote = file.findElementAt(offset - 2) + if (openQuote == null || openQuote !is LeafPsiElement || openQuote.elementType != KtTokens.OPEN_QUOTE) { + return Result.CONTINUE + } - return Result.CONTINUE + val closeQuote = file.findElementAt(offset - 1) + if (closeQuote == null || closeQuote !is LeafPsiElement || closeQuote.elementType != KtTokens.CLOSING_QUOTE) { + return Result.CONTINUE + } + + if (closeQuote.text != "\"") { + // Check it is not a multi-line quote + return Result.CONTINUE + } + + editor.document.insertString(offset, "\"\"\"\"") + editor.caretModel.currentCaret.moveToOffset(offset + 1) + + return Result.STOP } } \ No newline at end of file diff --git a/idea/testData/editor/backspaceHandler/rawStringDelete.kt b/idea/testData/editor/backspaceHandler/rawStringDelete.kt index 389cf906644..119dda63202 100644 --- a/idea/testData/editor/backspaceHandler/rawStringDelete.kt +++ b/idea/testData/editor/backspaceHandler/rawStringDelete.kt @@ -1 +1 @@ -"\"\"\"\"\"\"" \ No newline at end of file +val test = """""" \ No newline at end of file diff --git a/idea/testData/editor/backspaceHandler/rawStringDelete.kt.after b/idea/testData/editor/backspaceHandler/rawStringDelete.kt.after index 81389d50841..141510fa632 100644 --- a/idea/testData/editor/backspaceHandler/rawStringDelete.kt.after +++ b/idea/testData/editor/backspaceHandler/rawStringDelete.kt.after @@ -1 +1 @@ - \ No newline at end of file +val test = \ No newline at end of file diff --git a/idea/testData/editor/backspaceHandler/rawStringInCloseQuote.kt b/idea/testData/editor/backspaceHandler/rawStringInCloseQuote.kt new file mode 100644 index 00000000000..a4699fa6ee2 --- /dev/null +++ b/idea/testData/editor/backspaceHandler/rawStringInCloseQuote.kt @@ -0,0 +1 @@ +val test = """""" \ No newline at end of file diff --git a/idea/testData/editor/backspaceHandler/rawStringInCloseQuote.kt.after b/idea/testData/editor/backspaceHandler/rawStringInCloseQuote.kt.after new file mode 100644 index 00000000000..dae3d449f22 --- /dev/null +++ b/idea/testData/editor/backspaceHandler/rawStringInCloseQuote.kt.after @@ -0,0 +1 @@ +val test = """"" \ No newline at end of file diff --git a/idea/testData/editor/backspaceHandler/rawStringInOpenQuote.kt b/idea/testData/editor/backspaceHandler/rawStringInOpenQuote.kt new file mode 100644 index 00000000000..7c950f4547b --- /dev/null +++ b/idea/testData/editor/backspaceHandler/rawStringInOpenQuote.kt @@ -0,0 +1 @@ +val test = """""" \ No newline at end of file diff --git a/idea/testData/editor/backspaceHandler/rawStringInOpenQuote.kt.after b/idea/testData/editor/backspaceHandler/rawStringInOpenQuote.kt.after new file mode 100644 index 00000000000..bfac88bd19f --- /dev/null +++ b/idea/testData/editor/backspaceHandler/rawStringInOpenQuote.kt.after @@ -0,0 +1 @@ +val test = """"" \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt b/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt index 70d7d4d0025..3c10d5f3493 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/editor/TypedHandlerTest.kt @@ -74,10 +74,46 @@ class TypedHandlerTest : LightCodeInsightTestCase() { """val x = "$dollar{}]" """ ) - fun testAutoCloseRawString() = doCharTypeTest( + fun testAutoCloseRawStringInEnd() = doCharTypeTest( '"', """val x = """"", - """val x = ""${'"'}"""${'"'}""" + """val x = ""${'"'}""${'"'}""" + ) + + fun testNoAutoCloseRawStringInEnd() = doCharTypeTest( + '"', + """val x = ""${'"'}""", + """val x = ""${'"'}"""" + ) + + fun testAutoCloseRawStringInMiddle() = doCharTypeTest( + '"', + """ + val x = "" + val y = 12 + """.trimIndent(), + """ + val x = ""${'"'}""${'"'} + val y = 12 + """.trimIndent() + ) + + fun testNoAutoCloseBetweenMultiQuotes() = doCharTypeTest( + '"', + """val x = ""${'"'}${'"'}""/**/""", + """val x = ""${'"'}${'"'}""/**/""" + ) + + fun testNoAutoCloseBetweenMultiQuotes1() = doCharTypeTest( + '"', + """val x = ""${'"'}""${'"'}/**/""", + """val x = ""${'"'}""${'"'}/**/""" + ) + + fun testNoAutoCloseAfterEscape() = doCharTypeTest( + '"', + """val x = "\""""", + """val x = "\""${'"'}"""" ) fun testAutoCloseBraceInFunctionDeclaration() = doCharTypeTest( diff --git a/idea/tests/org/jetbrains/kotlin/idea/editor/backspaceHandler/BackspaceHandlerTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/editor/backspaceHandler/BackspaceHandlerTestGenerated.java index 0f58efcd586..55ea96ae218 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/editor/backspaceHandler/BackspaceHandlerTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/editor/backspaceHandler/BackspaceHandlerTestGenerated.java @@ -29,6 +29,21 @@ public class BackspaceHandlerTestGenerated extends AbstractBackspaceHandlerTest KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/editor/backspaceHandler"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("rawStringDelete.kt") + public void testRawStringDelete() throws Exception { + runTest("idea/testData/editor/backspaceHandler/rawStringDelete.kt"); + } + + @TestMetadata("rawStringInCloseQuote.kt") + public void testRawStringInCloseQuote() throws Exception { + runTest("idea/testData/editor/backspaceHandler/rawStringInCloseQuote.kt"); + } + + @TestMetadata("rawStringInOpenQuote.kt") + public void testRawStringInOpenQuote() throws Exception { + runTest("idea/testData/editor/backspaceHandler/rawStringInOpenQuote.kt"); + } + @TestMetadata("typeArguments.kt") public void testTypeArguments() throws Exception { runTest("idea/testData/editor/backspaceHandler/typeArguments.kt");