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