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