don't resolve target expressions outside of their defining function (PY-1179)

This commit is contained in:
Dmitry Jemerov
2010-06-30 22:02:19 +04:00
parent a76a852258
commit 77e4a1561b
3 changed files with 35 additions and 13 deletions
@@ -166,17 +166,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
// Use real context here to enable correct completion and resolve in case of PyExpressionCodeFragment!!!
final PsiElement realContext = PyPsiUtils.getRealContext(myElement);
PsiElement roof = null;
if (PyUtil.isClassPrivateName(referencedName)) {
// a class-private name; limited by either class or this file
PsiElement one = myElement;
do {
one = PyUtil.getConcealingParent(one);
}
while (one instanceof PyFunction);
if (one instanceof PyClass) roof = one;
}
if (roof == null) roof = realContext.getContainingFile();
PsiElement roof = findResolveRoof(referencedName, realContext);
PsiElement uexpr = PyResolveUtil.treeCrawlUp(processor, false, realContext, roof);
if ((uexpr != null)) {
if ((uexpr instanceof PyClass)) {
@@ -216,9 +206,10 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
uexpr = bfile.getElementNamed(referencedName);
}
}
if (uexpr == null) {
if (uexpr == null && !(myElement instanceof PyTargetExpression)) {
//uexpr = PyResolveUtil.resolveOffContext(this);
uexpr = PyUtil.turnDirIntoInit(PyResolveUtil.scanOuterContext(new ResolveProcessor(referencedName), realContext));
final PsiElement outerContextElement = PyResolveUtil.scanOuterContext(new ResolveProcessor(referencedName), realContext);
uexpr = PyUtil.turnDirIntoInit(outerContextElement);
}
if (uexpr != null) {
ret.add(new ImportedResolveResult(uexpr, getRate(uexpr), processor.getDefiners()));
@@ -227,6 +218,28 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
return ret;
}
private PsiElement findResolveRoof(String referencedName, PsiElement realContext) {
if (PyUtil.isClassPrivateName(referencedName)) {
// a class-private name; limited by either class or this file
PsiElement one = myElement;
do {
one = PyUtil.getConcealingParent(one);
}
while (one instanceof PyFunction);
if (one instanceof PyClass) {
return one;
}
}
if (myElement instanceof PyTargetExpression) {
final ScopeOwner scopeOwner = PsiTreeUtil.getParentOfType(myElement, ScopeOwner.class);
if (scopeOwner != null && !scopeOwner.getScope().isGlobal(myElement.getName())) {
return scopeOwner;
}
}
return realContext.getContainingFile();
}
private boolean isSuperClassExpression(PyClass cls) {
if (myElement.getContainingFile() != cls.getContainingFile()) { // quick check to avoid unnecessary tree loading
return false;
@@ -0,0 +1,4 @@
<caret>a = 0
def b():
a = 1
print a
@@ -43,4 +43,9 @@ public class PyFindUsagesTest extends PyLightFixtureTestCase {
final Collection<UsageInfo> usages = myFixture.testFindUsages("findUsages/GlobalUsages2.py");
assertEquals(3, usages.size());
}
public void testNonGlobalUsages() { // PY-1179
final Collection<UsageInfo> usages = myFixture.testFindUsages("findUsages/NonGlobalUsages.py");
assertEquals(1, usages.size());
}
}