xref: /linux/rust/syn/macros.rs (revision 808c999fc9e7c366fd47da564e69d579c1dc8279)
1 #[cfg_attr(
2     not(any(feature = "full", feature = "derive")),
3     allow(unknown_lints, unused_macro_rules)
4 )]
5 macro_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"))]
41 macro_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 
53 macro_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         #[cfg(feature = "printing")]
66         generate_to_tokens!(() tokens $name $body);
67     };
68 }
69 
70 macro_rules! ast_enum_of_structs_impl {
71     (
72         $name:ident {
73             $(
74                 $(#[cfg $cfg_attr:tt])*
75                 $(#[doc $($doc_attr:tt)*])*
76                 $variant:ident $( ($member:ident) )*,
77             )*
78         }
79     ) => {
80         $($(
81             ast_enum_from_struct!($name::$variant, $member);
82         )*)*
83     };
84 }
85 
86 macro_rules! ast_enum_from_struct {
87     // No From<TokenStream> for verbatim variants.
88     ($name:ident::Verbatim, $member:ident) => {};
89 
90     ($name:ident::$variant:ident, $member:ident) => {
91         impl From<$member> for $name {
92             fn from(e: $member) -> $name {
93                 $name::$variant(e)
94             }
95         }
96     };
97 }
98 
99 #[cfg(feature = "printing")]
100 macro_rules! generate_to_tokens {
101     (
102         ($($arms:tt)*) $tokens:ident $name:ident {
103             $(#[cfg $cfg_attr:tt])*
104             $(#[doc $($doc_attr:tt)*])*
105             $variant:ident,
106             $($next:tt)*
107         }
108     ) => {
109         generate_to_tokens!(
110             ($($arms)* $(#[cfg $cfg_attr])* $name::$variant => {})
111             $tokens $name { $($next)* }
112         );
113     };
114 
115     (
116         ($($arms:tt)*) $tokens:ident $name:ident {
117             $(#[cfg $cfg_attr:tt])*
118             $(#[doc $($doc_attr:tt)*])*
119             $variant:ident($member:ident),
120             $($next:tt)*
121         }
122     ) => {
123         generate_to_tokens!(
124             ($($arms)* $(#[cfg $cfg_attr])* $name::$variant(_e) => _e.to_tokens($tokens),)
125             $tokens $name { $($next)* }
126         );
127     };
128 
129     (($($arms:tt)*) $tokens:ident $name:ident {}) => {
130         #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
131         impl ::quote::ToTokens for $name {
132             fn to_tokens(&self, $tokens: &mut ::proc_macro2::TokenStream) {
133                 match self {
134                     $($arms)*
135                 }
136             }
137         }
138     };
139 }
140 
141 // Rustdoc bug: does not respect the doc(hidden) on some items.
142 #[cfg(all(doc, feature = "parsing"))]
143 macro_rules! pub_if_not_doc {
144     ($(#[$m:meta])* $pub:ident $($item:tt)*) => {
145         check_keyword_matches!(pub $pub);
146 
147         $(#[$m])*
148         $pub(crate) $($item)*
149     };
150 }
151 
152 #[cfg(all(not(doc), feature = "parsing"))]
153 macro_rules! pub_if_not_doc {
154     ($(#[$m:meta])* $pub:ident $($item:tt)*) => {
155         check_keyword_matches!(pub $pub);
156 
157         $(#[$m])*
158         $pub $($item)*
159     };
160 }
161 
162 macro_rules! check_keyword_matches {
163     (enum enum) => {};
164     (pub pub) => {};
165     (struct struct) => {};
166 }
167 
168 #[cfg(any(feature = "full", feature = "derive"))]
169 macro_rules! return_impl_trait {
170     (
171         $(#[$attr:meta])*
172         $vis:vis fn $name:ident $args:tt -> $impl_trait:ty [$concrete:ty] $body:block
173     ) => {
174         #[cfg(not(docsrs))]
175         $(#[$attr])*
176         $vis fn $name $args -> $concrete $body
177 
178         #[cfg(docsrs)]
179         $(#[$attr])*
180         $vis fn $name $args -> $impl_trait $body
181     };
182 }
183