From de7f22cfbf854fe06d0c87c9a10a9012e981a07e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 5 Mar 2012 19:48:54 +0100 Subject: [PATCH] getter/setter/deleter icons in structure view also for classic style properties (PY-5949) --- python/src/com/jetbrains/python/psi/PyClass.java | 9 +++++++++ .../jetbrains/python/psi/impl/PyClassImpl.java | 15 +++++++++++++++ .../jetbrains/python/psi/impl/PyFunctionImpl.java | 6 ++---- python/testData/property/Classic.py | 7 +++++++ .../jetbrains/python/PyClassicPropertyTest.java | 8 ++++++++ 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/PyClass.java b/python/src/com/jetbrains/python/psi/PyClass.java index 8ac1d83ce590..d501b1b8e4cc 100644 --- a/python/src/com/jetbrains/python/psi/PyClass.java +++ b/python/src/com/jetbrains/python/psi/PyClass.java @@ -130,6 +130,15 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine @Nullable Property scanProperties(Processor processor, boolean inherited); + /** + * Non-recursively searches for a property for which the given function is a getter, setter or deleter. + * + * @param function the function which may be an accessor + * @return the property, or null + */ + @Nullable + Property findPropertyByFunction(PyFunction function); + /** * @param parent * @return True iff this and parent are the same or parent is one of our superclasses. diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index 72e3efd5c071..a6cebe6ddd52 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -633,6 +633,21 @@ public class PyClassImpl extends PyPresentableElementImpl implement return null; } + @Override + public Property findPropertyByFunction(PyFunction function) { + if (myPropertyCache == null) { + myPropertyCache = initializePropertyCache(); + } + for (Property property : myPropertyCache.values()) { + if (property.getGetter().value() == function || + property.getSetter().value() == function || + property.getDeleter().value() == function) { + return property; + } + } + return null; + } + private Property findLocalProperty(String name) { if (myPropertyCache == null) { myPropertyCache = initializePropertyCache(); diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index 1df4e3ad3e83..9d1510712e0e 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -450,10 +450,8 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp public Property getProperty() { final PyClass containingClass = getContainingClass(); - final String name = getName(); - if (containingClass != null && name != null) { - // TODO find property which uses property call, rather than annotation (function name will be different in that case) - return containingClass.findProperty(name); + if (containingClass != null) { + return containingClass.findPropertyByFunction(this); } return null; } diff --git a/python/testData/property/Classic.py b/python/testData/property/Classic.py index 26c15ae2da42..c7293b63d2e4 100644 --- a/python/testData/property/Classic.py +++ b/python/testData/property/Classic.py @@ -11,7 +11,14 @@ class A(object): def deleter(self): pass + def v5getter(self): + return self._v + + def v5setter(self, v): + self._v = v + v1 = property(getter, setter) v2 = property(fset=setter, fdel=deleter, fget=getter, doc="doc of v2") v3 = property(lambda self: self._v, None, (deleter)) v4 = otherworldly # NOTE: not supported yet + v5 = property(v5getter, v5setter) diff --git a/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java b/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java index 65347b0531a5..332c586e594b 100644 --- a/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java +++ b/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java @@ -108,4 +108,12 @@ public class PyClassicPropertyTest extends PyTestCase { } */ + public void testGetProperty() { + final PyFunction getter = myClass.findMethodByName("v5getter", false); + assertNotNull(getter.getProperty()); + + final PyFunction setter = myClass.findMethodByName("v5setter", false); + assertNotNull(setter.getProperty()); + } + }