| 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 | #[cfg(feature = "printing" )] |
| 66 | generate_to_tokens!(() tokens $name $body); |
| 67 | }; |
| 68 | } |
| 69 | |
| 70 | macro_rules! ast_enum_of_structs_impl { |
| 71 | ( |
| 72 | $name:ident { |
| 73 | $( |
| 74 | $(#[cfg $cfg_attr:tt])* |
| 75 | $(#[doc $($doc_attr:tt)*])* |
| 76 | $variant:ident $( ($member:ident) )*, |
| 77 | )* |
| 78 | } |
| 79 | ) => { |
| 80 | $($( |
| 81 | ast_enum_from_struct!($name::$variant, $member); |
| 82 | )*)* |
| 83 | }; |
| 84 | } |
| 85 | |
| 86 | macro_rules! ast_enum_from_struct { |
| 87 | // No From<TokenStream> for verbatim variants. |
| 88 | ($name:ident::Verbatim, $member:ident) => {}; |
| 89 | |
| 90 | ($name:ident::$variant:ident, $member:ident) => { |
| 91 | impl From<$member> for $name { |
| 92 | fn from(e: $member) -> $name { |
| 93 | $name::$variant(e) |
| 94 | } |
| 95 | } |
| 96 | }; |
| 97 | } |
| 98 | |
| 99 | #[cfg (feature = "printing" )] |
| 100 | macro_rules! generate_to_tokens { |
| 101 | ( |
| 102 | ($($arms:tt)*) $tokens:ident $name:ident { |
| 103 | $(#[cfg $cfg_attr:tt])* |
| 104 | $(#[doc $($doc_attr:tt)*])* |
| 105 | $variant:ident, |
| 106 | $($next:tt)* |
| 107 | } |
| 108 | ) => { |
| 109 | generate_to_tokens!( |
| 110 | ($($arms)* $(#[cfg $cfg_attr])* $name::$variant => {}) |
| 111 | $tokens $name { $($next)* } |
| 112 | ); |
| 113 | }; |
| 114 | |
| 115 | ( |
| 116 | ($($arms:tt)*) $tokens:ident $name:ident { |
| 117 | $(#[cfg $cfg_attr:tt])* |
| 118 | $(#[doc $($doc_attr:tt)*])* |
| 119 | $variant:ident($member:ident), |
| 120 | $($next:tt)* |
| 121 | } |
| 122 | ) => { |
| 123 | generate_to_tokens!( |
| 124 | ($($arms)* $(#[cfg $cfg_attr])* $name::$variant(_e) => _e.to_tokens($tokens),) |
| 125 | $tokens $name { $($next)* } |
| 126 | ); |
| 127 | }; |
| 128 | |
| 129 | (($($arms:tt)*) $tokens:ident $name:ident {}) => { |
| 130 | #[cfg_attr(docsrs, doc(cfg(feature = "printing" )))] |
| 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 | // Rustdoc bug: does not respect the doc(hidden) on some items. |
| 142 | #[cfg (all(doc, feature = "parsing" ))] |
| 143 | macro_rules! pub_if_not_doc { |
| 144 | ($(#[$m:meta])* $pub:ident $($item:tt)*) => { |
| 145 | check_keyword_matches!(pub $pub); |
| 146 | |
| 147 | $(#[$m])* |
| 148 | $pub(crate) $($item)* |
| 149 | }; |
| 150 | } |
| 151 | |
| 152 | #[cfg (all(not(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 $($item)* |
| 159 | }; |
| 160 | } |
| 161 | |
| 162 | macro_rules! check_keyword_matches { |
| 163 | (enum enum) => {}; |
| 164 | (pub pub) => {}; |
| 165 | (struct struct) => {}; |
| 166 | } |
| 167 | |
| 168 | #[cfg (any(feature = "full" , feature = "derive" ))] |
| 169 | macro_rules! return_impl_trait { |
| 170 | ( |
| 171 | $(#[$attr:meta])* |
| 172 | $vis:vis fn $name:ident $args:tt -> $impl_trait:ty [$concrete:ty] $body:block |
| 173 | ) => { |
| 174 | #[cfg(not(docsrs))] |
| 175 | $(#[$attr])* |
| 176 | $vis fn $name $args -> $concrete $body |
| 177 | |
| 178 | #[cfg(docsrs)] |
| 179 | $(#[$attr])* |
| 180 | $vis fn $name $args -> $impl_trait $body |
| 181 | }; |
| 182 | } |
| 183 | |