From 06c804787ff575c3f2ba34b1aa3d3dd6f8f03118 Mon Sep 17 00:00:00 2001 From: gitreelike Date: Wed, 21 Sep 2016 00:21:06 +0200 Subject: [PATCH] Implement quick fix to convert a too long char literal to a string #KT-13635 Fixed --- .../kotlin/idea/quickfix/QuickFixRegistrar.kt | 2 + .../quickfix/TooLongCharLiteralToStringFix.kt | 39 +++++++++++++++++++ .../backslashShouldNotBeEscaped.kt | 5 +++ .../backslashShouldNotBeEscaped.kt.after | 5 +++ .../dollarShouldNotBeEscaped.kt | 6 +++ .../dollarShouldNotBeEscaped.kt.after | 6 +++ .../doubleQuotesShouldBeEscaped.kt | 5 +++ .../doubleQuotesShouldBeEscaped.kt.after | 5 +++ .../idea/quickfix/QuickFixTestGenerated.java | 27 +++++++++++++ 9 files changed, 100 insertions(+) create mode 100644 idea/src/org/jetbrains/kotlin/idea/quickfix/TooLongCharLiteralToStringFix.kt create mode 100644 idea/testData/quickfix/tooLongCharLiteralToString/backslashShouldNotBeEscaped.kt create mode 100644 idea/testData/quickfix/tooLongCharLiteralToString/backslashShouldNotBeEscaped.kt.after create mode 100644 idea/testData/quickfix/tooLongCharLiteralToString/dollarShouldNotBeEscaped.kt create mode 100644 idea/testData/quickfix/tooLongCharLiteralToString/dollarShouldNotBeEscaped.kt.after create mode 100644 idea/testData/quickfix/tooLongCharLiteralToString/doubleQuotesShouldBeEscaped.kt create mode 100644 idea/testData/quickfix/tooLongCharLiteralToString/doubleQuotesShouldBeEscaped.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 3a270fc00ac..f6fa14dc329 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -422,5 +422,7 @@ class QuickFixRegistrar : QuickFixContributor { FINAL_UPPER_BOUND.registerFactory(RemoveFinalUpperBoundFix) TYPE_PARAMETER_AS_REIFIED.registerFactory(AddReifiedToTypeParameterOfFunctionFix) + + TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL.registerFactory(TooLongCharLiteralToStringFix) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/TooLongCharLiteralToStringFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/TooLongCharLiteralToStringFix.kt new file mode 100644 index 00000000000..f0c4b8ae837 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/TooLongCharLiteralToStringFix.kt @@ -0,0 +1,39 @@ +package org.jetbrains.kotlin.idea.quickfix + +import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.psi.KtConstantExpression +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtPsiFactory + +class TooLongCharLiteralToStringFix( + element: KtConstantExpression +) : KotlinQuickFixAction(element) { + override fun getText(): String = "Convert too long character literal to string" + + override fun invoke(project: Project, editor: Editor?, file: KtFile) { + val text = element.text + if (!(text.startsWith("'") && text.endsWith("'") && text.length >= 2)) { + return + } + + val newStringContent = text + .slice(1..text.length - 2) + .replace("\"", "\\\"") + val newElement = KtPsiFactory(element).createStringTemplate(newStringContent) + + element.replace(newElement) + } + + override fun getFamilyName(): String = text + + companion object Factory : KotlinSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + val element = Errors.TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL.cast(diagnostic).psiElement + return TooLongCharLiteralToStringFix(element = element) + } + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/tooLongCharLiteralToString/backslashShouldNotBeEscaped.kt b/idea/testData/quickfix/tooLongCharLiteralToString/backslashShouldNotBeEscaped.kt new file mode 100644 index 00000000000..c2a826c8c3a --- /dev/null +++ b/idea/testData/quickfix/tooLongCharLiteralToString/backslashShouldNotBeEscaped.kt @@ -0,0 +1,5 @@ +// "Convert too long character literal to string" "true" + +fun foo() { + 'foo\nbar' +} \ No newline at end of file diff --git a/idea/testData/quickfix/tooLongCharLiteralToString/backslashShouldNotBeEscaped.kt.after b/idea/testData/quickfix/tooLongCharLiteralToString/backslashShouldNotBeEscaped.kt.after new file mode 100644 index 00000000000..6a45be53478 --- /dev/null +++ b/idea/testData/quickfix/tooLongCharLiteralToString/backslashShouldNotBeEscaped.kt.after @@ -0,0 +1,5 @@ +// "Convert too long character literal to string" "true" + +fun foo() { + "foo\nbar" +} \ No newline at end of file diff --git a/idea/testData/quickfix/tooLongCharLiteralToString/dollarShouldNotBeEscaped.kt b/idea/testData/quickfix/tooLongCharLiteralToString/dollarShouldNotBeEscaped.kt new file mode 100644 index 00000000000..744a8343ddf --- /dev/null +++ b/idea/testData/quickfix/tooLongCharLiteralToString/dollarShouldNotBeEscaped.kt @@ -0,0 +1,6 @@ +// "Convert too long character literal to string" "true" +// ERROR: Unresolved reference: bar + +fun foo() { + 'foo$bar' +} \ No newline at end of file diff --git a/idea/testData/quickfix/tooLongCharLiteralToString/dollarShouldNotBeEscaped.kt.after b/idea/testData/quickfix/tooLongCharLiteralToString/dollarShouldNotBeEscaped.kt.after new file mode 100644 index 00000000000..4cc34b15b95 --- /dev/null +++ b/idea/testData/quickfix/tooLongCharLiteralToString/dollarShouldNotBeEscaped.kt.after @@ -0,0 +1,6 @@ +// "Convert too long character literal to string" "true" +// ERROR: Unresolved reference: bar + +fun foo() { + "foo$bar" +} \ No newline at end of file diff --git a/idea/testData/quickfix/tooLongCharLiteralToString/doubleQuotesShouldBeEscaped.kt b/idea/testData/quickfix/tooLongCharLiteralToString/doubleQuotesShouldBeEscaped.kt new file mode 100644 index 00000000000..ecfb283f6c5 --- /dev/null +++ b/idea/testData/quickfix/tooLongCharLiteralToString/doubleQuotesShouldBeEscaped.kt @@ -0,0 +1,5 @@ +// "Convert too long character literal to string" "true" + +fun foo() { + 'foo"bar' +} \ No newline at end of file diff --git a/idea/testData/quickfix/tooLongCharLiteralToString/doubleQuotesShouldBeEscaped.kt.after b/idea/testData/quickfix/tooLongCharLiteralToString/doubleQuotesShouldBeEscaped.kt.after new file mode 100644 index 00000000000..ae09326af5d --- /dev/null +++ b/idea/testData/quickfix/tooLongCharLiteralToString/doubleQuotesShouldBeEscaped.kt.after @@ -0,0 +1,5 @@ +// "Convert too long character literal to string" "true" + +fun foo() { + "foo\"bar" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 46f9933c878..38a41e00d53 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -8348,6 +8348,33 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/tooLongCharLiteralToString") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TooLongCharLiteralToString extends AbstractQuickFixTest { + public void testAllFilesPresentInTooLongCharLiteralToString() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/tooLongCharLiteralToString"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("backslashShouldNotBeEscaped.kt") + public void testBackslashShouldNotBeEscaped() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/tooLongCharLiteralToString/backslashShouldNotBeEscaped.kt"); + doTest(fileName); + } + + @TestMetadata("dollarShouldNotBeEscaped.kt") + public void testDollarShouldNotBeEscaped() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/tooLongCharLiteralToString/dollarShouldNotBeEscaped.kt"); + doTest(fileName); + } + + @TestMetadata("doubleQuotesShouldBeEscaped.kt") + public void testDoubleQuotesShouldBeEscaped() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/tooLongCharLiteralToString/doubleQuotesShouldBeEscaped.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/quickfix/typeAddition") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)