From 81d01a8f8e70347f654439e5214a6e1ba0d3a77d Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Thu, 6 Feb 2020 23:13:14 +0900 Subject: [PATCH] "To ordinary string literal": don't add unnecessary escapes to characters in template expression #KT-36406 Fixed --- .../ToOrdinaryStringLiteralIntention.kt | 20 +++++++++++++------ .../quotesInExpression.kt | 4 ++++ .../quotesInExpression.kt.after | 4 ++++ .../toOrdinaryStringLiteral/trimIndent10.kt | 8 ++++++++ .../trimIndent10.kt.after | 6 ++++++ .../toOrdinaryStringLiteral/trimIndent11.kt | 8 ++++++++ .../trimIndent11.kt.after | 4 ++++ .../intentions/IntentionTestGenerated.java | 15 ++++++++++++++ 8 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 idea/testData/intentions/toOrdinaryStringLiteral/quotesInExpression.kt create mode 100644 idea/testData/intentions/toOrdinaryStringLiteral/quotesInExpression.kt.after create mode 100644 idea/testData/intentions/toOrdinaryStringLiteral/trimIndent10.kt create mode 100644 idea/testData/intentions/toOrdinaryStringLiteral/trimIndent10.kt.after create mode 100644 idea/testData/intentions/toOrdinaryStringLiteral/trimIndent11.kt create mode 100644 idea/testData/intentions/toOrdinaryStringLiteral/trimIndent11.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt index 3857abc18a0..7c9b577cf52 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ToOrdinaryStringLiteralIntention.kt @@ -58,10 +58,16 @@ class ToOrdinaryStringLiteralIntention : SelfTargetingOffsetIndependentIntention editor?.caretModel?.moveToOffset(offset) } - private fun String.escape(): String = StringUtil.convertLineSeparators( - replace("\\", "\\\\").replace("\"", "\\\""), - "\\n" - ) + private fun String.escape(escapeLineSeparators: Boolean = true): String { + var text = this + text = text.replace("\\", "\\\\") + text = text.replace("\"", "\\\"") + return if (escapeLineSeparators) text.escapeLineSeparators() else text + } + + private fun String.escapeLineSeparators(): String { + return StringUtil.convertLineSeparators(this, "\\n") + } private fun getTrimIndentCall( element: KtStringTemplateExpression, @@ -82,9 +88,11 @@ class ToOrdinaryStringLiteralIntention : SelfTargetingOffsetIndependentIntention } val stringTemplateText = entries - .joinToString(separator = "") { it.text } + .joinToString(separator = "") { + if (it is KtLiteralStringTemplateEntry) it.text.escape(escapeLineSeparators = false) else it.text + } .let { if (marginPrefix != null) it.trimMargin(marginPrefix) else it.trimIndent() } - .escape() + .escapeLineSeparators() return TrimIndentCall(qualifiedExpression, stringTemplateText) } diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/quotesInExpression.kt b/idea/testData/intentions/toOrdinaryStringLiteral/quotesInExpression.kt new file mode 100644 index 00000000000..5c3d430689a --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/quotesInExpression.kt @@ -0,0 +1,4 @@ +// WITH_RUNTIME +fun test(list: List) { + val s = """foo ${list.joinToString(", ")} bar""" +} \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/quotesInExpression.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/quotesInExpression.kt.after new file mode 100644 index 00000000000..eb17fa95109 --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/quotesInExpression.kt.after @@ -0,0 +1,4 @@ +// WITH_RUNTIME +fun test(list: List) { + val s = "foo ${list.joinToString(", ")} bar" +} \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent10.kt b/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent10.kt new file mode 100644 index 00000000000..145c0bdb0bf --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent10.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME +data class Column(val name: String) + +fun test(columns: List) { + val sql = """ + SELECT ${columns.joinToString(", ")} FROM foo + """.trimIndent() +} \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent10.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent10.kt.after new file mode 100644 index 00000000000..e96d62a78ad --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent10.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME +data class Column(val name: String) + +fun test(columns: List) { + val sql = "SELECT ${columns.joinToString(", ")} FROM foo" +} \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent11.kt b/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent11.kt new file mode 100644 index 00000000000..fa52d27c83a --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent11.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME +fun test(list: List) { + val s = """ + "\foo + ${list.joinToString(",")} + "\bar + """.trimIndent() +} \ No newline at end of file diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent11.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent11.kt.after new file mode 100644 index 00000000000..b92ed09e9e4 --- /dev/null +++ b/idea/testData/intentions/toOrdinaryStringLiteral/trimIndent11.kt.after @@ -0,0 +1,4 @@ +// WITH_RUNTIME +fun test(list: List) { + val s = "\"\\foo\n${list.joinToString(",")}\n\"\\bar" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 550ff0610a6..6c8bc2fd24e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -16168,6 +16168,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest { runTest("idea/testData/intentions/toOrdinaryStringLiteral/quotesAndSlashes.kt"); } + @TestMetadata("quotesInExpression.kt") + public void testQuotesInExpression() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/quotesInExpression.kt"); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { runTest("idea/testData/intentions/toOrdinaryStringLiteral/simple.kt"); @@ -16178,6 +16183,16 @@ public class IntentionTestGenerated extends AbstractIntentionTest { runTest("idea/testData/intentions/toOrdinaryStringLiteral/trimIndent1.kt"); } + @TestMetadata("trimIndent10.kt") + public void testTrimIndent10() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/trimIndent10.kt"); + } + + @TestMetadata("trimIndent11.kt") + public void testTrimIndent11() throws Exception { + runTest("idea/testData/intentions/toOrdinaryStringLiteral/trimIndent11.kt"); + } + @TestMetadata("trimIndent2.kt") public void testTrimIndent2() throws Exception { runTest("idea/testData/intentions/toOrdinaryStringLiteral/trimIndent2.kt");