fixed PY-13965 Global declarations in nested functions are marked as undefined at module level

This commit is contained in:
Ekaterina Tuzova
2014-11-24 18:57:32 +03:00
parent 1355b9513e
commit 28c885a572
5 changed files with 26 additions and 9 deletions

View File

@@ -46,7 +46,7 @@ public interface Scope {
List<PyImportedNameDefiner> getImportedNameDefiners();
@Nullable
PsiNamedElement getNamedElement(String name);
PsiNamedElement getNamedElement(String name, boolean includeNestedGlobals);
@NotNull
Collection<PsiNamedElement> getNamedElements();

View File

@@ -118,7 +118,7 @@ public class ScopeImpl implements Scope {
if (isNonlocal(name)) {
return false;
}
if (getNamedElement(name) != null) {
if (getNamedElement(name, true) != null) {
return true;
}
if (isAugAssignment(name)) {
@@ -143,7 +143,7 @@ public class ScopeImpl implements Scope {
@Nullable
@Override
public PsiNamedElement getNamedElement(String name) {
public PsiNamedElement getNamedElement(String name, boolean includeNestedGlobals) {
if (myNamedElements == null) {
collectDeclarations();
}
@@ -151,9 +151,9 @@ public class ScopeImpl implements Scope {
if (element != null) {
return element;
}
if (isGlobal(name)) {
if (includeNestedGlobals && isGlobal(name)) {
for (Scope scope : myNestedScopes) {
final PsiNamedElement global = scope.getNamedElement(name);
final PsiNamedElement global = scope.getNamedElement(name, true);
if (global != null) {
return global;
}

View File

@@ -133,7 +133,8 @@ public class PyResolveUtil {
final Scope scope = ControlFlowCache.getScope(scopeOwner);
boolean found = false;
if (name != null) {
final PsiElement resolved = scope.getNamedElement(name);
final boolean includeNestedGlobals = scopeOwner instanceof PyFile;
final PsiElement resolved = scope.getNamedElement(name, includeNestedGlobals);
if (resolved != null) {
if (!processor.execute(resolved, ResolveState.initial())) {
found = true;

View File

@@ -0,0 +1,10 @@
foo = 0
def outer():
def inner():
global fo<ref>o
print(foo)
inner()
outer()

View File

@@ -160,13 +160,19 @@ public class PyResolveTest extends PyResolveTestCase {
public void testTryExceptElse() {
PsiElement targetElement = resolve();
Assert.assertTrue(targetElement instanceof PyTargetExpression);
assertTrue(targetElement instanceof PyTargetExpression);
}
public void testGlobal() {
PsiElement targetElement = resolve();
Assert.assertTrue(targetElement instanceof PyTargetExpression);
Assert.assertTrue(targetElement.getParent() instanceof PyAssignmentStatement);
assertTrue(targetElement instanceof PyTargetExpression);
assertTrue(targetElement.getParent() instanceof PyAssignmentStatement);
}
public void testGlobalInNestedFunction() {
PsiElement targetElement = resolve();
assertInstanceOf(targetElement, PyTargetExpression.class);
assertInstanceOf(ScopeUtil.getScopeOwner(targetElement), PyFile.class);
}
public void testGlobalDefinedLocally() {