1fad3a1d3Sopenharmony_ci#[cfg_attr(
2fad3a1d3Sopenharmony_ci    not(any(feature = "full", feature = "derive")),
3fad3a1d3Sopenharmony_ci    allow(unknown_lints, unused_macro_rules)
4fad3a1d3Sopenharmony_ci)]
5fad3a1d3Sopenharmony_cimacro_rules! ast_struct {
6fad3a1d3Sopenharmony_ci    (
7fad3a1d3Sopenharmony_ci        $(#[$attr:meta])*
8fad3a1d3Sopenharmony_ci        $pub:ident $struct:ident $name:ident #full $body:tt
9fad3a1d3Sopenharmony_ci    ) => {
10fad3a1d3Sopenharmony_ci        check_keyword_matches!(pub $pub);
11fad3a1d3Sopenharmony_ci        check_keyword_matches!(struct $struct);
12fad3a1d3Sopenharmony_ci
13fad3a1d3Sopenharmony_ci        #[cfg(feature = "full")]
14fad3a1d3Sopenharmony_ci        $(#[$attr])* $pub $struct $name $body
15fad3a1d3Sopenharmony_ci
16fad3a1d3Sopenharmony_ci        #[cfg(not(feature = "full"))]
17fad3a1d3Sopenharmony_ci        $(#[$attr])* $pub $struct $name {
18fad3a1d3Sopenharmony_ci            _noconstruct: ::std::marker::PhantomData<::proc_macro2::Span>,
19fad3a1d3Sopenharmony_ci        }
20fad3a1d3Sopenharmony_ci
21fad3a1d3Sopenharmony_ci        #[cfg(all(not(feature = "full"), feature = "printing"))]
22fad3a1d3Sopenharmony_ci        impl ::quote::ToTokens for $name {
23fad3a1d3Sopenharmony_ci            fn to_tokens(&self, _: &mut ::proc_macro2::TokenStream) {
24fad3a1d3Sopenharmony_ci                unreachable!()
25fad3a1d3Sopenharmony_ci            }
26fad3a1d3Sopenharmony_ci        }
27fad3a1d3Sopenharmony_ci    };
28fad3a1d3Sopenharmony_ci
29fad3a1d3Sopenharmony_ci    (
30fad3a1d3Sopenharmony_ci        $(#[$attr:meta])*
31fad3a1d3Sopenharmony_ci        $pub:ident $struct:ident $name:ident $body:tt
32fad3a1d3Sopenharmony_ci    ) => {
33fad3a1d3Sopenharmony_ci        check_keyword_matches!(pub $pub);
34fad3a1d3Sopenharmony_ci        check_keyword_matches!(struct $struct);
35fad3a1d3Sopenharmony_ci
36fad3a1d3Sopenharmony_ci        $(#[$attr])* $pub $struct $name $body
37fad3a1d3Sopenharmony_ci    };
38fad3a1d3Sopenharmony_ci}
39fad3a1d3Sopenharmony_ci
40fad3a1d3Sopenharmony_ci#[cfg(any(feature = "full", feature = "derive"))]
41fad3a1d3Sopenharmony_cimacro_rules! ast_enum {
42fad3a1d3Sopenharmony_ci    (
43fad3a1d3Sopenharmony_ci        $(#[$enum_attr:meta])*
44fad3a1d3Sopenharmony_ci        $pub:ident $enum:ident $name:ident $body:tt
45fad3a1d3Sopenharmony_ci    ) => {
46fad3a1d3Sopenharmony_ci        check_keyword_matches!(pub $pub);
47fad3a1d3Sopenharmony_ci        check_keyword_matches!(enum $enum);
48fad3a1d3Sopenharmony_ci
49fad3a1d3Sopenharmony_ci        $(#[$enum_attr])* $pub $enum $name $body
50fad3a1d3Sopenharmony_ci    };
51fad3a1d3Sopenharmony_ci}
52fad3a1d3Sopenharmony_ci
53fad3a1d3Sopenharmony_cimacro_rules! ast_enum_of_structs {
54fad3a1d3Sopenharmony_ci    (
55fad3a1d3Sopenharmony_ci        $(#[$enum_attr:meta])*
56fad3a1d3Sopenharmony_ci        $pub:ident $enum:ident $name:ident $body:tt
57fad3a1d3Sopenharmony_ci    ) => {
58fad3a1d3Sopenharmony_ci        check_keyword_matches!(pub $pub);
59fad3a1d3Sopenharmony_ci        check_keyword_matches!(enum $enum);
60fad3a1d3Sopenharmony_ci
61fad3a1d3Sopenharmony_ci        $(#[$enum_attr])* $pub $enum $name $body
62fad3a1d3Sopenharmony_ci
63fad3a1d3Sopenharmony_ci        ast_enum_of_structs_impl!($name $body);
64fad3a1d3Sopenharmony_ci    };
65fad3a1d3Sopenharmony_ci}
66fad3a1d3Sopenharmony_ci
67fad3a1d3Sopenharmony_cimacro_rules! ast_enum_of_structs_impl {
68fad3a1d3Sopenharmony_ci    (
69fad3a1d3Sopenharmony_ci        $name:ident {
70fad3a1d3Sopenharmony_ci            $(
71fad3a1d3Sopenharmony_ci                $(#[cfg $cfg_attr:tt])*
72fad3a1d3Sopenharmony_ci                $(#[doc $($doc_attr:tt)*])*
73fad3a1d3Sopenharmony_ci                $variant:ident $( ($($member:ident)::+) )*,
74fad3a1d3Sopenharmony_ci            )*
75fad3a1d3Sopenharmony_ci        }
76fad3a1d3Sopenharmony_ci    ) => {
77fad3a1d3Sopenharmony_ci        $($(
78fad3a1d3Sopenharmony_ci            ast_enum_from_struct!($name::$variant, $($member)::+);
79fad3a1d3Sopenharmony_ci        )*)*
80fad3a1d3Sopenharmony_ci
81fad3a1d3Sopenharmony_ci        #[cfg(feature = "printing")]
82fad3a1d3Sopenharmony_ci        generate_to_tokens! {
83fad3a1d3Sopenharmony_ci            ()
84fad3a1d3Sopenharmony_ci            tokens
85fad3a1d3Sopenharmony_ci            $name {
86fad3a1d3Sopenharmony_ci                $(
87fad3a1d3Sopenharmony_ci                    $(#[cfg $cfg_attr])*
88fad3a1d3Sopenharmony_ci                    $(#[doc $($doc_attr)*])*
89fad3a1d3Sopenharmony_ci                    $variant $($($member)::+)*,
90fad3a1d3Sopenharmony_ci                )*
91fad3a1d3Sopenharmony_ci            }
92fad3a1d3Sopenharmony_ci        }
93fad3a1d3Sopenharmony_ci    };
94fad3a1d3Sopenharmony_ci}
95fad3a1d3Sopenharmony_ci
96fad3a1d3Sopenharmony_cimacro_rules! ast_enum_from_struct {
97fad3a1d3Sopenharmony_ci    // No From<TokenStream> for verbatim variants.
98fad3a1d3Sopenharmony_ci    ($name:ident::Verbatim, $member:ident) => {};
99fad3a1d3Sopenharmony_ci
100fad3a1d3Sopenharmony_ci    ($name:ident::$variant:ident, $member:ident) => {
101fad3a1d3Sopenharmony_ci        impl From<$member> for $name {
102fad3a1d3Sopenharmony_ci            fn from(e: $member) -> $name {
103fad3a1d3Sopenharmony_ci                $name::$variant(e)
104fad3a1d3Sopenharmony_ci            }
105fad3a1d3Sopenharmony_ci        }
106fad3a1d3Sopenharmony_ci    };
107fad3a1d3Sopenharmony_ci}
108fad3a1d3Sopenharmony_ci
109fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")]
110fad3a1d3Sopenharmony_cimacro_rules! generate_to_tokens {
111fad3a1d3Sopenharmony_ci    (
112fad3a1d3Sopenharmony_ci        ($($arms:tt)*) $tokens:ident $name:ident {
113fad3a1d3Sopenharmony_ci            $(#[cfg $cfg_attr:tt])*
114fad3a1d3Sopenharmony_ci            $(#[doc $($doc_attr:tt)*])*
115fad3a1d3Sopenharmony_ci            $variant:ident,
116fad3a1d3Sopenharmony_ci            $($next:tt)*
117fad3a1d3Sopenharmony_ci        }
118fad3a1d3Sopenharmony_ci    ) => {
119fad3a1d3Sopenharmony_ci        generate_to_tokens!(
120fad3a1d3Sopenharmony_ci            ($($arms)* $(#[cfg $cfg_attr])* $name::$variant => {})
121fad3a1d3Sopenharmony_ci            $tokens $name { $($next)* }
122fad3a1d3Sopenharmony_ci        );
123fad3a1d3Sopenharmony_ci    };
124fad3a1d3Sopenharmony_ci
125fad3a1d3Sopenharmony_ci    (
126fad3a1d3Sopenharmony_ci        ($($arms:tt)*) $tokens:ident $name:ident {
127fad3a1d3Sopenharmony_ci            $(#[cfg $cfg_attr:tt])*
128fad3a1d3Sopenharmony_ci            $(#[doc $($doc_attr:tt)*])*
129fad3a1d3Sopenharmony_ci            $variant:ident $member:ident,
130fad3a1d3Sopenharmony_ci            $($next:tt)*
131fad3a1d3Sopenharmony_ci        }
132fad3a1d3Sopenharmony_ci    ) => {
133fad3a1d3Sopenharmony_ci        generate_to_tokens!(
134fad3a1d3Sopenharmony_ci            ($($arms)* $(#[cfg $cfg_attr])* $name::$variant(_e) => _e.to_tokens($tokens),)
135fad3a1d3Sopenharmony_ci            $tokens $name { $($next)* }
136fad3a1d3Sopenharmony_ci        );
137fad3a1d3Sopenharmony_ci    };
138fad3a1d3Sopenharmony_ci
139fad3a1d3Sopenharmony_ci    (($($arms:tt)*) $tokens:ident $name:ident {}) => {
140fad3a1d3Sopenharmony_ci        #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
141fad3a1d3Sopenharmony_ci        impl ::quote::ToTokens for $name {
142fad3a1d3Sopenharmony_ci            fn to_tokens(&self, $tokens: &mut ::proc_macro2::TokenStream) {
143fad3a1d3Sopenharmony_ci                match self {
144fad3a1d3Sopenharmony_ci                    $($arms)*
145fad3a1d3Sopenharmony_ci                }
146fad3a1d3Sopenharmony_ci            }
147fad3a1d3Sopenharmony_ci        }
148fad3a1d3Sopenharmony_ci    };
149fad3a1d3Sopenharmony_ci}
150fad3a1d3Sopenharmony_ci
151fad3a1d3Sopenharmony_ci// Rustdoc bug: does not respect the doc(hidden) on some items.
152fad3a1d3Sopenharmony_ci#[cfg(all(doc, feature = "parsing"))]
153fad3a1d3Sopenharmony_cimacro_rules! pub_if_not_doc {
154fad3a1d3Sopenharmony_ci    ($(#[$m:meta])* $pub:ident $($item:tt)*) => {
155fad3a1d3Sopenharmony_ci        check_keyword_matches!(pub $pub);
156fad3a1d3Sopenharmony_ci
157fad3a1d3Sopenharmony_ci        $(#[$m])*
158fad3a1d3Sopenharmony_ci        $pub(crate) $($item)*
159fad3a1d3Sopenharmony_ci    };
160fad3a1d3Sopenharmony_ci}
161fad3a1d3Sopenharmony_ci
162fad3a1d3Sopenharmony_ci#[cfg(all(not(doc), feature = "parsing"))]
163fad3a1d3Sopenharmony_cimacro_rules! pub_if_not_doc {
164fad3a1d3Sopenharmony_ci    ($(#[$m:meta])* $pub:ident $($item:tt)*) => {
165fad3a1d3Sopenharmony_ci        check_keyword_matches!(pub $pub);
166fad3a1d3Sopenharmony_ci
167fad3a1d3Sopenharmony_ci        $(#[$m])*
168fad3a1d3Sopenharmony_ci        $pub $($item)*
169fad3a1d3Sopenharmony_ci    };
170fad3a1d3Sopenharmony_ci}
171fad3a1d3Sopenharmony_ci
172fad3a1d3Sopenharmony_cimacro_rules! check_keyword_matches {
173fad3a1d3Sopenharmony_ci    (enum enum) => {};
174fad3a1d3Sopenharmony_ci    (pub pub) => {};
175fad3a1d3Sopenharmony_ci    (struct struct) => {};
176fad3a1d3Sopenharmony_ci}
177