don't suggest to rewrite dictionary as literal if RHS of dict element assignment references dict itself (PY-1347)

This commit is contained in:
Dmitry Jemerov
2010-07-21 20:07:12 +04:00
parent f3acc7c422
commit 740131428c
4 changed files with 44 additions and 13 deletions
@@ -2,7 +2,9 @@ package com.jetbrains.python.inspections;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.actions.DictCreationQuickFix;
@@ -10,6 +12,9 @@ import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author Alexey.Ivanov
*/
@@ -39,7 +44,8 @@ public class PyDictCreationInspection extends PyInspection {
if (node.getTargets().length != 1) {
return;
}
String name = node.getTargets()[0].getName();
final PyExpression target = node.getTargets()[0];
String name = target.getName();
if (name == null) {
return;
}
@@ -54,7 +60,9 @@ loop:
for (Pair<PyExpression, PyExpression> targetToValue : assignmentStatement.getTargetsToValuesMapping()) {
if (targetToValue.first instanceof PySubscriptionExpression) {
PySubscriptionExpression subscriptionExpression = (PySubscriptionExpression)targetToValue.first;
if (name.equals(subscriptionExpression.getOperand().getName()) && subscriptionExpression.getIndexExpression() != null) {
if (name.equals(subscriptionExpression.getOperand().getName()) &&
subscriptionExpression.getIndexExpression() != null &&
!referencesTarget(targetToValue.second, target)) {
if (!availableFix) {
quickFix = new DictCreationQuickFix(node);
availableFix = true;
@@ -73,9 +81,24 @@ loop:
}
if (availableFix) {
registerProblem(node, "This dictionary creation could be rewritten by dictionary literal", quickFix);
registerProblem(node, "This dictionary creation could be rewritten as a dictionary literal", quickFix);
}
}
}
private boolean referencesTarget(PyExpression expression, final PyExpression target) {
final List<PsiElement> refs = new ArrayList<PsiElement>();
expression.accept(new PyRecursiveElementVisitor() {
@Override
public void visitPyReferenceExpression(PyReferenceExpression node) {
super.visitPyReferenceExpression(node);
final PsiPolyVariantReference ref = node.getReference();
if (ref.isReferenceTo(target)) {
refs.add(node);
}
}
});
return !refs.isEmpty();
}
}
}
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>test.py</file>
<line>1</line>
<description>This dictionary creation could be rewritten by dictionary literal</description>
</problem>
</problems>
@@ -0,0 +1,17 @@
<warning descr="This dictionary creation could be rewritten as a dictionary literal">dict = {"n": "n"}</warning>
dict["a"], dict["b"] = "a", "b"
dict["k"] = "k"
dict, a = {"n": "n"}
dict["a"], a["b"] = "a", "b"
dict["k"] = "k"
d = {}
foo()
d["a"] = 3
def someiter():
yield 1
yield 2
dikt = { 'results' : list(someiter()) }
dikt['num_results'] = len(dikt['results'])
@@ -102,8 +102,7 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase {
}
public void testPyDictCreationInspection() throws Throwable {
LocalInspectionTool inspection = new PyDictCreationInspection();
doTest(getTestName(false), inspection);
doHighlightingTest(PyDictCreationInspection.class);
}
public void testPyDeprecatedModulesInspection() throws Throwable {