From d320cedecdca9058b39f738cdaa1ed403a32c807 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 17 Aug 2010 20:03:53 +0400 Subject: [PATCH] unused constructor parameters have quickfix to initialize field (PY-1398) --- .../python/actions/AddFieldQuickFix.java | 16 ++++++++------ .../PyUnresolvedReferencesInspection.java | 2 +- .../PyUnusedLocalInspectionVisitor.java | 21 ++++++++++++++----- .../inspections/FieldFromUnusedParameter.py | 3 +++ .../FieldFromUnusedParameter_after.py | 3 +++ .../com/jetbrains/python/PyQuickFixTest.java | 4 ++++ 6 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 python/testData/inspections/FieldFromUnusedParameter.py create mode 100644 python/testData/inspections/FieldFromUnusedParameter_after.py diff --git a/python/src/com/jetbrains/python/actions/AddFieldQuickFix.java b/python/src/com/jetbrains/python/actions/AddFieldQuickFix.java index 68c4338e4bb8..4bf80e502d52 100644 --- a/python/src/com/jetbrains/python/actions/AddFieldQuickFix.java +++ b/python/src/com/jetbrains/python/actions/AddFieldQuickFix.java @@ -25,11 +25,13 @@ import org.jetbrains.annotations.Nullable; public class AddFieldQuickFix implements LocalQuickFix { private PyClass myQualifierClass; + private final String myInitializer; private String myIdentifier; - public AddFieldQuickFix(String identifier, PyClass qualifierClass) { + public AddFieldQuickFix(String identifier, PyClass qualifierClass, String initializer) { myIdentifier = identifier; myQualifierClass = qualifierClass; + myInitializer = initializer; } @NotNull @@ -67,7 +69,7 @@ public class AddFieldQuickFix implements LocalQuickFix { PyClass cls = myQualifierClass; String item_name = myIdentifier; if (cls != null) { - PsiElement initStatement = addFieldToInit(project, cls, item_name, new CreateFieldCallback(project, item_name)); + PsiElement initStatement = addFieldToInit(project, cls, item_name, new CreateFieldCallback(project, item_name, myInitializer)); if (initStatement != null) { showTemplateBuilder(initStatement); return; @@ -77,11 +79,11 @@ public class AddFieldQuickFix implements LocalQuickFix { PyUtil.showBalloon(project, PyBundle.message("QFIX.failed.to.add.field"), MessageType.ERROR); } - private static void showTemplateBuilder(PsiElement initStatement) { + private void showTemplateBuilder(PsiElement initStatement) { initStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(initStatement); if (initStatement instanceof PyAssignmentStatement) { final TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(initStatement); - builder.replaceElement(((PyAssignmentStatement) initStatement).getAssignedValue(), "None"); + builder.replaceElement(((PyAssignmentStatement) initStatement).getAssignedValue(), myInitializer); builder.run(); } } @@ -159,14 +161,16 @@ public class AddFieldQuickFix implements LocalQuickFix { private static class CreateFieldCallback implements Function { private Project myProject; private String myItemName; + private String myInitializer; - private CreateFieldCallback(Project project, String itemName) { + private CreateFieldCallback(Project project, String itemName, String initializer) { myProject = project; myItemName = itemName; + myInitializer = initializer; } public PyStatement fun(String self_name) { - return PyElementGenerator.getInstance(myProject).createFromText(PyStatement.class, self_name + "." + myItemName + " = None"); + return PyElementGenerator.getInstance(myProject).createFromText(PyStatement.class, self_name + "." + myItemName + " = " + myInitializer); } } } diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java index 61106bd71a8d..affa952cb434 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java @@ -210,7 +210,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection { if (reference.getElement().getParent() instanceof PyCallExpression) { actions.add(new AddMethodQuickFix(ref_text, (PyClassType)qtype)); } - else actions.add(new AddFieldQuickFix(ref_text, cls)); + else actions.add(new AddFieldQuickFix(ref_text, cls, "None")); } } description_buf.append(PyBundle.message("INSP.unresolved.ref.$0.for.class.$1", ref_text, qtype.getName())); diff --git a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java index cd3dca1521c3..13216a58da39 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java +++ b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java @@ -17,6 +17,8 @@ import com.intellij.psi.ResolveResult; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Function; import com.jetbrains.python.PyBundle; +import com.jetbrains.python.PyNames; +import com.jetbrains.python.actions.AddFieldQuickFix; import com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.codeInsight.dataflow.scope.Scope; @@ -244,14 +246,23 @@ class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { continue; } } + boolean isInitMethod = false; + PyClass containingClass = null; PyParameterList paramList = PsiTreeUtil.getParentOfType(element, PyParameterList.class); if (paramList != null && paramList.getParent() instanceof PyFunction) { PyFunction func = (PyFunction) paramList.getParent(); - if (canHaveUnusedParameters(func, functionsWithInheritors)) { + containingClass = func.getContainingClass(); + if (PyNames.INIT.equals(func.getName()) && containingClass != null) { + isInitMethod = true; + } + else if (ignoreUnusedParameters(func, functionsWithInheritors)) { continue; } } - registerWarning(element, PyBundle.message("INSP.unused.locals.parameter.isnot.used", name)); + LocalQuickFix[] fixes = isInitMethod + ? new LocalQuickFix[] { new AddFieldQuickFix(name, containingClass, name) } + : LocalQuickFix.EMPTY_ARRAY; + registerWarning(element, PyBundle.message("INSP.unused.locals.parameter.isnot.used", name), fixes); } else { if (myIgnoreTupleUnpacking && isTupleUnpacking(element)) { @@ -269,7 +280,7 @@ class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { } } - private static boolean canHaveUnusedParameters(PyFunction func, Set functionsWithInheritors) { + private static boolean ignoreUnusedParameters(PyFunction func, Set functionsWithInheritors) { if (functionsWithInheritors.contains(func)) { return true; } @@ -297,8 +308,8 @@ class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { return false; } - private void registerWarning(final PsiElement element, final String msg) { - registerProblem(element, msg, ProblemHighlightType.LIKE_UNUSED_SYMBOL, null); + private void registerWarning(final PsiElement element, final String msg, LocalQuickFix... quickfixes) { + registerProblem(element, msg, ProblemHighlightType.LIKE_UNUSED_SYMBOL, null, quickfixes); } private static class ReplaceWithWildCard implements LocalQuickFix { diff --git a/python/testData/inspections/FieldFromUnusedParameter.py b/python/testData/inspections/FieldFromUnusedParameter.py new file mode 100644 index 000000000000..1e4620a7b413 --- /dev/null +++ b/python/testData/inspections/FieldFromUnusedParameter.py @@ -0,0 +1,3 @@ +class A: + def __init__(self, foo): + pass \ No newline at end of file diff --git a/python/testData/inspections/FieldFromUnusedParameter_after.py b/python/testData/inspections/FieldFromUnusedParameter_after.py new file mode 100644 index 000000000000..35c0b40ee3b1 --- /dev/null +++ b/python/testData/inspections/FieldFromUnusedParameter_after.py @@ -0,0 +1,3 @@ +class A: + def __init__(self, foo): + self.foo = foo \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java index ecdda72eed1b..0d2dd80ee405 100644 --- a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java +++ b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java @@ -144,6 +144,10 @@ public class PyQuickFixTest extends PyLightFixtureTestCase { doInspectionTest("AddClass.py", PyUnresolvedReferencesInspection.class, "Create class 'Xyzzy'", true, true); } + public void testFieldFromUnusedParameter() { // PY-1398 + doInspectionTest("FieldFromUnusedParameter.py", PyUnusedLocalInspection.class, "Add field 'foo' to class A", true, true); + } + @NonNls protected String getTestDataPath() { return PythonTestUtil.getTestDataPath() + "/inspections/";