Support more property decorators from third-party libraries

This commit is contained in:
Semyon Proshev
2017-02-14 19:19:48 +03:00
parent c55d28bc8b
commit ebc316287b
2 changed files with 17 additions and 5 deletions
@@ -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<KnownDecorator> PROPERTY_DECORATORS = EnumSet.of(PROPERTY,
ABC_ABSTRACTPROPERTY,
PYRAMID_DECORATOR_REIFY,
DJANGO_UTILS_FUNCTIONAL_CACHED_PROPERTY,
KOMBU_UTILS_CACHED_PROPERTY);
private static final Map<String, KnownDecorator> ourByShortName = newMapFromValues(Iterators.forArray(values()),
new Convertor<KnownDecorator, String>() {
@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<KnownDecorator> decorators) {
final PyDecoratorList decoratorList = element.getDecoratorList();
return decoratorList == null ? decorators.isEmpty() : decoratorList.getDecorators().length == decorators.size();
@@ -765,9 +765,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> 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)) {