From ebc316287b274436b8c7cf4a289fcf1ddf87dc1c Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Tue, 14 Feb 2017 19:14:34 +0300 Subject: [PATCH] Support more property decorators from third-party libraries --- .../python/psi/PyKnownDecoratorUtil.java | 18 ++++++++++++++++-- .../jetbrains/python/psi/impl/PyClassImpl.java | 4 +--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/PyKnownDecoratorUtil.java b/python/src/com/jetbrains/python/psi/PyKnownDecoratorUtil.java index 5dcfc3381df2..92039a77ec2b 100644 --- a/python/src/com/jetbrains/python/psi/PyKnownDecoratorUtil.java +++ b/python/src/com/jetbrains/python/psi/PyKnownDecoratorUtil.java @@ -76,7 +76,11 @@ public class PyKnownDecoratorUtil { TYPING_OVERLOAD("typing.overload"), - REPRLIB_RECURSIVE_REPR("reprlib.recursive_repr"); + REPRLIB_RECURSIVE_REPR("reprlib.recursive_repr"), + + PYRAMID_DECORATOR_REIFY("pyramid.decorator.reify"), + DJANGO_UTILS_FUNCTIONAL_CACHED_PROPERTY("django.utils.functional.cached_property"), + KOMBU_UTILS_CACHED_PROPERTY("kombu.utils.cached_property"); private final QualifiedName myQualifiedName; @@ -102,6 +106,12 @@ public class PyKnownDecoratorUtil { ABC_ABSTRACTSTATICMETHOD, ABC_ABSTRACTCLASSMETHOD); + private static final Set PROPERTY_DECORATORS = EnumSet.of(PROPERTY, + ABC_ABSTRACTPROPERTY, + PYRAMID_DECORATOR_REIFY, + DJANGO_UTILS_FUNCTIONAL_CACHED_PROPERTY, + KOMBU_UTILS_CACHED_PROPERTY); + private static final Map ourByShortName = newMapFromValues(Iterators.forArray(values()), new Convertor() { @Override @@ -111,7 +121,7 @@ public class PyKnownDecoratorUtil { }); /** - * Map decorators of element to {@link com.jetbrains.python.psi.PyKnownDecoratorUtil.KnownDecorator}. + * Map decorators of element to {@link PyKnownDecoratorUtil.KnownDecorator}. * * @param element decoratable element to check * @param context type evaluation context. If it doesn't allow switch to AST, decorators will be compared by the text of the last component @@ -220,6 +230,10 @@ public class PyKnownDecoratorUtil { return !knownDecorators.isEmpty(); } + public static boolean isPropertyDecorator(@NotNull PyDecorator decorator, @NotNull TypeEvalContext context) { + return PROPERTY_DECORATORS.contains(asKnownDecorator(decorator, context)); + } + private static boolean allDecoratorsAreKnown(@NotNull PyDecoratable element, @NotNull List decorators) { final PyDecoratorList decoratorList = element.getDecoratorList(); return decoratorList == null ? decorators.isEmpty() : decoratorList.getDecorators().length == decorators.size(); diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index 65b454ac57b5..1a93811238bd 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -765,9 +765,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla } } if (PyNames.PROPERTY.equals(decoName) || - ArrayUtil.contains(PyKnownDecoratorUtil.asKnownDecorator(deco, TypeEvalContext.codeInsightFallback(getProject())), - PyKnownDecoratorUtil.KnownDecorator.ABC_ABSTRACTPROPERTY, - PyKnownDecoratorUtil.KnownDecorator.PROPERTY)) { + PyKnownDecoratorUtil.isPropertyDecorator(deco, TypeEvalContext.codeInsightFallback(getProject()))) { getter = new Maybe<>(method); } else if (useAdvancedSyntax && qname.matches(decoratorName, PyNames.GETTER)) {