1#[cfg(any(feature = "full", feature = "derive"))]
2#[macro_export]
3macro_rules! ast_struct {
4 (
5 $(#[$attr:meta])*
6 pub struct $name:ident #full $($rest:tt)*
7 ) => {
8 #[cfg(feature = "full")]
9 $(#[$attr])*
10 #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
11 #[cfg_attr(feature = "clone-impls", derive(Clone))]
12 pub struct $name $($rest)*
13
14 #[cfg(not(feature = "full"))]
15 $(#[$attr])*
16 #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
17 #[cfg_attr(feature = "clone-impls", derive(Clone))]
18 pub struct $name {
19 _noconstruct: (),
20 }
21 };
22
23 (
24 $(#[$attr:meta])*
25 pub struct $name:ident #manual_extra_traits $($rest:tt)*
26 ) => {
27 $(#[$attr])*
28 #[cfg_attr(feature = "extra-traits", derive(Debug))]
29 #[cfg_attr(feature = "clone-impls", derive(Clone))]
30 pub struct $name $($rest)*
31 };
32
33 (
34 $(#[$attr:meta])*
35 pub struct $name:ident $($rest:tt)*
36 ) => {
37 $(#[$attr])*
38 #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
39 #[cfg_attr(feature = "clone-impls", derive(Clone))]
40 pub struct $name $($rest)*
41 };
42}
43
44#[cfg(any(feature = "full", feature = "derive"))]
45#[macro_export]
46macro_rules! ast_enum {
47 (
48 $(#[$enum_attr:meta])*
49 pub enum $name:ident $(# $tags:ident)* { $($variants:tt)* }
50 ) => (
51 $(#[$enum_attr])*
52 #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
53 #[cfg_attr(feature = "clone-impls", derive(Clone))]
54 pub enum $name {
55 $($variants)*
56 }
57 )
58}
59
60#[cfg(any(feature = "full", feature = "derive"))]
61#[macro_export]
62macro_rules! ast_enum_of_structs {
63 (
64 $(#[$enum_attr:meta])*
65 pub enum $name:ident {
66 $(
67 $(#[$variant_attr:meta])*
68 pub $variant:ident $( ($member:ident $($rest:tt)*) )*,
69 )*
70 }
71
72 $($remaining:tt)*
73 ) => (
74 ast_enum! {
75 $(#[$enum_attr])*
76 pub enum $name {
77 $(
78 $(#[$variant_attr])*
79 $variant $( ($member) )*,
80 )*
81 }
82 }
83
84 $(
85 maybe_ast_struct! {
86 $(#[$variant_attr])*
87 $(
88 pub struct $member $($rest)*
89 )*
90 }
91
92 $(
93 impl From<$member> for $name {
94 fn from(e: $member) -> $name {
95 $name::$variant(e)
96 }
97 }
98 )*
99 )*
100
101 #[cfg(feature = "printing")]
102 generate_to_tokens! {
103 $($remaining)*
104 ()
105 tokens
106 $name { $($variant $( [$($rest)*] )*,)* }
107 }
108 )
109}
110
111#[cfg(all(feature = "printing", any(feature = "full", feature = "derive")))]
112#[macro_export]
113macro_rules! generate_to_tokens {
114 (do_not_generate_to_tokens $($foo:tt)*) => ();
115
116 (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident, $($next:tt)*}) => {
117 generate_to_tokens!(
118 ($($arms)* $name::$variant => {})
119 $tokens $name { $($next)* }
120 );
121 };
122
123 (($($arms:tt)*) $tokens:ident $name:ident { $variant:ident [$($rest:tt)*], $($next:tt)*}) => {
124 generate_to_tokens!(
125 ($($arms)* $name::$variant(ref _e) => to_tokens_call!(_e, $tokens, $($rest)*),)
126 $tokens $name { $($next)* }
127 );
128 };
129
130 (($($arms:tt)*) $tokens:ident $name:ident {}) => {
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#[cfg(all(feature = "printing", feature = "full"))]
142#[macro_export]
143macro_rules! to_tokens_call {
144 ($e:ident, $tokens:ident, $($rest:tt)*) => {
145 $e.to_tokens($tokens)
146 };
147}
148
149#[cfg(all(feature = "printing", feature = "derive", not(feature = "full")))]
150#[macro_export]
151macro_rules! to_tokens_call {
152 ($e:ident, $tokens:ident, #full $($rest:tt)*) => {
154 unreachable!()
155 };
156 ($e:ident, $tokens:ident, $($rest:tt)*) => {
157 $e.to_tokens($tokens)
158 };
159}
160
161#[cfg(any(feature = "full", feature = "derive"))]
162#[macro_export]
163macro_rules! maybe_ast_struct {
164 (
165 $(#[$attr:meta])*
166 $(
167 pub struct $name:ident
168 )*
169 ) => ();
170
171 ($($rest:tt)*) => (ast_struct! { $($rest)* });
172}