Skip to main content

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: ::core::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        #[cfg(feature = "printing")]
64        generate_to_tokens!(() tokens $name $body);
65    };
66}
67
68#[cfg(feature = "printing")]
69macro_rules! generate_to_tokens {
70    (
71        ($($arms:tt)*) $tokens:ident $name:ident {
72            $(#[doc $($doc_attr:tt)*])*
73            $(#[cfg_attr $cfg_attr:tt])*
74            $variant:ident,
75            $($next:tt)*
76        }
77    ) => {
78        generate_to_tokens!(
79            ($($arms)* $name::$variant => {})
80            $tokens $name { $($next)* }
81        );
82    };
83
84    (
85        ($($arms:tt)*) $tokens:ident $name:ident {
86            $(#[doc $($doc_attr:tt)*])*
87            $(#[cfg_attr $cfg_attr:tt])*
88            $variant:ident($member:ident),
89            $($next:tt)*
90        }
91    ) => {
92        generate_to_tokens!(
93            ($($arms)* $name::$variant(_e) => _e.to_tokens($tokens),)
94            $tokens $name { $($next)* }
95        );
96    };
97
98    (($($arms:tt)*) $tokens:ident $name:ident {}) => {
99        #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
100        impl ::quote::ToTokens for $name {
101            fn to_tokens(&self, $tokens: &mut ::proc_macro2::TokenStream) {
102                match self {
103                    $($arms)*
104                }
105            }
106        }
107    };
108}
109
110// Rustdoc bug: does not respect the doc(hidden) on some items.
111#[cfg(all(doc, feature = "parsing"))]
112macro_rules! pub_if_not_doc {
113    ($(#[$m:meta])* $pub:ident $($item:tt)*) => {
114        check_keyword_matches!(pub $pub);
115
116        $(#[$m])*
117        $pub(crate) $($item)*
118    };
119}
120
121#[cfg(all(not(doc), feature = "parsing"))]
122macro_rules! pub_if_not_doc {
123    ($(#[$m:meta])* $pub:ident $($item:tt)*) => {
124        check_keyword_matches!(pub $pub);
125
126        $(#[$m])*
127        $pub $($item)*
128    };
129}
130
131macro_rules! check_keyword_matches {
132    (enum enum) => {};
133    (pub pub) => {};
134    (struct struct) => {};
135}
136
137#[cfg(any(feature = "full", feature = "derive"))]
138macro_rules! return_impl_trait {
139    (
140        $(#[$attr:meta])*
141        $vis:vis fn $name:ident $args:tt -> $impl_trait:ty [$concrete:ty] $body:block
142    ) => {
143        #[cfg(not(docsrs))]
144        $(#[$attr])*
145        $vis fn $name $args -> $concrete $body
146
147        #[cfg(docsrs)]
148        $(#[$attr])*
149        $vis fn $name $args -> $impl_trait $body
150    };
151}