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