mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
correct isReferenceTo() for variables used in nested functions (part of PY-3118)
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package com.jetbrains.python.codeInsight.controlflow;
|
||||
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.Scope;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
|
||||
/**
|
||||
|
||||
@@ -314,8 +314,27 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
|
||||
if (element instanceof PyParameter || element instanceof PyTargetExpression) {
|
||||
PsiElement ourContainer = PsiTreeUtil.getParentOfType(getElement(), PsiNamedElement.class, PyLambdaExpression.class, PyComprehensionElement.class);
|
||||
PsiElement theirContainer = PsiTreeUtil.getParentOfType(element, PsiNamedElement.class, PyLambdaExpression.class, PyComprehensionElement.class);
|
||||
if (ourContainer != null && ourContainer == theirContainer) {
|
||||
return true;
|
||||
if (ourContainer != null) {
|
||||
if (ourContainer == theirContainer) {
|
||||
return true;
|
||||
}
|
||||
if (PsiTreeUtil.isAncestor(theirContainer, ourContainer, true)) {
|
||||
ScopeOwner ourScopeOwner = PsiTreeUtil.getParentOfType(getElement(), ScopeOwner.class);
|
||||
ScopeOwner theirScopeOwner = PsiTreeUtil.getParentOfType(element, ScopeOwner.class);
|
||||
if (ourScopeOwner != theirScopeOwner) {
|
||||
boolean shadowsName = false;
|
||||
while(ourScopeOwner != theirScopeOwner && ourScopeOwner != null) {
|
||||
if (ControlFlowCache.getScope(ourScopeOwner).containsDeclaration(elementName)) {
|
||||
shadowsName = true;
|
||||
break;
|
||||
}
|
||||
ourScopeOwner = PsiTreeUtil.getParentOfType(ourScopeOwner, ScopeOwner.class);
|
||||
}
|
||||
if (!shadowsName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiElement resolveResult = resolve();
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
xyzzy = False
|
||||
|
||||
def foo():
|
||||
if xyzzy:
|
||||
b<caret>ar = {}
|
||||
else:
|
||||
bar = []
|
||||
def x():
|
||||
for y in enumerate(bar):
|
||||
pass
|
||||
@@ -64,6 +64,15 @@ public class PyFindUsagesTest extends PyLightFixtureTestCase {
|
||||
assertUsages(usages, "import <caret>re", "<caret>re.compile");
|
||||
}
|
||||
|
||||
public void testNestedFunctions() { // PY-3118
|
||||
final Collection<UsageInfo> usages = doTest();
|
||||
assertUsages(usages, "<caret>bar = {}", "<caret>bar = []", "enumerate(<caret>bar)");
|
||||
}
|
||||
|
||||
private Collection<UsageInfo> doTest() {
|
||||
return myFixture.testFindUsages("findUsages/" + getTestName(false) + ".py");
|
||||
}
|
||||
|
||||
private void assertUsages(Collection<UsageInfo> usages, String... usageTexts) {
|
||||
assertEquals(usageTexts.length, usages.size());
|
||||
List<UsageInfo> sortedUsages = new ArrayList<UsageInfo>(usages);
|
||||
|
||||
Reference in New Issue
Block a user