From 3c84d4bc13b8ea535b3579570211d0472a23e7fe Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Fri, 3 Aug 2012 19:32:22 +0400 Subject: [PATCH] Don't mark parameters of empty methods with no body as unused (PY-7028) --- .../PyUnusedLocalInspectionVisitor.java | 51 +++++++++++++++++-- .../inspections/FieldFromUnusedParameter.py | 2 +- .../FieldFromUnusedParameterKeyword.py | 2 +- .../FieldFromUnusedParameterKeyword_after.py | 1 + .../FieldFromUnusedParameter_after.py | 1 + .../PyUnusedLocalVariableInspection/test.py | 30 +++++++++-- 6 files changed, 77 insertions(+), 10 deletions(-) diff --git a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java index e9635044b672..1697bf7c3a9d 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java +++ b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java @@ -29,9 +29,7 @@ import com.jetbrains.python.psi.search.PyOverridingMethodsSearch; import com.jetbrains.python.psi.search.PySuperMethodsSearch; import org.jetbrains.annotations.NotNull; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; +import java.util.*; /** * @author oleg @@ -215,7 +213,8 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { final UnusedLocalFilter[] filters = Extensions.getExtensions(UnusedLocalFilter.EP_NAME); // Register problems - Set functionsWithInheritors = new HashSet(); + final Set functionsWithInheritors = new HashSet(); + final Map emptyFunctions = new HashMap(); for (PsiElement element : myUnusedElements) { boolean ignoreUnused = false; @@ -275,6 +274,14 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { else if (ignoreUnusedParameters(func, functionsWithInheritors)) { continue; } + Boolean isEmpty = emptyFunctions.get(func); + if (isEmpty == null) { + isEmpty = isEmptyFunction(func); + emptyFunctions.put(func, isEmpty); + } + if (isEmpty) { + continue; + } } final LocalQuickFix[] fixes = mayBeField ? new LocalQuickFix[] { new AddFieldQuickFix(name, containingClass, name) } @@ -393,4 +400,40 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor { return getName(); } } + + private static boolean isEmptyFunction(@NotNull PyFunction f) { + final PyStatementList statementList = f.getStatementList(); + if (statementList == null) { + return true; + } + final PyStatement[] statements = statementList.getStatements(); + if (statements.length == 0) { + return true; + } + else if (statements.length == 1) { + if (isStringLiteral(statements[0]) || isPassOrRaise(statements[0])) { + return true; + } + } + else if (statements.length == 2) { + if (isStringLiteral(statements[0]) && (isPassOrRaise(statements[1]))) { + return true; + } + } + return false; + } + + private static boolean isPassOrRaise(PyStatement stmt) { + return stmt instanceof PyPassStatement || stmt instanceof PyRaiseStatement; + } + + private static boolean isStringLiteral(PyStatement stmt) { + if (stmt instanceof PyExpressionStatement) { + final PyExpression expr = ((PyExpressionStatement)stmt).getExpression(); + if (expr instanceof PyStringLiteralExpression) { + return true; + } + } + return false; + } } diff --git a/python/testData/inspections/FieldFromUnusedParameter.py b/python/testData/inspections/FieldFromUnusedParameter.py index db267a13b140..a9b802bb0136 100644 --- a/python/testData/inspections/FieldFromUnusedParameter.py +++ b/python/testData/inspections/FieldFromUnusedParameter.py @@ -1,3 +1,3 @@ class A: def __init__(self, foo): - pass \ No newline at end of file + print('hello') \ No newline at end of file diff --git a/python/testData/inspections/FieldFromUnusedParameterKeyword.py b/python/testData/inspections/FieldFromUnusedParameterKeyword.py index 286ab96cac8b..35851f0f87df 100644 --- a/python/testData/inspections/FieldFromUnusedParameterKeyword.py +++ b/python/testData/inspections/FieldFromUnusedParameterKeyword.py @@ -1,3 +1,3 @@ class A: def __init__(self, foo=True): - pass \ No newline at end of file + print('hello') \ No newline at end of file diff --git a/python/testData/inspections/FieldFromUnusedParameterKeyword_after.py b/python/testData/inspections/FieldFromUnusedParameterKeyword_after.py index 5aa1fe2c1c56..7e0d6627cc00 100644 --- a/python/testData/inspections/FieldFromUnusedParameterKeyword_after.py +++ b/python/testData/inspections/FieldFromUnusedParameterKeyword_after.py @@ -1,3 +1,4 @@ class A: def __init__(self, foo=True): + print('hello') self.foo = foo \ No newline at end of file diff --git a/python/testData/inspections/FieldFromUnusedParameter_after.py b/python/testData/inspections/FieldFromUnusedParameter_after.py index 35c0b40ee3b1..7405ba3ec789 100644 --- a/python/testData/inspections/FieldFromUnusedParameter_after.py +++ b/python/testData/inspections/FieldFromUnusedParameter_after.py @@ -1,3 +1,4 @@ class A: def __init__(self, foo): + print('hello') self.foo = foo \ No newline at end of file diff --git a/python/testData/inspections/PyUnusedLocalVariableInspection/test.py b/python/testData/inspections/PyUnusedLocalVariableInspection/test.py index 37d2f9b7705b..00377593463e 100644 --- a/python/testData/inspections/PyUnusedLocalVariableInspection/test.py +++ b/python/testData/inspections/PyUnusedLocalVariableInspection/test.py @@ -112,7 +112,7 @@ def test(): print v def foo(a = 123): # fail Do not use getText() as parameter name - pass + print('hello') def loopie(): for x in range(5): pass @@ -123,9 +123,9 @@ def locals_inside(): do_smth_with(locals()) class Stat(object): - @staticmethod - def woof(dog="bark"): # fail - pass + @staticmethod + def woof(dog="bark"): # fail + print('hello') class A: def __init__(self, *args): #pass @@ -261,3 +261,25 @@ def test_only_name_in_local_class(): class C: pass return x + + +# PY-7028 +def test_unused_params_in_empty_function_1(x, y, z): + pass + + +# PY-7028 +def test_unused_params_in_empty_function_2(x, y, z): + raise Exception() + + +# PY-7028 +def test_unused_params_in_empty_function_3(x, y, z): + """Docstring.""" + + +# PY-7028 +def test_unused_params_in_empty_function_4(x, y, z): + """Docstring.""" + raise Exception() +