From 8b5046442092fc76140ffc64b5809566ffaee183 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 22 Aug 2011 17:54:28 +0400 Subject: [PATCH] Fixed find usages for reassigned class and instance attributes (PY-4338). --- .../psi/impl/PyQualifiedReferenceImpl.java | 14 +++++++++----- .../findUsages/ReassignedClassAttribute.py | 17 +++++++++++++++++ .../findUsages/ReassignedInstanceAttribute.py | 18 ++++++++++++++++++ .../com/jetbrains/python/PyFindUsagesTest.java | 12 +++++++++++- 4 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 python/testData/findUsages/ReassignedClassAttribute.py create mode 100644 python/testData/findUsages/ReassignedInstanceAttribute.py diff --git a/python/src/com/jetbrains/python/psi/impl/PyQualifiedReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/PyQualifiedReferenceImpl.java index 4471299f1b6d..647e3191ec09 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyQualifiedReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyQualifiedReferenceImpl.java @@ -348,8 +348,8 @@ public class PyQualifiedReferenceImpl extends PyReferenceImpl { } } } - if (resolveResult instanceof PyTargetExpression && PyUtil.isInstanceAttribute((PyTargetExpression)resolveResult) && - element instanceof PyTargetExpression && PyUtil.isInstanceAttribute((PyTargetExpression)element)) { + if (resolveResult instanceof PyTargetExpression && isInstanceOrClassAttribute((PyTargetExpression)resolveResult) && + element instanceof PyTargetExpression && isInstanceOrClassAttribute((PyTargetExpression)element)) { PyClass aClass = PsiTreeUtil.getParentOfType(resolveResult, PyClass.class); PyClass bClass = PsiTreeUtil.getParentOfType(element, PyClass.class); @@ -362,11 +362,15 @@ public class PyQualifiedReferenceImpl extends PyReferenceImpl { return false; } - private boolean isSubclass(@Nullable PyClass init, @Nullable PyClass usage) { - if (init == null || usage == null) { + private static boolean isInstanceOrClassAttribute(PyTargetExpression ex) { + return PyUtil.isInstanceAttribute(ex) || PyUtil.isClassAttribute(ex); + } + + private static boolean isSubclass(@Nullable PyClass aClass, @Nullable PyClass bClass) { + if (aClass == null || bClass == null) { return false; } - return usage.isSubclass(init); + return bClass.isSubclass(aClass); } private static boolean isLocalScope(PsiElement element) { diff --git a/python/testData/findUsages/ReassignedClassAttribute.py b/python/testData/findUsages/ReassignedClassAttribute.py new file mode 100644 index 000000000000..8bf86558d4d2 --- /dev/null +++ b/python/testData/findUsages/ReassignedClassAttribute.py @@ -0,0 +1,17 @@ +class A(object): + bacaba = 0 + def __init__(self): + self.bacaba = 1 + + def foo(self, x): + self.bacaba = x + + +class B(A): + bacaba = 2 + def __init__(self): + super(B, self).__init__() + self.bacaba = 3 + + def foo2(self): + print self.bacaba \ No newline at end of file diff --git a/python/testData/findUsages/ReassignedInstanceAttribute.py b/python/testData/findUsages/ReassignedInstanceAttribute.py new file mode 100644 index 000000000000..717e0a6cb4ef --- /dev/null +++ b/python/testData/findUsages/ReassignedInstanceAttribute.py @@ -0,0 +1,18 @@ +class A(object): + def __init__(self): + self.bacaba = 1 + + def foo(self, x): + self.bacaba = x + +class B(A): + def __init__(self): + super(B, self).__init__() + self.bacaba = 2 + + def foo2(self): + self.bacaba = 3 + + def foo3(self): + print self.bacaba + \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyFindUsagesTest.java b/python/testSrc/com/jetbrains/python/PyFindUsagesTest.java index e455303ca21d..911ae33f6017 100644 --- a/python/testSrc/com/jetbrains/python/PyFindUsagesTest.java +++ b/python/testSrc/com/jetbrains/python/PyFindUsagesTest.java @@ -83,7 +83,7 @@ public class PyFindUsagesTest extends PyLightFixtureTestCase { } }); for (int i = 0; i < usageTexts.length; i++) { - assertSameUsage(usageTexts [i], sortedUsages.get(i)); + assertSameUsage(usageTexts[i], sortedUsages.get(i)); } } @@ -94,4 +94,14 @@ public class PyFindUsagesTest extends PyLightFixtureTestCase { final int startIndex = usageInfo.getElement().getTextOffset() + usageInfo.getRangeInElement().getStartOffset() - pos; assertEquals(usageText, myFixture.getFile().getText().substring(startIndex, startIndex + usageText.length())); } + + public void testReassignedInstanceAttribute() { // PY-4338 + final Collection usages = myFixture.testFindUsages("findUsages/ReassignedInstanceAttribute.py"); + assertEquals(5, usages.size()); + } + + public void testReassignedClassAttribute() { // PY-4338 + final Collection usages = myFixture.testFindUsages("findUsages/ReassignedClassAttribute.py"); + assertEquals(5, usages.size()); + } }