macros.rs 4.6 KB

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