diff --git a/python/resources/inspectionDescriptions/PyRedeclarationInspection.html b/python/resources/inspectionDescriptions/PyRedeclarationInspection.html index 7ef9296a01d2..c5bc954e07c4 100644 --- a/python/resources/inspectionDescriptions/PyRedeclarationInspection.html +++ b/python/resources/inspectionDescriptions/PyRedeclarationInspection.html @@ -4,6 +4,6 @@ This inspection detects redeclarations of names without being used in between, l
def x(): pass
 x = 2
 
-It applies to function and class declarations, and assignments.
+It applies to function and class declarations, and top-level assignments.
diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index 6d9d5854c1c0..34cefc751528 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -280,7 +280,7 @@ INSP.decorator.receives.unexpected.builtin=This decorator will not receive a cal # PyRedeclarationInspection INSP.NAME.redeclaration=Names redeclared without usage -INSP.shadows.same.named.$0.above=Shadows a {0} with the same name defined above +INSP.redeclared.name=Redeclared name defined above without usage # PyUnresolvedReferencesInspection INSP.NAME.unresolved.refs=Unresolved references diff --git a/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java b/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java index 77df179260a8..2388a5c1d213 100644 --- a/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyRedeclarationInspection.java @@ -7,6 +7,7 @@ import com.intellij.codeInspection.ProblemsHolder; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiNameIdentifierOwner; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Function; import com.jetbrains.python.PyBundle; import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache; @@ -33,7 +34,6 @@ public class PyRedeclarationInspection extends PyInspection { return PyBundle.message("INSP.NAME.redeclaration"); } - @NotNull @Override public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, @@ -69,6 +69,11 @@ public class PyRedeclarationInspection extends PyInspection { } } + private static boolean isConditional(@NotNull PsiElement node) { + return PsiTreeUtil.getParentOfType(node, PyIfStatement.class, PyConditionalExpression.class, PyLoopStatement.class, + PyComprehensionElement.class, PyTryExceptStatement.class) != null; + } + private static boolean isDecorated(@NotNull PyDecoratable node) { boolean isDecorated = false; final PyDecoratorList decoratorList = node.getDecoratorList(); @@ -82,6 +87,9 @@ public class PyRedeclarationInspection extends PyInspection { } private void processElement(@NotNull final PsiNameIdentifierOwner element) { + if (isConditional(element)) { + return; + } final String name = element.getName(); final ScopeOwner owner = ScopeUtil.getScopeOwner(element); if (owner != null && name != null) { @@ -94,10 +102,9 @@ public class PyRedeclarationInspection extends PyInspection { final ReadWriteInstruction rwInstruction = (ReadWriteInstruction)instruction; if (name.equals(rwInstruction.getName())) { if (rwInstruction.getAccess().isWriteAccess()) { - final PsiElement shadowed = rwInstruction.getElement(); final PsiElement identifier = element.getNameIdentifier(); registerProblem(identifier != null ? identifier : element, - PyBundle.message("INSP.shadows.same.named.$0.above", getKind(shadowed))); + PyBundle.message("INSP.redeclared.name")); } return ControlFlowUtil.Operation.BREAK; } @@ -108,17 +115,4 @@ public class PyRedeclarationInspection extends PyInspection { } } } - - @NotNull - private static String getKind(@Nullable PsiElement element) { - if (element instanceof PyFunction) { - return PyBundle.message("GNAME.function"); - } - else if (element instanceof PyClass) { - return PyBundle.message("GNAME.class"); - } - else { - return PyBundle.message("GNAME.var"); - } - } } diff --git a/python/testData/inspections/PyRedeclarationInspection/test.py b/python/testData/inspections/PyRedeclarationInspection/test.py index 89ad3cc34274..f2adbfb09da4 100644 --- a/python/testData/inspections/PyRedeclarationInspection/test.py +++ b/python/testData/inspections/PyRedeclarationInspection/test.py @@ -2,14 +2,14 @@ def test_class(): class X: pass - class X: + class X: pass def test_function(): def foo(): pass - def foo(): + def foo(): pass @@ -18,11 +18,11 @@ def TopLevelBoo(): pass -TopLevelBoo = 1 -TopLevelBoo = 2 +TopLevelBoo = 1 +TopLevelBoo = 2 -class TopLevelBoo: +class TopLevelBoo: pass @@ -34,10 +34,29 @@ def test_decorated_function(decorator): def foo(): pass - def foo(): + def foo(): pass def test_local_variable(): x = 1 x = 2 + + +def conditional(c): + def foo(): + pass + + if c: + def foo(): + pass + + while c: + def foo(): + pass + + try: + def foo(): + pass + except: + pass