Don't warn about conditionally redeclared items

This commit is contained in:
Andrey Vlasovskikh
2013-09-03 18:42:57 +04:00
parent 03d185ca1b
commit aa714041e1
4 changed files with 37 additions and 24 deletions
@@ -4,6 +4,6 @@ This inspection detects redeclarations of names without being used in between, l
<pre>def x(): pass
x = 2
</pre>
It applies to function and class declarations, and assignments.<br/>
It applies to function and class declarations, and top-level assignments.<br/>
</span></body>
</html>
@@ -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
@@ -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");
}
}
}
@@ -2,14 +2,14 @@ def test_class():
class X:
pass
class <warning descr="Shadows a class with the same name defined above">X</warning>:
class <warning descr="Redeclared name defined above without usage">X</warning>:
pass
def test_function():
def foo():
pass
def <warning descr="Shadows a function with the same name defined above">foo</warning>():
def <warning descr="Redeclared name defined above without usage">foo</warning>():
pass
@@ -18,11 +18,11 @@ def TopLevelBoo():
pass
<warning descr="Shadows a function with the same name defined above">TopLevelBoo</warning> = 1
<warning descr="Shadows a variable with the same name defined above">TopLevelBoo</warning> = 2
<warning descr="Redeclared name defined above without usage">TopLevelBoo</warning> = 1
<warning descr="Redeclared name defined above without usage">TopLevelBoo</warning> = 2
class <warning descr="Shadows a variable with the same name defined above">TopLevelBoo</warning>:
class <warning descr="Redeclared name defined above without usage">TopLevelBoo</warning>:
pass
@@ -34,10 +34,29 @@ def test_decorated_function(decorator):
def foo():
pass
def <warning descr="Shadows a function with the same name defined above">foo</warning>():
def <warning descr="Redeclared name defined above without usage">foo</warning>():
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