From 029b06f7495699381a26e468034ef52e23ba6edb Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Tue, 24 Jan 2012 21:11:38 +0400 Subject: [PATCH] Fixed resolve of target expression to previous targets --- .../psi/impl/references/PyReferenceImpl.java | 3 +-- .../python/refactoring/PyDefUseUtil.java | 8 +++++++- python/testData/resolve/PreviousTarget.py | 4 ++++ .../com/jetbrains/python/PyResolveTest.java | 16 ++++++++++++---- 4 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 python/testData/resolve/PreviousTarget.py diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java index ca526bb915f1..2435574b869b 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java @@ -194,8 +194,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference if (referencedName == null) return ret; if (myElement instanceof PyTargetExpression) { - final PsiElement parent = myElement.getParent(); - if (!(parent instanceof PyGlobalStatement || parent instanceof PyNonlocalStatement)) { + if (PsiTreeUtil.getParentOfType(myElement, PyComprehensionElement.class) != null) { ret.poke(myElement, getRate(myElement)); return ret; } diff --git a/python/src/com/jetbrains/python/refactoring/PyDefUseUtil.java b/python/src/com/jetbrains/python/refactoring/PyDefUseUtil.java index b871161bd0d2..75f656e5e686 100644 --- a/python/src/com/jetbrains/python/refactoring/PyDefUseUtil.java +++ b/python/src/com/jetbrains/python/refactoring/PyDefUseUtil.java @@ -31,10 +31,16 @@ public class PyDefUseUtil { if (augAssignment != null) { anchor = augAssignment; } - final int instr = ControlFlowUtil.findInstructionNumberByElement(instructions, anchor); + int instr = ControlFlowUtil.findInstructionNumberByElement(instructions, anchor); if (instr < 0) { return Collections.emptyList(); } + if (anchor instanceof PyTargetExpression) { + Collection pred = instructions[instr].allPred(); + if (!pred.isEmpty()) { + instr = pred.iterator().next().num(); + } + } final boolean[] visited = new boolean[instructions.length]; final Collection result = new LinkedHashSet(); getLatestDefs(varName, instructions, instr, acceptTypeAssertions, visited, result); diff --git a/python/testData/resolve/PreviousTarget.py b/python/testData/resolve/PreviousTarget.py new file mode 100644 index 000000000000..6d8b77f4b221 --- /dev/null +++ b/python/testData/resolve/PreviousTarget.py @@ -0,0 +1,4 @@ +def f(c, y): + localVariable = 10 + if c: + localVariable = y diff --git a/python/testSrc/com/jetbrains/python/PyResolveTest.java b/python/testSrc/com/jetbrains/python/PyResolveTest.java index 41f3f0299f2c..1d986cb42e2c 100644 --- a/python/testSrc/com/jetbrains/python/PyResolveTest.java +++ b/python/testSrc/com/jetbrains/python/PyResolveTest.java @@ -276,7 +276,7 @@ public class PyResolveTest extends PyResolveTestCase { PsiElement targetElement = resolve(); assertTrue(targetElement instanceof PyParameter); } - + public void testTextBasedResolve() { ResolveResult[] resolveResults = multiResolve(); assertEquals(1, resolveResults.length); @@ -422,19 +422,27 @@ public class PyResolveTest extends PyResolveTestCase { public void testDontResolveTargetToBuiltins() { // PY-4256 assertResolvesTo(PyTargetExpression.class, "str"); } - + public void testKeywordArgument() { assertResolvesTo(PyNamedParameter.class, "bar"); } - + public void testImplicitResolveInstanceAttribute() { ResolveResult[] resolveResults = multiResolve(); assertEquals(1, resolveResults.length); final PsiElement psiElement = resolveResults[0].getElement(); assertTrue(psiElement instanceof PyTargetExpression && "xyzzy".equals(((PyTargetExpression)psiElement).getName())); } - + public void testAttributeAssignedNearby() { assertResolvesTo(PyTargetExpression.class, "xyzzy"); } + + public void testPreviousTarget() { + PsiElement resolved = resolve(); + assertInstanceOf(resolved, PyTargetExpression.class); + PyTargetExpression target = (PyTargetExpression)resolved; + PyExpression value = target.findAssignedValue(); + assertInstanceOf(value, PyNumericLiteralExpression.class); + } }