1 #[cfg_attr( 2 not(any(feature = "full", feature = "derive")), 3 allow(unknown_lints, unused_macro_rules) 4 )] 5 macro_rules! ast_struct { 6 ( 7 [$($attrs_pub:tt)*] 8 struct $name:ident #full $($rest:tt)* 9 ) => { 10 #[cfg(feature = "full")] 11 $($attrs_pub)* struct $name $($rest)* 12 13 #[cfg(not(feature = "full"))] 14 $($attrs_pub)* struct $name { 15 _noconstruct: ::std::marker::PhantomData<::proc_macro2::Span>, 16 } 17 18 #[cfg(all(not(feature = "full"), feature = "printing"))] 19 impl ::quote::ToTokens for $name { 20 fn to_tokens(&self, _: &mut ::proc_macro2::TokenStream) { 21 unreachable!() 22 } 23 } 24 }; 25 26 ( 27 [$($attrs_pub:tt)*] 28 struct $name:ident $($rest:tt)* 29 ) => { 30 $($attrs_pub)* struct $name $($rest)* 31 }; 32 33 ($($t:tt)*) => { 34 strip_attrs_pub!(ast_struct!($($t)*)); 35 }; 36 } 37 38 macro_rules! ast_enum { 39 // Drop the `#no_visit` attribute, if present. 40 ( 41 [$($attrs_pub:tt)*] 42 enum $name:ident #no_visit $($rest:tt)* 43 ) => ( 44 ast_enum!([$($attrs_pub)*] enum $name $($rest)*); 45 ); 46 47 ( 48 [$($attrs_pub:tt)*] 49 enum $name:ident $($rest:tt)* 50 ) => ( 51 $($attrs_pub)* enum $name $($rest)* 52 ); 53 54 ($($t:tt)*) => { 55 strip_attrs_pub!(ast_enum!($($t)*)); 56 }; 57 } 58 59 macro_rules! ast_enum_of_structs { 60 ( 61 $(#[$enum_attr:meta])* 62 $pub:ident $enum:ident $name:ident $body:tt 63 $($remaining:tt)* 64 ) => { 65 ast_enum!($(#[$enum_attr])* $pub $enum $name $body); 66 ast_enum_of_structs_impl!($pub $enum $name $body $($remaining)*); 67 }; 68 } 69 70 macro_rules! ast_enum_of_structs_impl { 71 ( 72 $pub:ident $enum:ident $name:ident { 73 $( 74 $(#[cfg $cfg_attr:tt])* 75 $(#[doc $($doc_attr:tt)*])* 76 $variant:ident $( ($($member:ident)::+) )*, 77 )* 78 } 79 80 $($remaining:tt)* 81 ) => { 82 check_keyword_matches!(pub $pub); 83 check_keyword_matches!(enum $enum); 84 85 $($( 86 ast_enum_from_struct!($name::$variant, $($member)::+); 87 )*)* 88 89 #[cfg(feature = "printing")] 90 generate_to_tokens! { 91 $($remaining)* 92 () 93 tokens 94 $name { 95 $( 96 $(#[cfg $cfg_attr])* 97 $(#[doc $($doc_attr)*])* 98 $variant $($($member)::+)*, 99 )* 100 } 101 } 102 }; 103 } 104 105 macro_rules! ast_enum_from_struct { 106 // No From<TokenStream> for verbatim variants. 107 ($name:ident::Verbatim, $member:ident) => {}; 108 109 ($name:ident::$variant:ident, $member:ident) => { 110 impl From<$member> for $name { 111 fn from(e: $member) -> $name { 112 $name::$variant(e) 113 } 114 } 115 }; 116 } 117 118 #[cfg(feature = "printing")] 119 #[cfg_attr( 120 not(any(feature = "full", feature = "derive")), 121 allow(unknown_lints, unused_macro_rules) 122 )] 123 macro_rules! generate_to_tokens { 124 (do_not_generate_to_tokens $($foo:tt)*) => (); 125 126 ( 127 ($($arms:tt)*) $tokens:ident $name:ident { 128 $(#[cfg $cfg_attr:tt])* 129 $(#[doc $($doc_attr:tt)*])* 130 $variant:ident, 131 $($next:tt)* 132 } 133 ) => { 134 generate_to_tokens!( 135 ($($arms)* $(#[cfg $cfg_attr])* $name::$variant => {}) 136 $tokens $name { $($next)* } 137 ); 138 }; 139 140 ( 141 ($($arms:tt)*) $tokens:ident $name:ident { 142 $(#[cfg $cfg_attr:tt])* 143 $(#[doc $($doc_attr:tt)*])* 144 $variant:ident $member:ident, 145 $($next:tt)* 146 } 147 ) => { 148 generate_to_tokens!( 149 ($($arms)* $(#[cfg $cfg_attr])* $name::$variant(_e) => _e.to_tokens($tokens),) 150 $tokens $name { $($next)* } 151 ); 152 }; 153 154 (($($arms:tt)*) $tokens:ident $name:ident {}) => { 155 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 156 impl ::quote::ToTokens for $name { 157 fn to_tokens(&self, $tokens: &mut ::proc_macro2::TokenStream) { 158 match self { 159 $($arms)* 160 } 161 } 162 } 163 }; 164 } 165 166 macro_rules! strip_attrs_pub { 167 ($mac:ident!($(#[$m:meta])* $pub:ident $($t:tt)*)) => { 168 check_keyword_matches!(pub $pub); 169 170 $mac!([$(#[$m])* $pub] $($t)*); 171 }; 172 } 173 174 macro_rules! check_keyword_matches { 175 (enum enum) => {}; 176 (pub pub) => {}; 177 } 178