/** * 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; }
@Override public String convert(KnownDecorator o) { return o.getShortName(); }