diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyQuotedStringIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyQuotedStringIntention.java index 258a154f616e..c73e3216038b 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyQuotedStringIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyQuotedStringIntention.java @@ -1,7 +1,6 @@ package com.jetbrains.python.codeInsight.intentions; import com.intellij.codeInsight.intention.impl.BaseIntentionAction; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; @@ -58,29 +57,25 @@ public class PyQuotedStringIntention extends BaseIntentionAction { PyStringLiteralExpression string = PsiTreeUtil.getParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PyStringLiteralExpression.class); PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); if (string != null) { - StringBuilder strBuilder = new StringBuilder(); - for (ASTNode node : string.getStringNodes()) - strBuilder.append(node.getText()); - String stringText = strBuilder.toString(); + final String stringText = string.getText(); int prefixLength = PyStringLiteralExpressionImpl.getPrefixLength(stringText); - String prefix = stringText.substring(0, prefixLength); - stringText = stringText.substring(prefixLength); + final String text = stringText.substring(prefixLength); - if (stringText.startsWith("'") && stringText.endsWith("'")) { + if (text.startsWith("'") && text.endsWith("'")) { String result = convertSingleToDoubleQuoted(stringText); - PyStringLiteralExpression st = elementGenerator.createStringLiteralAlreadyEscaped(prefix + result); + PyStringLiteralExpression st = elementGenerator.createStringLiteralAlreadyEscaped(result); string.replace(st); } - if (stringText.startsWith("\"") && stringText.endsWith("\"")) { + if (text.startsWith("\"") && text.endsWith("\"")) { String result = convertDoubleToSingleQuoted(stringText); - PyStringLiteralExpression st = elementGenerator.createStringLiteralAlreadyEscaped(prefix + result); + PyStringLiteralExpression st = elementGenerator.createStringLiteralAlreadyEscaped(result); string.replace(st); } } } private static String convertDoubleToSingleQuoted(String stringText) { - StringBuilder stringBuilder = new StringBuilder("'"); + StringBuilder stringBuilder = new StringBuilder(); boolean skipNext = false; char[] charArr = stringText.toCharArray(); @@ -91,8 +86,8 @@ public class PyQuotedStringIntention extends BaseIntentionAction { continue; } if (ch == '"') { + stringBuilder.append('\''); continue; - // stringBuilder.append('\''); } else if (ch == '\'') { stringBuilder.append("\\\'"); @@ -106,12 +101,11 @@ public class PyQuotedStringIntention extends BaseIntentionAction { } } - stringBuilder.append("'"); return stringBuilder.toString(); } private static String convertSingleToDoubleQuoted(String stringText) { - StringBuilder stringBuilder = new StringBuilder("\""); + StringBuilder stringBuilder = new StringBuilder(); boolean skipNext = false; char[] charArr = stringText.toCharArray(); for (int i = 0; i != charArr.length; ++i) { @@ -121,8 +115,8 @@ public class PyQuotedStringIntention extends BaseIntentionAction { continue; } if (ch == '\'') { + stringBuilder.append('"'); continue; - //stringBuilder.append('"'); } else if (ch == '"') { stringBuilder.append("\\\""); @@ -135,7 +129,6 @@ public class PyQuotedStringIntention extends BaseIntentionAction { stringBuilder.append(ch); } } - stringBuilder.append("\""); return stringBuilder.toString(); } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java b/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java index 3fe0bbf99959..eec1e18cbde4 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java @@ -56,9 +56,9 @@ public class PyElementGeneratorImpl extends PyElementGenerator { } public PyStringLiteralExpression createStringLiteralAlreadyEscaped(String str) { - final PsiFile dummyFile = createDummyFile(LanguageLevel.getDefault(), "a=" + str); + final PsiFile dummyFile = createDummyFile(LanguageLevel.getDefault(), "a=(" + str + ")"); final PyAssignmentStatement expressionStatement = (PyAssignmentStatement)dummyFile.getFirstChild(); - return (PyStringLiteralExpression)expressionStatement.getAssignedValue(); + return (PyStringLiteralExpression)((PyParenthesizedExpression)expressionStatement.getAssignedValue()).getContainedExpression(); } diff --git a/python/testData/intentions/afterDoubledQuotedString.py b/python/testData/intentions/afterDoubledQuotedString.py index c44de2c7846d..0486ca0462ef 100644 --- a/python/testData/intentions/afterDoubledQuotedString.py +++ b/python/testData/intentions/afterDoubledQuotedString.py @@ -1 +1,2 @@ -test_function('String resuming string'.format(a, b)) \ No newline at end of file +test_function('String ' + 'resuming string'.format(a, b)) \ No newline at end of file diff --git a/python/testData/intentions/afterMultilineQuotedString.py b/python/testData/intentions/afterMultilineQuotedString.py new file mode 100644 index 000000000000..8559645f08c8 --- /dev/null +++ b/python/testData/intentions/afterMultilineQuotedString.py @@ -0,0 +1,5 @@ +def foo(): + return ( + r'oo' + r'ps', + ) diff --git a/python/testData/intentions/beforeMultilineQuotedString.py b/python/testData/intentions/beforeMultilineQuotedString.py new file mode 100644 index 000000000000..d691712775b1 --- /dev/null +++ b/python/testData/intentions/beforeMultilineQuotedString.py @@ -0,0 +1,5 @@ +def foo(): + return ( + r"oo" + r"ps", + ) diff --git a/python/testSrc/com/jetbrains/python/PyIntentionTest.java b/python/testSrc/com/jetbrains/python/PyIntentionTest.java index e5cfd68cd328..7a415f7241da 100644 --- a/python/testSrc/com/jetbrains/python/PyIntentionTest.java +++ b/python/testSrc/com/jetbrains/python/PyIntentionTest.java @@ -214,6 +214,10 @@ public class PyIntentionTest extends PyTestCase { doTest(PyBundle.message("INTN.quoted.string.double.to.single")); } + public void testMultilineQuotedString() { //PY-8064 + doTest(PyBundle.message("INTN.quoted.string.double.to.single")); + } + public void testConvertLambdaToFunction() { doTest(PyBundle.message("INTN.convert.lambda.to.function")); }