syn_pub_items/
macros.rs

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    // If the variant is marked as #full, don't auto-generate to-tokens for it.
153    ($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}