PY-1209 Unused local variable inspection doesn't handle name conflicts correctly

This commit is contained in:
Oleg Shpynov
2010-07-14 17:35:28 +04:00
parent bbf7041ad6
commit 85b85b200c
9 changed files with 73 additions and 21 deletions
@@ -560,4 +560,28 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor {
node.acceptChildren(evaluator);
InstructionBuilder.addAssertInstructions(myBuilder, evaluator);
}
@Override
public void visitPyLambdaExpression(final PyLambdaExpression node) {
myBuilder.startNode(node);
for (PyParameter parameter : node.getParameterList().getParameters()){
final PyExpression value = parameter.getDefaultValue();
if (value != null){
value.accept(this);
}
final PyNamedParameter namedParameter = parameter.getAsNamed();
if (namedParameter != null){
final PsiElement paramName = namedParameter.getFirstChild();
final ReadWriteInstruction instruction = ReadWriteInstruction.newInstruction(myBuilder, paramName,
parameter.getName(),
ReadWriteInstruction.ACCESS.WRITE);
myBuilder.addNode(instruction);
myBuilder.checkPending(instruction);
}
}
final PyExpression body = node.getBody();
if (body != null){
body.accept(this);
}
}
}
@@ -2,6 +2,7 @@ package com.jetbrains.python.codeInsight.controlflow;
import com.intellij.codeInsight.controlflow.ControlFlowBuilder;
import com.intellij.codeInsight.controlflow.impl.InstructionImpl;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.psi.PyElement;
import org.jetbrains.annotations.NonNls;
@@ -32,7 +33,7 @@ public class ReadWriteInstruction extends InstructionImpl {
private final ACCESS myAccess;
private ReadWriteInstruction(final ControlFlowBuilder builder,
final PyElement element,
final PsiElement element,
final String name,
final ACCESS access) {
super(builder, element);
@@ -73,7 +74,7 @@ public class ReadWriteInstruction extends InstructionImpl {
}
public static ReadWriteInstruction newInstruction(final ControlFlowBuilder builder,
final PyElement element,
final PsiElement element,
final String name,
final ACCESS access) {
return new ReadWriteInstruction(builder, element, name, access);
@@ -200,7 +200,7 @@ class PyUnusedLocalVariableInspectionVisitor extends PyInspectionVisitor {
// Register problems
for (PsiElement element : myUnusedElements) {
final String name = element.getText();
if (element instanceof PyNamedParameter) {
if (element instanceof PyNamedParameter || element.getParent() instanceof PyNamedParameter) {
// Ignore unused self parameters as obligatory
if ("self".equals(name) && PyPsiUtils.isMethodContext(element)) {
continue;
@@ -1,7 +1,11 @@
package com.jetbrains.python.psi;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
public interface PyLambdaExpression extends PyExpression, Callable {
@Nullable
public PyExpression getBody();
}
@@ -10,6 +10,7 @@ import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
@@ -33,11 +34,16 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp
}
public PyType getReturnType() {
PyExpression body = PsiTreeUtil.getChildOfType(this, PyExpression.class);
final PyExpression body = getBody();
if (body != null) return body.getType(TypeEvalContext.fast()); // or slow?
else return null;
}
@Nullable
public PyExpression getBody() {
return PsiTreeUtil.getChildOfType(this, PyExpression.class);
}
public PyFunction asMethod() {
return null; // we're never a method
}
@@ -18,20 +18,22 @@
17(18) WRITE ACCESS: methodList
18(19) element: PyAssignmentStatement
19(20) READ ACCESS: collapse
20(21) WRITE ACCESS: s
21(22) READ ACCESS: s
22(23) WRITE ACCESS: s
23(24) READ ACCESS: s
24(25) WRITE ACCESS: processFunc
25(26) element: PyPrintStatement
26(27) element: PyListCompExpression
27(28) READ ACCESS: methodList
28(29) WRITE ACCESS: method
29(30) READ ACCESS: method
30(31) READ ACCESS: spacing
31(32) READ ACCESS: processFunc
32(33) READ ACCESS: str
33(34) READ ACCESS: getattr
34(35) READ ACCESS: object
35(36) READ ACCESS: method
36() element: null
20(21) element: PyLambdaExpression
21(22) WRITE ACCESS: s
22(23) READ ACCESS: s
23(24) element: PyLambdaExpression
24(25) WRITE ACCESS: s
25(26) READ ACCESS: s
26(27) WRITE ACCESS: processFunc
27(28) element: PyPrintStatement
28(29) element: PyListCompExpression
29(30) READ ACCESS: methodList
30(31) WRITE ACCESS: method
31(32) READ ACCESS: method
32(33) READ ACCESS: spacing
33(34) READ ACCESS: processFunc
34(35) READ ACCESS: str
35(36) READ ACCESS: getattr
36(37) READ ACCESS: object
37(38) READ ACCESS: method
38() element: null
@@ -0,0 +1 @@
{(lambda i=i: i) for i in range(4)}
@@ -0,0 +1,10 @@
0(1) element: null
1(2) element: PyExpressionStatement
2(3) element: PySetCompExpression
3(4) READ ACCESS: range
4(5) WRITE ACCESS: i
5(6) element: PyLambdaExpression
6(7) READ ACCESS: i
7(8) WRITE ACCESS: i
8(9) READ ACCESS: i
9() element: null
@@ -135,6 +135,10 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase {
doTest();
}
public void testLambda() throws Exception {
doTest();
}
public void testSelf() throws Exception {
final String testName = getTestName(false).toLowerCase();
configureByFile(testName + ".py");