mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-1209 Unused local variable inspection doesn't handle name conflicts correctly
This commit is contained in:
@@ -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);
|
||||
|
||||
+1
-1
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user