/**
   * 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();
 }