use rustc_ast::ast::{AttrStyle, LitKind, MetaItemLit};
use rustc_errors::{Applicability, msg};
use rustc_feature::AttributeStability;
use rustc_hir::Target;
use rustc_hir::attrs::{
    AttributeKind, CfgEntry, CfgHideShow, CfgInfo, DocAttribute, DocInline, HideOrShow,
};
use rustc_session::errors::feature_err;
use rustc_span::{Span, Symbol, edition, sym};
use thin_vec::ThinVec;

use super::prelude::{ALL_TARGETS, AllowedTargets};
use super::{AcceptMapping, AttributeParser, template};
use crate::context::{AcceptContext, FinalizeContext};
use crate::diagnostics::{
    AttrCrateLevelOnly, DocAliasDuplicated, DocAutoCfgExpectsHideOrShow,
    DocAutoCfgHideShowExpectsList, DocAutoCfgHideShowUnexpectedItem, DocAutoCfgWrongLiteral,
    DocTestLiteral, DocTestTakesList, DocTestUnknown, DocUnknownAny, DocUnknownInclude,
    DocUnknownPasses, DocUnknownPlugins, DocUnknownSpotlight, ExpectedNameValue, ExpectedNoArgs,
    IllFormedAttributeInput, MalformedDoc,
};
use crate::parser::{ArgParser, MetaItemOrLitParser, MetaItemParser, OwnedPathParser};
use crate::session_diagnostics::{
    DocAliasBadChar, DocAliasEmpty, DocAliasMalformed, DocAliasStartEnd, DocAttrNotCrateLevel,
    DocAttributeNotAttribute, DocKeywordNotKeyword, UnusedDuplicate,
};

fn check_keyword(cx: &mut AcceptContext<'_, '_>, keyword: Symbol, span: Span) -> bool {
    // FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we
    // can remove the `SelfTy` case here, remove `sym::SelfTy`, and update the
    // `#[doc(keyword = "SelfTy")` attribute in `library/std/src/keyword_docs.rs`.
    if keyword.is_reserved(|| edition::LATEST_STABLE_EDITION)
        || keyword.is_weak()
        || keyword == sym::SelfTy
    {
        return true;
    }
    cx.emit_err(DocKeywordNotKeyword { span, keyword });
    false
}

fn check_attribute(cx: &mut AcceptContext<'_, '_>, attribute: Symbol, span: Span) -> bool {
    // FIXME: This should support attributes with namespace like `diagnostic::do_not_recommend`.
    if rustc_feature::BUILTIN_ATTRIBUTE_MAP.contains(&attribute) {
        return true;
    }
    cx.emit_err(DocAttributeNotAttribute { span, attribute });
    false
}

/// Checks that an attribute is *not* used at the crate level. Returns `true` if valid.
fn check_attr_not_crate_level(
    cx: &mut AcceptContext<'_, '_>,
    span: Span,
    attr_name: Symbol,
) -> bool {
    if cx.shared.target == Target::Crate {
        cx.emit_err(DocAttrNotCrateLevel { span, attr_name });
        return false;
    }
    true
}

/// Checks that an attribute is used at the crate level. Returns `true` if valid.
fn check_attr_crate_level(cx: &mut AcceptContext<'_, '_>, span: Span) -> bool {
    if cx.shared.target != Target::Crate {
        cx.emit_lint(
            rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
            AttrCrateLevelOnly,
            span,
        );
        return false;
    }
    true
}

// FIXME: To be removed once merged and replace with `cx.expected_name_value(span, _name)`.
fn expected_name_value(cx: &mut AcceptContext<'_, '_>, span: Span, _name: Option<Symbol>) {
    cx.emit_lint(rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, ExpectedNameValue, span);
}

// FIXME: remove this method once merged and use `cx.expected_no_args(span)` instead.
fn expected_no_args(cx: &mut AcceptContext<'_, '_>, span: Span) {
    cx.emit_lint(rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, ExpectedNoArgs, span);
}

// FIXME: remove this method once merged and use `cx.expected_no_args(span)` instead.
// cx.expected_string_literal(span, _actual_literal);
fn expected_string_literal(
    cx: &mut AcceptContext<'_, '_>,
    span: Span,
    _actual_literal: Option<&MetaItemLit>,
) {
    cx.emit_lint(rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES, MalformedDoc, span);
}

fn parse_keyword_and_attribute(
    cx: &mut AcceptContext<'_, '_>,
    path: &OwnedPathParser,
    args: &ArgParser,
    attr_value: &mut Option<(Symbol, Span)>,
    attr_name: Symbol,
) {
    let Some(nv) = args.as_name_value() else {
        expected_name_value(cx, args.span().unwrap_or(path.span()), path.word_sym());
        return;
    };

    let Some(value) = nv.value_as_str() else {
        expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit()));
        return;
    };

    let ret = if attr_name == sym::keyword {
        check_keyword(cx, value, nv.value_span)
    } else {
        check_attribute(cx, value, nv.value_span)
    };
    if !ret {
        return;
    }

    let span = path.span();
    if attr_value.is_some() {
        cx.adcx().duplicate_key(span, path.word_sym().unwrap());
        return;
    }

    if !check_attr_not_crate_level(cx, span, attr_name) {
        return;
    }

    *attr_value = Some((value, span));
}

#[derive(Default, Debug)]
pub(crate) struct DocParser {
    attribute: DocAttribute,
    nb_doc_attrs: usize,
}

impl DocParser {
    fn parse_single_test_doc_attr_item(
        &mut self,
        cx: &mut AcceptContext<'_, '_>,
        mip: &MetaItemParser,
    ) {
        let path = mip.path();
        let args = mip.args();

        match path.word_sym() {
            Some(sym::no_crate_inject) => {
                if let Err(span) = args.as_no_args() {
                    expected_no_args(cx, span);
                    return;
                }

                if let Some(used_span) = self.attribute.no_crate_inject {
                    let unused_span = path.span();
                    cx.emit_lint(
                        rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                        UnusedDuplicate { this: unused_span, other: used_span, warning: true },
                        unused_span,
                    );
                    return;
                }

                if !check_attr_crate_level(cx, path.span()) {
                    return;
                }

                self.attribute.no_crate_inject = Some(path.span())
            }
            Some(sym::attr) => {
                let Some(list) = args.as_list() else {
                    // FIXME: remove this method once merged and uncomment the line below instead.
                    // cx.expected_list(cx.attr_span, args);
                    let span = cx.attr_span;
                    cx.emit_lint(
                        rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                        MalformedDoc,
                        span,
                    );
                    return;
                };

                // FIXME: convert list into a Vec of `AttributeKind` because current code is awful.
                for attr in list.mixed() {
                    // Arguments of `attr` are checked via the span, so can be safely ignored
                    attr.ignore_args();
                    self.attribute.test_attrs.push(attr.span());
                }
            }
            Some(name) => {
                cx.emit_lint(
                    rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                    DocTestUnknown { name },
                    path.span(),
                );
            }
            None => {
                cx.emit_lint(
                    rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                    DocTestLiteral,
                    path.span(),
                );
            }
        }
    }

    fn add_alias(&mut self, cx: &mut AcceptContext<'_, '_>, alias: Symbol, span: Span) {
        let attr_str = "`#[doc(alias = \"...\")]`";
        if alias == sym::empty {
            cx.emit_err(DocAliasEmpty { span, attr_str });
            return;
        }

        let alias_str = alias.as_str();
        if let Some(c) =
            alias_str.chars().find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' '))
        {
            cx.emit_err(DocAliasBadChar { span, attr_str, char_: c });
            return;
        }
        if alias_str.starts_with(' ') || alias_str.ends_with(' ') {
            cx.emit_err(DocAliasStartEnd { span, attr_str });
            return;
        }
        if !check_attr_not_crate_level(cx, span, sym::alias) {
            return;
        }

        if let Some(first_definition) = self.attribute.aliases.get(&alias).copied() {
            cx.emit_lint(
                rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
                DocAliasDuplicated { first_definition },
                span,
            );
        }

        self.attribute.aliases.insert(alias, span);
    }

    fn parse_alias(
        &mut self,
        cx: &mut AcceptContext<'_, '_>,
        path: &OwnedPathParser,
        args: &ArgParser,
    ) {
        match args {
            ArgParser::NoArgs => {
                cx.emit_err(DocAliasMalformed { span: args.span().unwrap_or(path.span()) });
            }
            ArgParser::List(list) => {
                for i in list.mixed() {
                    let Some(alias) = cx.expect_string_literal(i) else {
                        continue;
                    };

                    self.add_alias(cx, alias, i.span());
                }
            }
            ArgParser::NameValue(nv) => {
                let Some(alias) = cx.expect_string_literal(nv) else {
                    return;
                };
                self.add_alias(cx, alias, nv.value_span);
            }
        }
    }

    fn parse_inline(
        &mut self,
        cx: &mut AcceptContext<'_, '_>,
        path: &OwnedPathParser,
        args: &ArgParser,
        inline: DocInline,
    ) {
        if let Err(span) = args.as_no_args() {
            expected_no_args(cx, span);
            return;
        }

        self.attribute.inline.push((inline, path.span()));
    }

    fn parse_cfg(&mut self, cx: &mut AcceptContext<'_, '_>, args: &ArgParser) {
        // This function replaces cases like `cfg(all())` with `true`.
        fn simplify_cfg(cfg_entry: &mut CfgEntry) {
            match cfg_entry {
                CfgEntry::All(cfgs, span) if cfgs.is_empty() => {
                    *cfg_entry = CfgEntry::Bool(true, *span)
                }
                CfgEntry::Any(cfgs, span) if cfgs.is_empty() => {
                    *cfg_entry = CfgEntry::Bool(false, *span)
                }
                CfgEntry::Not(cfg, _) => simplify_cfg(cfg),
                _ => {}
            }
        }
        if let Some(mut cfg_entry) = super::cfg::parse_cfg(cx, args) {
            simplify_cfg(&mut cfg_entry);
            self.attribute.cfg.push(cfg_entry);
        }
    }

    fn parse_auto_cfg(
        &mut self,
        cx: &mut AcceptContext<'_, '_>,
        path: &OwnedPathParser,
        args: &ArgParser,
    ) {
        match args {
            ArgParser::NoArgs => {
                self.attribute.auto_cfg_change.push((true, path.span()));
            }
            ArgParser::List(list) => {
                for meta in list.mixed() {
                    let MetaItemOrLitParser::MetaItemParser(item) = meta else {
                        cx.emit_lint(
                            rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                            DocAutoCfgExpectsHideOrShow,
                            meta.span(),
                        );
                        continue;
                    };
                    let (kind, attr_name) = match item.path().word_sym() {
                        Some(sym::hide) => (HideOrShow::Hide, sym::hide),
                        Some(sym::show) => (HideOrShow::Show, sym::show),
                        _ => {
                            cx.emit_lint(
                                rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                                DocAutoCfgExpectsHideOrShow,
                                item.span(),
                            );
                            continue;
                        }
                    };
                    let ArgParser::List(list) = item.args() else {
                        cx.emit_lint(
                            rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                            DocAutoCfgHideShowExpectsList { attr_name },
                            item.span(),
                        );
                        continue;
                    };

                    let mut cfg_hide_show = CfgHideShow { kind, values: ThinVec::new() };

                    for item in list.mixed() {
                        let MetaItemOrLitParser::MetaItemParser(sub_item) = item else {
                            cx.emit_lint(
                                rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                                DocAutoCfgHideShowUnexpectedItem { attr_name },
                                item.span(),
                            );
                            continue;
                        };
                        match sub_item.args() {
                            a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => {
                                let Some(name) = sub_item.path().word_sym() else {
                                    // FIXME: remove this method once merged and uncomment the line
                                    // below instead.
                                    // cx.expected_identifier(sub_item.path().span());
                                    cx.emit_lint(
                                        rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                                        MalformedDoc,
                                        sub_item.path().span(),
                                    );
                                    continue;
                                };
                                if let Ok(CfgEntry::NameValue { name, value, .. }) =
                                    super::cfg::parse_name_value(
                                        name,
                                        sub_item.path().span(),
                                        a.as_name_value(),
                                        sub_item.span(),
                                        cx,
                                    )
                                {
                                    cfg_hide_show.values.push(CfgInfo {
                                        name,
                                        name_span: sub_item.path().span(),
                                        // If `value` is `Some`, `a.name_value()` will always return
                                        // `Some` as well.
                                        value: value
                                            .map(|v| (v, a.as_name_value().unwrap().value_span)),
                                    })
                                }
                            }
                            _ => {
                                cx.emit_lint(
                                    rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                                    DocAutoCfgHideShowUnexpectedItem { attr_name },
                                    sub_item.span(),
                                );
                                continue;
                            }
                        }
                    }
                    self.attribute.auto_cfg.push((cfg_hide_show, path.span()));
                }
            }
            ArgParser::NameValue(nv) => {
                let MetaItemLit { kind: LitKind::Bool(bool_value), span, .. } = nv.value_as_lit()
                else {
                    cx.emit_lint(
                        rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                        DocAutoCfgWrongLiteral,
                        nv.value_span,
                    );
                    return;
                };
                self.attribute.auto_cfg_change.push((*bool_value, *span));
            }
        }
    }

    fn parse_single_doc_attr_item(&mut self, cx: &mut AcceptContext<'_, '_>, mip: &MetaItemParser) {
        let path = mip.path();
        let args = mip.args();

        macro_rules! no_args {
            ($ident: ident) => {{
                if let Err(span) = args.as_no_args() {
                    expected_no_args(cx, span);
                    return;
                }

                // FIXME: It's errorring when the attribute is passed multiple times on the command
                // line.
                // The right fix for this would be to only check this rule if the attribute is
                // not set on the command line but directly in the code.
                // if self.attribute.$ident.is_some() {
                //     cx.duplicate_key(path.span(), path.word_sym().unwrap());
                //     return;
                // }

                self.attribute.$ident = Some(path.span());
            }};
        }
        macro_rules! no_args_and_not_crate_level {
            ($ident: ident) => {{
                if let Err(span) = args.as_no_args() {
                    expected_no_args(cx, span);
                    return;
                }
                let span = path.span();
                if !check_attr_not_crate_level(cx, span, sym::$ident) {
                    return;
                }
                self.attribute.$ident = Some(span);
            }};
        }
        macro_rules! no_args_and_crate_level {
            ($ident: ident) => {{
                no_args_and_crate_level!($ident, |span| {});
            }};
            ($ident: ident, |$span:ident| $extra_validation:block) => {{
                if let Err(span) = args.as_no_args() {
                    expected_no_args(cx, span);
                    return;
                }
                let $span = path.span();
                if !check_attr_crate_level(cx, $span) {
                    return;
                }
                $extra_validation
                self.attribute.$ident = Some($span);
            }};
        }
        macro_rules! string_arg_and_crate_level {
            ($ident: ident) => {{
                let Some(nv) = args.as_name_value() else {
                    expected_name_value(cx, args.span().unwrap_or(path.span()), path.word_sym());
                    return;
                };

                let Some(s) = nv.value_as_str() else {
                    expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit()));
                    return;
                };

                if !check_attr_crate_level(cx, path.span()) {
                    return;
                }

                // FIXME: It's errorring when the attribute is passed multiple times on the command
                // line.
                // The right fix for this would be to only check this rule if the attribute is
                // not set on the command line but directly in the code.
                // if self.attribute.$ident.is_some() {
                //     cx.duplicate_key(path.span(), path.word_sym().unwrap());
                //     return;
                // }

                self.attribute.$ident = Some((s, path.span()));
            }};
        }

        match path.word_sym() {
            Some(sym::alias) => self.parse_alias(cx, path, args),
            Some(sym::hidden) => no_args!(hidden),
            Some(sym::html_favicon_url) => string_arg_and_crate_level!(html_favicon_url),
            Some(sym::html_logo_url) => string_arg_and_crate_level!(html_logo_url),
            Some(sym::html_no_source) => no_args_and_crate_level!(html_no_source),
            Some(sym::html_playground_url) => string_arg_and_crate_level!(html_playground_url),
            Some(sym::html_root_url) => string_arg_and_crate_level!(html_root_url),
            Some(sym::issue_tracker_base_url) => {
                string_arg_and_crate_level!(issue_tracker_base_url)
            }
            Some(sym::inline) => self.parse_inline(cx, path, args, DocInline::Inline),
            Some(sym::no_inline) => self.parse_inline(cx, path, args, DocInline::NoInline),
            Some(sym::masked) => no_args!(masked),
            Some(sym::cfg) => self.parse_cfg(cx, args),
            Some(sym::notable_trait) => no_args!(notable_trait),
            Some(sym::keyword) => parse_keyword_and_attribute(
                cx,
                path,
                args,
                &mut self.attribute.keyword,
                sym::keyword,
            ),
            Some(sym::attribute) => parse_keyword_and_attribute(
                cx,
                path,
                args,
                &mut self.attribute.attribute,
                sym::attribute,
            ),
            Some(sym::fake_variadic) => no_args_and_not_crate_level!(fake_variadic),
            Some(sym::search_unbox) => no_args_and_not_crate_level!(search_unbox),
            Some(sym::rust_logo) => no_args_and_crate_level!(rust_logo, |span| {
                if !cx.features().rustdoc_internals() {
                    feature_err(
                        cx.sess(),
                        sym::rustdoc_internals,
                        span,
                        msg!("the `#[doc(rust_logo)]` attribute is used for Rust branding"),
                    )
                    .emit();
                }
            }),
            Some(sym::auto_cfg) => self.parse_auto_cfg(cx, path, args),
            Some(sym::test) => {
                let Some(list) = args.as_list() else {
                    cx.emit_lint(
                        rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                        DocTestTakesList,
                        args.span().unwrap_or(path.span()),
                    );
                    return;
                };

                for i in list.mixed() {
                    match i {
                        MetaItemOrLitParser::MetaItemParser(mip) => {
                            self.parse_single_test_doc_attr_item(cx, mip);
                        }
                        MetaItemOrLitParser::Lit(lit) => {
                            // FIXME: remove this method once merged and uncomment the line
                            // below instead.
                            // cx.unexpected_literal(lit.span);
                            cx.emit_lint(
                                rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                                MalformedDoc,
                                lit.span,
                            );
                        }
                    }
                }
            }
            Some(sym::spotlight) => {
                let span = path.span();
                cx.emit_lint(
                    rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                    DocUnknownSpotlight { sugg_span: span },
                    span,
                );
            }
            Some(sym::include) if let Some(nv) = args.as_name_value() => {
                let inner = match cx.attr_style {
                    AttrStyle::Outer => "",
                    AttrStyle::Inner => "!",
                };
                let value = nv.value_as_lit().symbol;
                let span = path.span();
                cx.emit_lint(
                    rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                    DocUnknownInclude { inner, value, sugg: (span, Applicability::MaybeIncorrect) },
                    span,
                );
            }
            Some(name @ (sym::passes | sym::no_default_passes)) => {
                let span = path.span();
                cx.emit_lint(
                    rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                    DocUnknownPasses { name, note_span: span },
                    span,
                );
            }
            Some(sym::plugins) => {
                let span = path.span();
                cx.emit_lint(
                    rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                    DocUnknownPlugins { label_span: span },
                    span,
                );
            }
            Some(name) => {
                cx.emit_lint(
                    rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                    DocUnknownAny { name },
                    path.span(),
                );
            }
            None => {
                let full_name =
                    path.segments().map(|s| s.as_str()).intersperse("::").collect::<String>();
                let name = Symbol::intern(&full_name);
                cx.emit_lint(
                    rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                    DocUnknownAny { name },
                    path.span(),
                );
            }
        }
    }

    fn accept_single_doc_attr(&mut self, cx: &mut AcceptContext<'_, '_>, args: &ArgParser) {
        match args {
            ArgParser::NoArgs => {
                let suggestions = cx.adcx().suggestions();
                let span = cx.attr_span;
                cx.emit_lint(
                    rustc_session::lint::builtin::INVALID_DOC_ATTRIBUTES,
                    IllFormedAttributeInput::new(&suggestions, None, None),
                    span,
                );
            }
            ArgParser::List(items) => {
                for i in items.mixed() {
                    match i {
                        MetaItemOrLitParser::MetaItemParser(mip) => {
                            if self.nb_doc_attrs == 0 {
                                self.attribute.first_span = cx.attr_span;
                            }
                            self.nb_doc_attrs += 1;
                            self.parse_single_doc_attr_item(cx, mip);
                        }
                        MetaItemOrLitParser::Lit(lit) => {
                            expected_name_value(cx, lit.span, None);
                        }
                    }
                }
            }
            ArgParser::NameValue(nv) => {
                if nv.value_as_str().is_none() {
                    expected_string_literal(cx, nv.value_span, Some(nv.value_as_lit()));
                } else {
                    unreachable!(
                        "Should have been handled at the same time as sugar-syntaxed doc comments"
                    );
                }
            }
        }
    }
}

impl AttributeParser for DocParser {
    const ATTRIBUTES: AcceptMapping<Self> = &[(
        &[sym::doc],
        template!(
            List: &[
                "alias",
                "attribute",
                "hidden",
                "html_favicon_url",
                "html_logo_url",
                "html_no_source",
                "html_playground_url",
                "html_root_url",
                "issue_tracker_base_url",
                "inline",
                "no_inline",
                "masked",
                "cfg",
                "notable_trait",
                "keyword",
                "fake_variadic",
                "search_unbox",
                "rust_logo",
                "auto_cfg",
                "test",
                "spotlight",
                "include",
                "no_default_passes",
                "passes",
                "plugins",
            ],
            NameValueStr: "string"
        ),
        AttributeStability::Stable, // Some parts of the attribute are unstable, manually checked in parser
        |this, cx, args| {
            this.accept_single_doc_attr(cx, args);
        },
    )];
    // FIXME: Currently emitted from 2 different places, generating duplicated warnings.
    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
    // const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
    //     Allow(Target::ExternCrate),
    //     Allow(Target::Use),
    //     Allow(Target::Static),
    //     Allow(Target::Const),
    //     Allow(Target::Fn),
    //     Allow(Target::Mod),
    //     Allow(Target::ForeignMod),
    //     Allow(Target::TyAlias),
    //     Allow(Target::Enum),
    //     Allow(Target::Variant),
    //     Allow(Target::Struct),
    //     Allow(Target::Field),
    //     Allow(Target::Union),
    //     Allow(Target::Trait),
    //     Allow(Target::TraitAlias),
    //     Allow(Target::Impl { of_trait: true }),
    //     Allow(Target::Impl { of_trait: false }),
    //     Allow(Target::AssocConst),
    //     Allow(Target::Method(MethodKind::Inherent)),
    //     Allow(Target::Method(MethodKind::Trait { body: true })),
    //     Allow(Target::Method(MethodKind::Trait { body: false })),
    //     Allow(Target::Method(MethodKind::TraitImpl)),
    //     Allow(Target::AssocTy),
    //     Allow(Target::ForeignFn),
    //     Allow(Target::ForeignStatic),
    //     Allow(Target::ForeignTy),
    //     Allow(Target::MacroDef),
    //     Allow(Target::Crate),
    //     Error(Target::WherePredicate),
    // ]);

    fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
        if self.nb_doc_attrs != 0 {
            Some(AttributeKind::Doc(Box::new(self.attribute)))
        } else {
            None
        }
    }
}
