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