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