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 | } |
66 | |
67 | macro_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 | |
96 | macro_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" )] |
110 | macro_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" ))] |
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(crate) $($item)* |
159 | }; |
160 | } |
161 | |
162 | #[cfg (all(not(doc), feature = "parsing" ))] |
163 | macro_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 | |
172 | macro_rules! check_keyword_matches { |
173 | (enum enum) => {}; |
174 | (pub pub) => {}; |
175 | (struct struct) => {}; |
176 | } |
177 | |