Fix PY-19000 Add expression types to RenameUnsupportedExpressionProcessor

Substitution in format string could resolve to these expressions and that produces exception during rename Add tests
This commit is contained in:
Valentina Kiryushkina
2016-04-19 13:54:44 +03:00
parent 7159040d5c
commit 84174f0ebe
11 changed files with 86 additions and 28 deletions
+1 -1
View File
@@ -452,7 +452,7 @@
<renamePsiElementProcessor implementation="com.jetbrains.python.refactoring.rename.RenamePyClassProcessor" order="before pyvar"/>
<renamePsiElementProcessor implementation="com.jetbrains.python.magicLiteral.PyMagicLiteralRenameProcessor" order="before pyvar"/>
<renamePsiElementProcessor implementation="com.jetbrains.python.refactoring.rename.RenamePyFileProcessor" order="first"/>
<renamePsiElementProcessor implementation="com.jetbrains.python.refactoring.rename.RenamePyLiteralExpressionProcessor"/>
<renamePsiElementProcessor implementation="com.jetbrains.python.refactoring.rename.RenameUnsupportedExpressionProcessor"/>
<automaticRenamerFactory implementation="com.jetbrains.python.refactoring.rename.PyContainingFileRenamerFactory"/>
<automaticRenamerFactory implementation="com.jetbrains.python.refactoring.rename.PyInheritorRenameFactory"/>
@@ -22,14 +22,23 @@ import com.intellij.refactoring.listeners.RefactoringElementListener;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
import com.jetbrains.python.psi.PyLiteralExpression;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class RenamePyLiteralExpressionProcessor extends RenamePyElementProcessor {
public class RenameUnsupportedExpressionProcessor extends RenamePyElementProcessor {
@Override
public boolean canProcessElement(@NotNull PsiElement element) {
return PsiTreeUtil.instanceOf(element, PyLiteralExpression.class);
return PsiTreeUtil.instanceOf(element,
PyStringLiteralExpression.class,
PyNumericLiteralExpression.class,
PyListLiteralExpression.class,
PyDictLiteralExpression.class,
PySetLiteralExpression.class,
PyStarArgument.class,
PyCallExpression.class,
PyBinaryExpression.class,
PySubscriptionExpression.class);
}
@Override
@@ -0,0 +1 @@
"%<caret>s" % (1+1)
@@ -0,0 +1,3 @@
def f():
return (1, 2)
"%<caret>s" % f()
@@ -0,0 +1 @@
"%<caret>s" % {"a": 1}
@@ -0,0 +1 @@
"%<caret>s" % [1, 2, 3]
@@ -0,0 +1 @@
"%<caret>s" % {"foo"}
@@ -0,0 +1,4 @@
def f():
return (1,2)
"{<caret>}".format(*f())
@@ -0,0 +1 @@
"{<caret>}".format("str")
@@ -0,0 +1 @@
"%<caret>s" % [1, 2][0]
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PythonTestUtil;
import com.jetbrains.python.documentation.docstrings.DocStringFormat;
import com.jetbrains.python.fixtures.PyTestCase;
@@ -236,39 +237,61 @@ public class PyRenameTest extends PyTestCase {
renameWithDocStringFormat(DocStringFormat.NUMPY, "bar");
}
//PY-2748
// PY-2748
public void testFormatStringKeyword() {
doTest("renamed");
}
//PY-2748
// PY-2748
public void testFormatStringDictLiteral() {
myFixture.configureByFile(RENAME_DATA_PATH + getTestName(true) + ".py");
try {
myFixture.renameElementAtCaret("renamed");
}
catch (RuntimeException e) {
if ("com.intellij.util.IncorrectOperationException".equals(e.getMessage())) {
return;
}
}
fail();
doUnsupportedOperationTest();
}
//PY-2748
// PY-2748
public void testFormatStringNumericLiteralExpression() {
myFixture.configureByFile(RENAME_DATA_PATH + getTestName(true) + ".py");
try {
myFixture.renameElementAtCaret("renamed");
}
catch (RuntimeException e) {
if ("com.intellij.util.IncorrectOperationException".equals(e.getMessage())) {
return;
}
}
fail();
doUnsupportedOperationTest();
}
// PY-19000
public void testStringAsPositionalFormatFunctionArgument() {
doUnsupportedOperationTest();
}
// PY-19000
public void testSetAsPercentArg() {
doUnsupportedOperationTest();
}
// PY-19000
public void testListAsPercentArg() {
doUnsupportedOperationTest();
}
// PY-19000
public void testCallAsPercentArg() {
doUnsupportedOperationTest();
}
// PY-19000
public void testStarAsFormatFunctionArg() {
doUnsupportedOperationTest();
}
// PY-19000
public void testSubscriptionAsPercentArg() {
doUnsupportedOperationTest();
}
// PY-19000
public void testBinaryAsPercentArg() {
doUnsupportedOperationTest();
}
// PY-19000
public void testDictAsPercentArg() {
doUnsupportedOperationTest();
}
private void renameWithDocStringFormat(DocStringFormat format, final String newName) {
runWithDocStringFormat(format, new Runnable() {
public void run() {
@@ -277,6 +300,19 @@ public class PyRenameTest extends PyTestCase {
});
}
private void doUnsupportedOperationTest() {
myFixture.configureByFile(RENAME_DATA_PATH + getTestName(true) + ".py");
try {
myFixture.renameElementAtCaret("renamed");
}
catch (RuntimeException e) {
if (e.getCause() instanceof IncorrectOperationException) {
return;
}
}
fail();
}
private void doRenameConflictTest(String newName, String expectedConflict) {
myFixture.configureByFile(RENAME_DATA_PATH + getTestName(true) + ".py");
try {