From 9eff8e77f476a9e4b667d831a5ff4902362723b1 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Thu, 26 Apr 2012 14:51:56 +0400 Subject: [PATCH] Fixed unresolved reference in local variable of lambda inside default parameter value (PY-6435) --- .../codeInsight/dataflow/scope/ScopeUtil.java | 23 ++++++++++--------- .../resolve/LambdaParameterInDefaultValue.py | 2 ++ .../com/jetbrains/python/PyResolveTest.java | 5 ++++ 3 files changed, 19 insertions(+), 11 deletions(-) create mode 100644 python/testData/resolve/LambdaParameterInDefaultValue.py diff --git a/python/src/com/jetbrains/python/codeInsight/dataflow/scope/ScopeUtil.java b/python/src/com/jetbrains/python/codeInsight/dataflow/scope/ScopeUtil.java index 11b36602f708..4bd865e1ea90 100644 --- a/python/src/com/jetbrains/python/codeInsight/dataflow/scope/ScopeUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/dataflow/scope/ScopeUtil.java @@ -56,20 +56,21 @@ public class ScopeUtil { } @Nullable - public static ScopeOwner getResolveScopeOwner(PsiElement element) { - // References in default values of parameters are defined somewhere in outer scopes, as well as references in decorators (if they are - // not inside a lambda, see PY-6083) and superclasses - final ScopeOwner initialScopeOwner = getScopeOwner(element); - if (!(initialScopeOwner instanceof PyLambdaExpression && PsiTreeUtil.getParentOfType(element, PyDecorator.class) != null) && - PsiTreeUtil.getParentOfType(element, PyParameter.class, PyDecorator.class) != null) { - element = initialScopeOwner; + public static ScopeOwner getResolveScopeOwner(@NotNull PsiElement element) { + final ScopeOwner firstOwner = getScopeOwner(element); + if (firstOwner == null) { + return null; + } + final ScopeOwner nextOwner = getScopeOwner(firstOwner); + final PyElement decoratorOrParameterAncestor = PsiTreeUtil.getParentOfType(element, PyDecorator.class, PyParameter.class); + if (decoratorOrParameterAncestor != null && !PsiTreeUtil.isAncestor(decoratorOrParameterAncestor, firstOwner, true)) { + return nextOwner; } final PyClass containingClass = PsiTreeUtil.getParentOfType(element, PyClass.class); - if (containingClass != null && element != null && - PsiTreeUtil.isAncestor(containingClass.getSuperClassExpressionList(), element, false)) { - element = containingClass; + if (containingClass != null && PsiTreeUtil.isAncestor(containingClass.getSuperClassExpressionList(), element, false)) { + return nextOwner; } - return PsiTreeUtil.getParentOfType(element, ScopeOwner.class); + return firstOwner; } @Nullable diff --git a/python/testData/resolve/LambdaParameterInDefaultValue.py b/python/testData/resolve/LambdaParameterInDefaultValue.py new file mode 100644 index 000000000000..1e0c6c0191cf --- /dev/null +++ b/python/testData/resolve/LambdaParameterInDefaultValue.py @@ -0,0 +1,2 @@ +def f(g=lambda xx: xx): + pass # \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyResolveTest.java b/python/testSrc/com/jetbrains/python/PyResolveTest.java index 0331ccfeb0ac..d0fde0cc6b62 100644 --- a/python/testSrc/com/jetbrains/python/PyResolveTest.java +++ b/python/testSrc/com/jetbrains/python/PyResolveTest.java @@ -462,4 +462,9 @@ public class PyResolveTest extends PyResolveTestCase { public void testLambdaParameterInDecorator() { assertResolvesTo(PyNamedParameter.class, "xx"); } + + // PY-6435 + public void testLambdaParameterInDefaultValue() { + assertResolvesTo(PyNamedParameter.class, "xx"); + } }