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(); }
/** * Checks that given element has any non-builtin decorators. * * @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 of theirs qualified names. * @see PyKnownDecoratorUtil.KnownDecorator */ public static boolean hasNonBuiltinDecorator( @NotNull PyDecoratable element, @NotNull TypeEvalContext context) { final List<KnownDecorator> knownDecorators = getKnownDecorators(element, context); if (!allDecoratorsAreKnown(element, knownDecorators)) { return true; } knownDecorators.removeAll(BUILTIN_DECORATORS); return !knownDecorators.isEmpty(); }
/** * Checks that given function has any decorators from {@code abc} module. * * @param element Python function 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 of theirs qualified names. * @see PyKnownDecoratorUtil.KnownDecorator */ public static boolean hasAbstractDecorator( @NotNull PyDecoratable element, @NotNull TypeEvalContext context) { final List<KnownDecorator> knownDecorators = getKnownDecorators(element, context); if (knownDecorators.isEmpty()) { return false; } knownDecorators.retainAll(ABSTRACT_DECORATORS); return !knownDecorators.isEmpty(); }
/** * Map decorators of element to {@link * com.jetbrains.python.psi.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 of theirs qualified names. * @return list of known decorators in declaration order with duplicates (with any) */ @NotNull public static List<KnownDecorator> getKnownDecorators( @NotNull PyDecoratable element, @NotNull TypeEvalContext context) { final PyDecoratorList decoratorList = element.getDecoratorList(); if (decoratorList == null) { return Collections.emptyList(); } final List<KnownDecorator> result = new ArrayList<>(); final boolean allowResolve = context.maySwitchToAST((PsiElement) element); for (PyDecorator decorator : decoratorList.getDecorators()) { final QualifiedName qualifiedName = decorator.getQualifiedName(); if (qualifiedName == null) { continue; } final KnownDecorator knownDecorator = ourByShortName.get(qualifiedName.getLastComponent()); if (knownDecorator != null) { if (allowResolve) { PyQualifiedNameOwner resolved = as(resolveDecorator(decorator), PyQualifiedNameOwner.class); if (resolved instanceof PyFunction && PyNames.INIT.equals(resolved.getName())) { resolved = ((PyFunction) resolved).getContainingClass(); } if (resolved != null && resolved.getQualifiedName() != null) { final QualifiedName resolvedName = QualifiedName.fromDottedString(resolved.getQualifiedName()); if (resolvedName.equals(knownDecorator.getQualifiedName())) { result.add(knownDecorator); } } } else { result.add(knownDecorator); } } } return result; }