PY-20803 Disable 'Replace with str.format method call' for string with * character...
authorValentina Kiryushkina <valentina.kiryushkina@jetbrains.com>
Fri, 16 Sep 2016 15:46:52 +0000 (18:46 +0300)
committerValentina Kiryushkina <valentina.kiryushkina@jetbrains.com>
Wed, 28 Sep 2016 11:36:09 +0000 (14:36 +0300)
python/src/com/jetbrains/python/codeInsight/intentions/ConvertFormatOperatorToMethodIntention.java
python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/starPrecision.py [new file with mode: 0644]
python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/starWidth.py [new file with mode: 0644]
python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/starWidthPrecision.py [new file with mode: 0644]
python/testSrc/com/jetbrains/python/intentions/PyConvertFormatOperatorToMethodIntentionTest.java

index f66411819763a8df19a5414aa6b013c64ca6b59a..753d6db758b8114c0f1b11ba97cffb97c3fde122 100644 (file)
@@ -30,6 +30,7 @@ import com.intellij.util.IncorrectOperationException;
 import com.jetbrains.python.PyBundle;
 import com.jetbrains.python.PyNames;
 import com.jetbrains.python.PyTokenTypes;
+import com.jetbrains.python.inspections.PyStringFormatParser;
 import com.jetbrains.python.psi.*;
 import com.jetbrains.python.psi.impl.PyBuiltinCache;
 import com.jetbrains.python.psi.impl.PyPsiUtils;
@@ -235,10 +236,21 @@ public class ConvertFormatOperatorToMethodIntention extends BaseIntentionAction
     if (binaryExpression.getLeftExpression() instanceof PyStringLiteralExpression 
         && binaryExpression.getOperator() == PyTokenTypes.PERC) {
       final PyStringLiteralExpression str = (PyStringLiteralExpression)binaryExpression.getLeftExpression();
-      if (!(str.getText().length() > 0 && Character.toUpperCase(str.getText().charAt(0)) == 'B')) {
-        setText(PyBundle.message("INTN.replace.with.method"));
-        return true;        
+      if ((str.getText().length() > 0 && Character.toUpperCase(str.getText().charAt(0)) == 'B')) {
+        return false;
       }
+
+      final List<PyStringFormatParser.SubstitutionChunk> chunks =
+        PyStringFormatParser.filterSubstitutions(PyStringFormatParser.parsePercentFormat(binaryExpression.getLeftExpression().getText()));
+
+      for (PyStringFormatParser.SubstitutionChunk chunk : chunks) {
+        if ("*".equals(chunk.getWidth()) || "*".equals(chunk.getPrecision())) {
+          return false;
+        }
+      }
+      
+      setText(PyBundle.message("INTN.replace.with.method"));
+      return true;
     }
     return false;
   }
diff --git a/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/starPrecision.py b/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/starPrecision.py
new file mode 100644 (file)
index 0000000..dbecdc8
--- /dev/null
@@ -0,0 +1 @@
+s = '%.*s = %.*f' % (3, 'Gibberish', 3, 2.7182)
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/starWidth.py b/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/starWidth.py
new file mode 100644 (file)
index 0000000..289ab0d
--- /dev/null
@@ -0,0 +1 @@
+s = '%*d' % (4, 5)
\ No newline at end of file
diff --git a/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/starWidthPrecision.py b/python/testData/intentions/PyConvertFormatOperatorToMethodIntentionTest/starWidthPrecision.py
new file mode 100644 (file)
index 0000000..5ee5040
--- /dev/null
@@ -0,0 +1 @@
+s = '%*.*f' % (5, 2, 2.7182)
\ No newline at end of file
index 62349ea11ad34f70d832639499f2038bea650d59..a8a09adb9f3894c253f88efded1f70da5ae31d93 100644 (file)
@@ -67,5 +67,20 @@ public class PyConvertFormatOperatorToMethodIntentionTest extends PyIntentionTes
   // PY-20800
   public void testRepr() {
     doTest(PyBundle.message("INTN.replace.with.method"), LanguageLevel.PYTHON26);
+  }
+  
+  // PY-20803
+  public void testStarWidth() {
+    doNegativeTest(PyBundle.message("INTN.replace.with.method"));
+  }
+  
+  // PY-20803
+  public void testStarPrecision() {
+    doNegativeTest(PyBundle.message("INTN.replace.with.method"));
+  }
+
+  // PY-20803
+  public void testStarWidthPrecision() {
+    doNegativeTest(PyBundle.message("INTN.replace.with.method"));    
   }  
 }
\ No newline at end of file