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