syn/
macros.rs

1#[cfg_attr(
2    not(any(feature = "full", feature = "derive")),
3    allow(unknown_lints, unused_macro_rules)
4)]
5macro_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"))]
41macro_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
53macro_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
70macro_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
86macro_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")]
100macro_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"))]
143macro_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"))]
153macro_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
162macro_rules! check_keyword_matches {
163    (enum enum) => {};
164    (pub pub) => {};
165    (struct struct) => {};
166}
167
168#[cfg(any(feature = "full", feature = "derive"))]
169macro_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}