From 6b106e258a2ea03d77fdf5aeb1538d68f4666498 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Thu, 10 May 2012 18:20:38 +0400 Subject: [PATCH] fixed PY-6505 "Replace + with string formatting operator" is available in a context which has nothing to do with strings --- ...yStringConcatenationToFormatIntention.java | 27 ++++++++++--------- .../intentions/afterStringConcatToFormat3.py | 1 + .../intentions/beforeStringConcatToFormat3.py | 1 + .../com/jetbrains/python/PyIntentionTest.java | 4 +++ 4 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 python/testData/intentions/afterStringConcatToFormat3.py create mode 100644 python/testData/intentions/beforeStringConcatToFormat3.py diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyStringConcatenationToFormatIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyStringConcatenationToFormatIntention.java index 70c50026a554..3c08eadf809a 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyStringConcatenationToFormatIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyStringConcatenationToFormatIntention.java @@ -48,19 +48,16 @@ public class PyStringConcatenationToFormatIntention extends BaseIntentionAction if (expressions.size() == 0) { return false; } - boolean hasReferenceOrCall = false; final PyBuiltinCache cache = PyBuiltinCache.getInstance(element); for (PyExpression expression: expressions) { - if ((expression instanceof PyReferenceExpression - || expression instanceof PyCallExpression) && - PyTypeChecker.match(cache.getStringType(LanguageLevel.forElement(expression)), - expression.getType(TypeEvalContext.fast()), TypeEvalContext.fast())) - hasReferenceOrCall = true; - else if (!(expression instanceof PyStringLiteralExpression)) + final boolean isStringLiteral = expression instanceof PyStringLiteralExpression; + final boolean isStringReference = PyTypeChecker.match(cache.getStringType(LanguageLevel.forElement(expression)), + expression.getType(TypeEvalContext.fast()), TypeEvalContext.fast()); + if (!(isStringLiteral || ((expression instanceof PyReferenceExpression || expression instanceof PyCallExpression) && + isStringReference))) { return false; + } } - if (!hasReferenceOrCall) - return false; setText(PyBundle.message("INTN.replace.plus.with.format.operator")); return true; @@ -103,10 +100,16 @@ public class PyStringConcatenationToFormatIntention extends BaseIntentionAction PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); PyStringLiteralExpression stringLiteralExpression = elementGenerator.createStringLiteralAlreadyEscaped("\"" + stringLiteral.toString() + "\""); - String paramString = addParens > 1? "(" + parameters.substring(0, parameters.length() - 2) +")" + + if (addParens > 0) { + final String paramString = addParens > 1? "(" + parameters.substring(0, parameters.length() - 2) +")" : parameters.substring(0, parameters.length() - 2); - PyExpression expression = elementGenerator.createFromText(LanguageLevel.getDefault(), + final PyExpression expression = elementGenerator.createFromText(LanguageLevel.getDefault(), PyExpressionStatement.class, paramString).getExpression(); - element.replace(elementGenerator.createBinaryExpression("%", stringLiteralExpression, expression)); + element.replace(elementGenerator.createBinaryExpression("%", stringLiteralExpression, expression)); + } + else { + element.replace(stringLiteralExpression); + } } } diff --git a/python/testData/intentions/afterStringConcatToFormat3.py b/python/testData/intentions/afterStringConcatToFormat3.py new file mode 100644 index 000000000000..243f31733e26 --- /dev/null +++ b/python/testData/intentions/afterStringConcatToFormat3.py @@ -0,0 +1 @@ +foo = "foobar" \ No newline at end of file diff --git a/python/testData/intentions/beforeStringConcatToFormat3.py b/python/testData/intentions/beforeStringConcatToFormat3.py new file mode 100644 index 000000000000..076b0755a605 --- /dev/null +++ b/python/testData/intentions/beforeStringConcatToFormat3.py @@ -0,0 +1 @@ +foo = "foo" + "bar" \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyIntentionTest.java b/python/testSrc/com/jetbrains/python/PyIntentionTest.java index 7ca593abcf07..54e7a5bf5e85 100644 --- a/python/testSrc/com/jetbrains/python/PyIntentionTest.java +++ b/python/testSrc/com/jetbrains/python/PyIntentionTest.java @@ -114,6 +114,10 @@ public class PyIntentionTest extends PyTestCase { doNegativeTest(PyBundle.message("INTN.replace.plus.with.format.operator")); } + public void testStringConcatToFormat3() { //PY-6505 + doTest(PyBundle.message("INTN.replace.plus.with.format.operator")); + } + public void testConvertFormatOperatorToMethod() { doTest(PyBundle.message("INTN.replace.with.method"), LanguageLevel.PYTHON26); }