fixed PY-7715 replace with augmented assignment doesn't work in case of subscription

This commit is contained in:
Ekaterina Tuzova
2013-01-16 16:54:27 +04:00
parent df5ef4abf1
commit 0f3e4fe397
4 changed files with 22 additions and 48 deletions
@@ -5,14 +5,10 @@ import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyAugAssignmentStatementImpl;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -59,54 +55,21 @@ public class AugmentedAssignmentQuickFix implements LocalQuickFix {
if ((leftExpression instanceof PyReferenceExpression || leftExpression instanceof PySubscriptionExpression)) {
if (leftExpression.getText().equals(targetText)) {
if (rightExpression instanceof PyNumericLiteralExpression || rightExpression instanceof PyStringLiteralExpression ||
rightExpression instanceof PyCallExpression || rightExpression instanceof PyReferenceExpression
|| isPercentage(rightExpression) || isCompound(rightExpression) || isMathOperation(rightExpression, expression.getOperator())) {
final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project);
final StringBuilder stringBuilder = new StringBuilder();
final PsiElement psiOperator = expression.getPsiOperator();
if (psiOperator == null) return;
stringBuilder.append(targetText).append(" ").
append(psiOperator.getText()).append("= ").append(rightExpression.getText());
final PyAugAssignmentStatementImpl augAssignment = elementGenerator.createFromText(LanguageLevel.forElement(element),
PyAugAssignmentStatementImpl.class, stringBuilder.toString());
for (PsiComment comment : comments)
augAssignment.add(comment);
statement.replace(augAssignment);
}
final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project);
final StringBuilder stringBuilder = new StringBuilder();
final PsiElement psiOperator = expression.getPsiOperator();
if (psiOperator == null) return;
stringBuilder.append(targetText).append(" ").
append(psiOperator.getText()).append("= ").append(rightExpression.getText());
final PyAugAssignmentStatementImpl augAssignment = elementGenerator.createFromText(LanguageLevel.forElement(element),
PyAugAssignmentStatementImpl.class, stringBuilder.toString());
for (PsiComment comment : comments)
augAssignment.add(comment);
statement.replace(augAssignment);
}
}
}
}
}
private static boolean isCompound(final PyExpression rightExpression) {
if (rightExpression instanceof PyCallExpression) {
final PyType type = rightExpression.getType(TypeEvalContext.fast());
if (type != null && type.isBuiltin(TypeEvalContext.fast()) &&
("int".equals(type.getName()) || "str".equals(type.getName()))) return true;
}
return false;
}
private static boolean isPercentage(final PyExpression rightExpression) {
return (rightExpression instanceof PyBinaryExpression &&
((PyBinaryExpression)rightExpression).getLeftExpression() instanceof PyStringLiteralExpression &&
((PyBinaryExpression)rightExpression).getOperator() == PyTokenTypes.PERC);
}
private static boolean isMathOperation(final PyExpression rightExpression, final PyElementType mainOperator) {
final TokenSet first = TokenSet.create(PyTokenTypes.EXP, PyTokenTypes.FLOORDIV);
final TokenSet second = TokenSet.create(PyTokenTypes.MULT, PyTokenTypes.DIV, PyTokenTypes.PERC);
final TokenSet third = TokenSet.create(PyTokenTypes.PLUS, PyTokenTypes.MINUS);
if (rightExpression instanceof PyBinaryExpression){
final PyElementType operator = ((PyBinaryExpression)rightExpression).getOperator();
if (third.contains(mainOperator))
return true;
else if (second.contains(mainOperator) && (second.contains(operator) || first.contains(operator)))
return true;
}
return false;
}
}
@@ -0,0 +1,3 @@
current_sum = 1
numbers = [1, 2, 3]
<weak_warning descr="Assignment can be replaced with augmented assignment">current_sum = current_sum + numbers[0]</weak_warning>
@@ -0,0 +1,3 @@
current_sum = 1
numbers = [1, 2, 3]
current_sum += numbers[0]
@@ -241,6 +241,11 @@ public class PyQuickFixTest extends PyTestCase {
PyBundle.message("QFIX.augment.assignment"), true, true);
}
public void testAugmentAssignmentSubscription() { // PY-7715
doInspectionTest("AugmentAssignmentFunction.py", PyAugmentAssignmentInspection.class,
PyBundle.message("QFIX.augment.assignment"), true, true);
}
public void testChainedComparisons() { // PY-1020
doInspectionTest("ChainedComparisons.py", PyChainedComparisonsInspection.class,
PyBundle.message("QFIX.chained.comparison"), true, true);