fixed PY-3125 Inspection: Argument value is equal to default parameter value plus quickFix

This commit is contained in:
Ekaterina Tuzova
2011-03-23 17:33:56 +03:00
parent 77512575a3
commit 71e5ac1ada
9 changed files with 138 additions and 0 deletions
@@ -78,6 +78,9 @@ QFIX.unresolved.reference.replace.$0=Replace with {0}
#PyDefaultArgumentQuickFix
QFIX.default.argument=Replace mutable default argument
#RemoveArgumentEqualDefaultQuickFix
QFIX.remove.argument.equal.default=Remove argument equal to default
# Intentions: INTN
INTN.Family.convert.import.unqualify=Convert 'import module' to 'from module import'
INTN.Family.convert.import.qualify=Convert 'from module import' to 'import module'
@@ -360,6 +363,9 @@ INSP.NAME.augment.assignment=Assignment can be replaced with augmented assignmen
# PyChainedComparsonsInspection
INSP.NAME.chained.comparisons=Chained comparisons can be simplified
# PyArgumentEqualDefaultInspection
INSP.NAME.argument.equal.default=Argument passed to function is equal to default parameter value
# PyOldStyleClassesInspection
INSP.NAME.oldstyle.class=Old-style class contains new-style class features
@@ -0,0 +1,30 @@
package com.jetbrains.python.actions;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.PyBundle;
import org.jetbrains.annotations.NotNull;
/**
* User: catherine
*
* QuickFix to remove redundant argument equal default
*/
public class RemoveArgumentEqualDefaultQuickFix implements LocalQuickFix {
@NotNull
public String getName() {
return PyBundle.message("QFIX.remove.argument.equal.default");
}
@NotNull
public String getFamilyName() {
return PyBundle.message("INSP.GROUP.python");
}
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getPsiElement();
element.delete();
}
}
@@ -0,0 +1,77 @@
package com.jetbrains.python.inspections;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiReference;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.actions.RemoveArgumentEqualDefaultQuickFix;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
/**
* User: catherine
*
* Inspection to detect situations, where argument passed to function
* is equal to default parameter value
* for instance,
* dict().get(x, None) --> None is default value for second param in dict().get function
*/
public class PyArgumentEqualDefaultInspection extends PyInspection {
@Nls
@NotNull
@Override
public String getDisplayName() {
return PyBundle.message("INSP.NAME.argument.equal.default");
}
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
return new Visitor(holder);
}
private static class Visitor extends PyInspectionVisitor {
public Visitor(final ProblemsHolder holder) {
super(holder);
}
@Override
public void visitPyCallExpression(final PyCallExpression node){
PyExpression[] arguments = node.getArguments();
PyExpression callee = node.getCallee();
if (callee != null) {
PsiReference ref = callee.getReference();
if (ref != null) {
PsiElement function = ref.resolve();
if (function instanceof PyFunction) {
checkArguments(function, arguments);
}
}
}
}
private void checkArguments(PsiElement function, PyExpression[] arguments) {
int argumentsSize = arguments.length;
PyClass containingClass = ((PyFunction)function).getContainingClass();
int adjust = 0;
if (containingClass != null)
adjust = 1;
PyParameter[] params = ((PyFunction)function).getParameterList().getParameters();
for (int i = 0; i != params.length - adjust; ++i) {
PyParameter p = params[i+adjust];
if (p instanceof PyNamedParameter) {
PyExpression defaultValue = p.getDefaultValue();
if (defaultValue != null && i < argumentsSize) {
if (arguments[i].getText().equals(defaultValue.getText())) {
registerProblem(arguments[i], "Argument equals to default parameter value",
new RemoveArgumentEqualDefaultQuickFix());
}
}
}
}
}
}
}
@@ -57,6 +57,7 @@ public class PythonInspectionToolProvider implements InspectionToolProvider {
PyUnnecessaryBackslashInspection.class,
PySingleQuotedDocstringInspection.class,
PyMissingConstructorInspection.class,
PyArgumentEqualDefaultInspection.class,
};
}
}
@@ -0,0 +1,4 @@
def foo(a, b = 345, c = 1):
pass
foo(1, <warning descr="Argument equals to default parameter value">345<caret></warning>, 22)
@@ -0,0 +1,4 @@
def foo(a, b = 345, c = 1):
pass
foo(1, 22)
@@ -0,0 +1,7 @@
def foo(a, b = 345, c = 1):
pass
foo(1, <warning descr="Argument equals to default parameter value">345</warning>, 22)
a = dict()
a.get(1, <warning descr="Argument equals to default parameter value">None</warning>)
@@ -235,6 +235,11 @@ public class PyQuickFixTest extends PyLightFixtureTestCase {
PyBundle.message("QFIX.default.argument"), true, true);
}
public void testPyArgumentEqualDefault() { //PY-3125
doInspectionTest("ArgumentEqualDefault.py", PyArgumentEqualDefaultInspection.class,
PyBundle.message("QFIX.remove.argument.equal.default"), true, true);
}
public void testUnnecessaryBackslash() {
String[] testFiles = new String[]{"UnnecessaryBackslash.py"};
myFixture.enableInspections(PyUnnecessaryBackslashInspection.class);
@@ -322,4 +322,8 @@ public class PythonInspectionsTest extends PyLightFixtureTestCase {
setLanguageLevel(LanguageLevel.PYTHON30);
doHighlightingTest(PyMissingConstructorInspection.class);
}
public void testPyArgumentEqualDefaultInspection() { //PY-3125
doHighlightingTest(PyArgumentEqualDefaultInspection.class);
}
}