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