diff --git a/idea/resources/intentionDescriptions/ToOrdinaryStringLiteralIntention/after.kt.template b/idea/resources/intentionDescriptions/ToOrdinaryStringLiteralIntention/after.kt.template
new file mode 100644
index 00000000000..ad71958b333
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ToOrdinaryStringLiteralIntention/after.kt.template
@@ -0,0 +1 @@
+val s = "\"Kotlin\nis\ngood!\""
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/ToOrdinaryStringLiteralIntention/before.kt.template b/idea/resources/intentionDescriptions/ToOrdinaryStringLiteralIntention/before.kt.template
new file mode 100644
index 00000000000..0f898619ce2
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ToOrdinaryStringLiteralIntention/before.kt.template
@@ -0,0 +1,3 @@
+val s = """"Kotlin
+is
+good!""""
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/ToOrdinaryStringLiteralIntention/description.html b/idea/resources/intentionDescriptions/ToOrdinaryStringLiteralIntention/description.html
new file mode 100644
index 00000000000..1a094758184
--- /dev/null
+++ b/idea/resources/intentionDescriptions/ToOrdinaryStringLiteralIntention/description.html
@@ -0,0 +1,5 @@
+
+
+This intention converts a raw string literal (one surrounded with triple quote characters) to ordinary one (surrounded with single quote characters).
+
+
\ No newline at end of file
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index aa30cb94ab4..07ad96ea547 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -1194,6 +1194,11 @@
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.ToOrdinaryStringLiteralIntention
+ Kotlin
+
+
(
+ KtStringTemplateExpression::class.java,
+ "To ordinary string literal"
+), LowPriorityAction {
+ override fun isApplicableTo(element: KtStringTemplateExpression): Boolean {
+ return element.text.startsWith("\"\"\"")
+ }
+
+ override fun applyTo(element: KtStringTemplateExpression, editor: Editor?) {
+ val text = buildString {
+ append("\"")
+
+ for (entry in element.entries) {
+ if (entry is KtLiteralStringTemplateEntry) {
+ var text = entry.text
+ text = text.replace("\\", "\\\\")
+ text = text.replace("\"", "\\\"")
+ text = StringUtil.convertLineSeparators(text, "\\n")
+ append(text)
+ }
+ else {
+ append(entry.text)
+ }
+ }
+
+ append("\"")
+ }
+ element.replace(KtPsiFactory(element).createExpression(text))
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/.intention b/idea/testData/intentions/toOrdinaryStringLiteral/.intention
new file mode 100644
index 00000000000..8f6c01a2165
--- /dev/null
+++ b/idea/testData/intentions/toOrdinaryStringLiteral/.intention
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.intentions.ToOrdinaryStringLiteralIntention
diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/lineBreakInExpression.kt b/idea/testData/intentions/toOrdinaryStringLiteral/lineBreakInExpression.kt
new file mode 100644
index 00000000000..9ad4572a668
--- /dev/null
+++ b/idea/testData/intentions/toOrdinaryStringLiteral/lineBreakInExpression.kt
@@ -0,0 +1,2 @@
+val v = """${2 +
+ 2}"""
\ No newline at end of file
diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/lineBreakInExpression.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/lineBreakInExpression.kt.after
new file mode 100644
index 00000000000..b71a9dc9c96
--- /dev/null
+++ b/idea/testData/intentions/toOrdinaryStringLiteral/lineBreakInExpression.kt.after
@@ -0,0 +1,2 @@
+val v = "${2 +
+ 2}"
\ No newline at end of file
diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/quotesAndSlashes.kt b/idea/testData/intentions/toOrdinaryStringLiteral/quotesAndSlashes.kt
new file mode 100644
index 00000000000..83e675cfcb9
--- /dev/null
+++ b/idea/testData/intentions/toOrdinaryStringLiteral/quotesAndSlashes.kt
@@ -0,0 +1 @@
+val v = """"Hello, world!" \ 'a'"""
\ No newline at end of file
diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/quotesAndSlashes.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/quotesAndSlashes.kt.after
new file mode 100644
index 00000000000..b75930b6a9e
--- /dev/null
+++ b/idea/testData/intentions/toOrdinaryStringLiteral/quotesAndSlashes.kt.after
@@ -0,0 +1 @@
+val v = "\"Hello, world!\" \\ 'a'"
\ No newline at end of file
diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/simple.kt b/idea/testData/intentions/toOrdinaryStringLiteral/simple.kt
new file mode 100644
index 00000000000..755d4a19631
--- /dev/null
+++ b/idea/testData/intentions/toOrdinaryStringLiteral/simple.kt
@@ -0,0 +1,2 @@
+val v = """"\Hello,
+world!\""""
\ No newline at end of file
diff --git a/idea/testData/intentions/toOrdinaryStringLiteral/simple.kt.after b/idea/testData/intentions/toOrdinaryStringLiteral/simple.kt.after
new file mode 100644
index 00000000000..3a17c96f351
--- /dev/null
+++ b/idea/testData/intentions/toOrdinaryStringLiteral/simple.kt.after
@@ -0,0 +1 @@
+val v = "\"\\Hello,\nworld!\\\""
\ 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 6a38a1c2f28..e78af45d318 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
@@ -9231,6 +9231,33 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
}
}
+ @TestMetadata("idea/testData/intentions/toOrdinaryStringLiteral")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class ToOrdinaryStringLiteral extends AbstractIntentionTest {
+ public void testAllFilesPresentInToOrdinaryStringLiteral() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/toOrdinaryStringLiteral"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
+ }
+
+ @TestMetadata("lineBreakInExpression.kt")
+ public void testLineBreakInExpression() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/toOrdinaryStringLiteral/lineBreakInExpression.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("quotesAndSlashes.kt")
+ public void testQuotesAndSlashes() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/toOrdinaryStringLiteral/quotesAndSlashes.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/toOrdinaryStringLiteral/simple.kt");
+ doTest(fileName);
+ }
+ }
+
@TestMetadata("idea/testData/intentions/toRawStringLiteral")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)