diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java index 164e2ba57101..850b03f6f97a 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java @@ -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); + } + } } \ No newline at end of file diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/ReadWriteInstruction.java b/python/src/com/jetbrains/python/codeInsight/controlflow/ReadWriteInstruction.java index d21629d44525..153013ad1ace 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/ReadWriteInstruction.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/ReadWriteInstruction.java @@ -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); diff --git a/python/src/com/jetbrains/python/inspections/PyUnusedLocalVariableInspectionVisitor.java b/python/src/com/jetbrains/python/inspections/PyUnusedLocalVariableInspectionVisitor.java index ff9986d73581..efefea2908e6 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnusedLocalVariableInspectionVisitor.java +++ b/python/src/com/jetbrains/python/inspections/PyUnusedLocalVariableInspectionVisitor.java @@ -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; diff --git a/python/src/com/jetbrains/python/psi/PyLambdaExpression.java b/python/src/com/jetbrains/python/psi/PyLambdaExpression.java index 08253138f858..bb6e9869503c 100644 --- a/python/src/com/jetbrains/python/psi/PyLambdaExpression.java +++ b/python/src/com/jetbrains/python/psi/PyLambdaExpression.java @@ -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(); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java index 2e998893e9a9..19ffa4a036e0 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java @@ -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 } diff --git a/python/testData/codeInsight/controlflow/function.txt b/python/testData/codeInsight/controlflow/function.txt index 174f4129d879..a7171a58cb30 100644 --- a/python/testData/codeInsight/controlflow/function.txt +++ b/python/testData/codeInsight/controlflow/function.txt @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/python/testData/codeInsight/controlflow/lambda.py b/python/testData/codeInsight/controlflow/lambda.py new file mode 100644 index 000000000000..8ce1b757f7e0 --- /dev/null +++ b/python/testData/codeInsight/controlflow/lambda.py @@ -0,0 +1 @@ +{(lambda i=i: i) for i in range(4)} diff --git a/python/testData/codeInsight/controlflow/lambda.txt b/python/testData/codeInsight/controlflow/lambda.txt new file mode 100644 index 000000000000..26bc5414d098 --- /dev/null +++ b/python/testData/codeInsight/controlflow/lambda.txt @@ -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 \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java index 993dddc21940..01a3960a7096 100644 --- a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java +++ b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java @@ -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");