blob: 439a21c7265e033f2352ea729619dee60d4f2bec [file] [log] [blame]
David Tolnayf38cdf62016-09-23 19:07:09 -07001use super::*;
David Tolnayf2cfd722017-12-31 18:02:51 -05002use punctuated::Punctuated;
David Tolnayf38cdf62016-09-23 19:07:09 -07003
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_struct! {
5 /// An enum variant.
6 pub struct Variant {
Alex Crichton62a0a592017-05-22 13:58:53 -07007 /// Attributes tagged on the variant.
8 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -05009
David Tolnay4a3f59a2017-12-28 21:21:12 -050010 /// Name of the variant.
11 pub ident: Ident,
12
David Tolnaye3d41b72017-12-31 15:24:00 -050013 /// Content stored in the variant.
14 pub fields: Fields,
Clar Charrd22b5702017-03-10 15:24:56 -050015
Alex Crichton62a0a592017-05-22 13:58:53 -070016 /// Explicit discriminant, e.g. `Foo = 1`
David Tolnaye67902a2017-12-28 22:12:00 -050017 pub discriminant: Option<(Token![=], Expr)>,
Alex Crichton62a0a592017-05-22 13:58:53 -070018 }
David Tolnayf38cdf62016-09-23 19:07:09 -070019}
20
David Tolnaye3d41b72017-12-31 15:24:00 -050021ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -070022 /// Data stored within an enum variant or struct.
David Tolnaye3d41b72017-12-31 15:24:00 -050023 pub enum Fields {
24 /// Named fields of a struct or struct variant such as `Point { x: f64,
25 /// y: f64 }`.
26 pub Named(FieldsNamed {
27 pub brace_token: token::Brace,
David Tolnaybdafb102018-01-01 19:39:10 -080028 pub named: Punctuated<Field, Token![,]>,
David Tolnaye3d41b72017-12-31 15:24:00 -050029 }),
Clar Charrd22b5702017-03-10 15:24:56 -050030
David Tolnaye3d41b72017-12-31 15:24:00 -050031 /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
32 pub Unnamed(FieldsUnnamed {
33 pub paren_token: token::Paren,
David Tolnaybdafb102018-01-01 19:39:10 -080034 pub unnamed: Punctuated<Field, Token![,]>,
David Tolnaye3d41b72017-12-31 15:24:00 -050035 }),
Clar Charrd22b5702017-03-10 15:24:56 -050036
David Tolnaye3d41b72017-12-31 15:24:00 -050037 /// Unit struct or unit variant such as `None`.
38 pub Unit,
Alex Crichton62a0a592017-05-22 13:58:53 -070039 }
David Tolnayf38cdf62016-09-23 19:07:09 -070040}
41
Alex Crichton62a0a592017-05-22 13:58:53 -070042ast_struct! {
43 /// A field of a struct or enum variant.
44 pub struct Field {
David Tolnay4a3f59a2017-12-28 21:21:12 -050045 /// Attributes tagged on the field.
46 pub attrs: Vec<Attribute>,
47
48 /// Visibility of the field.
49 pub vis: Visibility,
50
Alex Crichton62a0a592017-05-22 13:58:53 -070051 /// Name of the field, if any.
52 ///
53 /// Fields of tuple structs have no names.
54 pub ident: Option<Ident>,
Clar Charrd22b5702017-03-10 15:24:56 -050055
David Tolnay4a3f59a2017-12-28 21:21:12 -050056 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -050057
Alex Crichton62a0a592017-05-22 13:58:53 -070058 /// Type of the field.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080059 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -070060 }
David Tolnayf38cdf62016-09-23 19:07:09 -070061}
62
Alex Crichtonccbb45d2017-05-23 10:58:24 -070063ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -070064 /// Visibility level of an item.
65 pub enum Visibility {
66 /// Public, i.e. `pub`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070067 pub Public(VisPublic {
David Tolnayf8db7ba2017-11-11 22:52:16 -080068 pub pub_token: Token![pub],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070069 }),
Clar Charrd22b5702017-03-10 15:24:56 -050070
Alex Crichton62a0a592017-05-22 13:58:53 -070071 /// Crate-visible, i.e. `pub(crate)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070072 pub Crate(VisCrate {
David Tolnayf8db7ba2017-11-11 22:52:16 -080073 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050074 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080075 pub crate_token: Token![crate],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070076 }),
Clar Charrd22b5702017-03-10 15:24:56 -050077
Alex Crichton62a0a592017-05-22 13:58:53 -070078 /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070079 pub Restricted(VisRestricted {
David Tolnayf8db7ba2017-11-11 22:52:16 -080080 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050081 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080082 pub in_token: Option<Token![in]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070083 pub path: Box<Path>,
84 }),
Clar Charrd22b5702017-03-10 15:24:56 -050085
Alex Crichton62a0a592017-05-22 13:58:53 -070086 /// Inherited, i.e. private.
David Tolnayfcfb9002017-12-28 22:04:29 -050087 pub Inherited,
Alex Crichton62a0a592017-05-22 13:58:53 -070088 }
David Tolnayf38cdf62016-09-23 19:07:09 -070089}
90
David Tolnayf38cdf62016-09-23 19:07:09 -070091#[cfg(feature = "parsing")]
92pub mod parsing {
93 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -070094
Michael Layzell92639a52017-06-01 00:07:44 -040095 use synom::Synom;
David Tolnayf38cdf62016-09-23 19:07:09 -070096
David Tolnaye3d41b72017-12-31 15:24:00 -050097 impl Synom for Variant {
98 named!(parse -> Self, do_parse!(
99 attrs: many0!(Attribute::parse_outer) >>
100 id: syn!(Ident) >>
101 fields: alt!(
102 syn!(FieldsNamed) => { Fields::Named }
103 |
104 syn!(FieldsUnnamed) => { Fields::Unnamed }
105 |
106 epsilon!() => { |_| Fields::Unit }
107 ) >>
108 disr: option!(tuple!(punct!(=), syn!(Expr))) >>
109 (Variant {
110 ident: id,
111 attrs: attrs,
112 fields: fields,
113 discriminant: disr,
114 })
115 ));
116
117 fn description() -> Option<&'static str> {
118 Some("enum variant")
119 }
120 }
121
122 impl Synom for FieldsNamed {
123 named!(parse -> Self, map!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500124 braces!(call!(Punctuated::parse_terminated_with, Field::parse_named)),
David Tolnaye3d41b72017-12-31 15:24:00 -0500125 |(brace, fields)| FieldsNamed {
126 brace_token: brace,
David Tolnaybdafb102018-01-01 19:39:10 -0800127 named: fields,
David Tolnaye3d41b72017-12-31 15:24:00 -0500128 }
129 ));
130 }
131
132 impl Synom for FieldsUnnamed {
133 named!(parse -> Self, map!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500134 parens!(call!(Punctuated::parse_terminated_with, Field::parse_unnamed)),
David Tolnaye3d41b72017-12-31 15:24:00 -0500135 |(paren, fields)| FieldsUnnamed {
136 paren_token: paren,
David Tolnaybdafb102018-01-01 19:39:10 -0800137 unnamed: fields,
David Tolnaye3d41b72017-12-31 15:24:00 -0500138 }
139 ));
140 }
141
Alex Crichton954046c2017-05-30 21:49:42 -0700142 impl Field {
David Tolnaye3d41b72017-12-31 15:24:00 -0500143 named!(pub parse_named -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500144 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400145 vis: syn!(Visibility) >>
146 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800147 colon: punct!(:) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800148 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400149 (Field {
150 ident: Some(id),
151 vis: vis,
152 attrs: attrs,
153 ty: ty,
154 colon_token: Some(colon),
155 })
156 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700157
David Tolnaye3d41b72017-12-31 15:24:00 -0500158 named!(pub parse_unnamed -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500159 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400160 vis: syn!(Visibility) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800161 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400162 (Field {
163 ident: None,
164 colon_token: None,
165 vis: vis,
166 attrs: attrs,
167 ty: ty,
168 })
169 ));
Michael Layzell416724e2017-05-24 21:12:34 -0400170 }
171
Alex Crichton954046c2017-05-30 21:49:42 -0700172 impl Synom for Visibility {
Michael Layzell92639a52017-06-01 00:07:44 -0400173 named!(parse -> Self, alt!(
174 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800175 pub_token: keyword!(pub) >>
176 other: parens!(keyword!(crate)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400177 (Visibility::Crate(VisCrate {
Michael Layzell92639a52017-06-01 00:07:44 -0400178 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500179 paren_token: other.0,
180 crate_token: other.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400181 }))
182 )
183 |
184 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800185 pub_token: keyword!(pub) >>
186 other: parens!(keyword!(self)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400187 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400188 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500189 paren_token: other.0,
190 in_token: None,
191 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400192 }))
193 )
194 |
195 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800196 pub_token: keyword!(pub) >>
197 other: parens!(keyword!(super)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400198 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400199 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500200 paren_token: other.0,
201 in_token: None,
202 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400203 }))
204 )
205 |
206 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800207 pub_token: keyword!(pub) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400208 other: parens!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800209 in_tok: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400210 restricted: call!(Path::parse_mod_style) >>
211 (in_tok, restricted)
212 )) >>
213 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400214 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500215 paren_token: other.0,
216 in_token: Some((other.1).0),
217 path: Box::new((other.1).1),
Michael Layzell92639a52017-06-01 00:07:44 -0400218 }))
219 )
220 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800221 keyword!(pub) => { |tok| {
Michael Layzell92639a52017-06-01 00:07:44 -0400222 Visibility::Public(VisPublic {
223 pub_token: tok,
224 })
225 } }
226 |
David Tolnayfcfb9002017-12-28 22:04:29 -0500227 epsilon!() => { |_| Visibility::Inherited }
Michael Layzell92639a52017-06-01 00:07:44 -0400228 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800229
230 fn description() -> Option<&'static str> {
231 Some("visibility qualifier, e.g. `pub`")
232 }
Alex Crichton954046c2017-05-30 21:49:42 -0700233 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700234}
235
236#[cfg(feature = "printing")]
237mod printing {
238 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500239 use quote::{ToTokens, Tokens};
David Tolnayf38cdf62016-09-23 19:07:09 -0700240
241 impl ToTokens for Variant {
242 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700243 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700244 self.ident.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500245 self.fields.to_tokens(tokens);
David Tolnaye67902a2017-12-28 22:12:00 -0500246 if let Some((ref eq_token, ref disc)) = self.discriminant {
247 eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400248 disc.to_tokens(tokens);
249 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700250 }
251 }
252
David Tolnaye3d41b72017-12-31 15:24:00 -0500253 impl ToTokens for FieldsNamed {
David Tolnayf38cdf62016-09-23 19:07:09 -0700254 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye3d41b72017-12-31 15:24:00 -0500255 self.brace_token.surround(tokens, |tokens| {
David Tolnaybdafb102018-01-01 19:39:10 -0800256 self.named.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500257 });
258 }
259 }
260
261 impl ToTokens for FieldsUnnamed {
262 fn to_tokens(&self, tokens: &mut Tokens) {
263 self.paren_token.surround(tokens, |tokens| {
David Tolnaybdafb102018-01-01 19:39:10 -0800264 self.unnamed.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500265 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700266 }
267 }
268
269 impl ToTokens for Field {
270 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700271 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700272 self.vis.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400273 if let Some(ref ident) = self.ident {
274 ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -0700275 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400276 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700277 self.ty.to_tokens(tokens);
278 }
279 }
280
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700281 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700282 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700283 self.pub_token.to_tokens(tokens)
284 }
285 }
Arnaviond32b2942017-04-29 17:18:02 -0700286
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700287 impl ToTokens for VisCrate {
288 fn to_tokens(&self, tokens: &mut Tokens) {
289 self.pub_token.to_tokens(tokens);
290 self.paren_token.surround(tokens, |tokens| {
291 self.crate_token.to_tokens(tokens);
292 })
293 }
294 }
Arnaviond32b2942017-04-29 17:18:02 -0700295
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700296 impl ToTokens for VisRestricted {
297 fn to_tokens(&self, tokens: &mut Tokens) {
298 self.pub_token.to_tokens(tokens);
299 self.paren_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400300 // XXX: If we have a path which is not "self" or "super",
301 // automatically add the "in" token.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700302 self.in_token.to_tokens(tokens);
303 self.path.to_tokens(tokens);
304 });
305 }
306 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700307}