blob: 004a93848775e1a31f717f994108aabada3b7ba3 [file] [log] [blame]
David Tolnay55535012018-01-05 16:39:23 -08001// Copyright 2018 Syn Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
David Tolnayf38cdf62016-09-23 19:07:09 -07009use super::*;
David Tolnayf2cfd722017-12-31 18:02:51 -050010use punctuated::Punctuated;
David Tolnayf38cdf62016-09-23 19:07:09 -070011
Alex Crichton62a0a592017-05-22 13:58:53 -070012ast_struct! {
13 /// An enum variant.
David Tolnay461d98e2018-01-07 11:07:19 -080014 ///
15 /// *This type is available if Syn is built with the `"derive"` or `"full"`
16 /// feature.*
Alex Crichton62a0a592017-05-22 13:58:53 -070017 pub struct Variant {
Alex Crichton62a0a592017-05-22 13:58:53 -070018 /// Attributes tagged on the variant.
19 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -050020
David Tolnay4a3f59a2017-12-28 21:21:12 -050021 /// Name of the variant.
22 pub ident: Ident,
23
David Tolnaye3d41b72017-12-31 15:24:00 -050024 /// Content stored in the variant.
25 pub fields: Fields,
Clar Charrd22b5702017-03-10 15:24:56 -050026
David Tolnay05658502018-01-07 09:56:37 -080027 /// Explicit discriminant: `Variant = 1`
David Tolnaye67902a2017-12-28 22:12:00 -050028 pub discriminant: Option<(Token![=], Expr)>,
Alex Crichton62a0a592017-05-22 13:58:53 -070029 }
David Tolnayf38cdf62016-09-23 19:07:09 -070030}
31
David Tolnaye3d41b72017-12-31 15:24:00 -050032ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -070033 /// Data stored within an enum variant or struct.
David Tolnay614a0142018-01-07 10:25:43 -080034 ///
David Tolnay461d98e2018-01-07 11:07:19 -080035 /// *This type is available if Syn is built with the `"derive"` or `"full"`
36 /// feature.*
37 ///
David Tolnay614a0142018-01-07 10:25:43 -080038 /// # Syntax tree enum
39 ///
40 /// This type is a [syntax tree enum].
41 ///
42 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
David Tolnaye3d41b72017-12-31 15:24:00 -050043 pub enum Fields {
44 /// Named fields of a struct or struct variant such as `Point { x: f64,
45 /// y: f64 }`.
David Tolnay461d98e2018-01-07 11:07:19 -080046 ///
47 /// *This type is available if Syn is built with the `"derive"` or
48 /// `"full"` feature.*
David Tolnaye3d41b72017-12-31 15:24:00 -050049 pub Named(FieldsNamed {
50 pub brace_token: token::Brace,
David Tolnaybdafb102018-01-01 19:39:10 -080051 pub named: Punctuated<Field, Token![,]>,
David Tolnaye3d41b72017-12-31 15:24:00 -050052 }),
Clar Charrd22b5702017-03-10 15:24:56 -050053
David Tolnaye3d41b72017-12-31 15:24:00 -050054 /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
David Tolnay461d98e2018-01-07 11:07:19 -080055 ///
56 /// *This type is available if Syn is built with the `"derive"` or
57 /// `"full"` feature.*
David Tolnaye3d41b72017-12-31 15:24:00 -050058 pub Unnamed(FieldsUnnamed {
59 pub paren_token: token::Paren,
David Tolnaybdafb102018-01-01 19:39:10 -080060 pub unnamed: Punctuated<Field, Token![,]>,
David Tolnaye3d41b72017-12-31 15:24:00 -050061 }),
Clar Charrd22b5702017-03-10 15:24:56 -050062
David Tolnaye3d41b72017-12-31 15:24:00 -050063 /// Unit struct or unit variant such as `None`.
64 pub Unit,
Alex Crichton62a0a592017-05-22 13:58:53 -070065 }
David Tolnayf38cdf62016-09-23 19:07:09 -070066}
67
Alex Crichton62a0a592017-05-22 13:58:53 -070068ast_struct! {
69 /// A field of a struct or enum variant.
David Tolnay461d98e2018-01-07 11:07:19 -080070 ///
71 /// *This type is available if Syn is built with the `"derive"` or `"full"`
72 /// feature.*
Alex Crichton62a0a592017-05-22 13:58:53 -070073 pub struct Field {
David Tolnay4a3f59a2017-12-28 21:21:12 -050074 /// Attributes tagged on the field.
75 pub attrs: Vec<Attribute>,
76
77 /// Visibility of the field.
78 pub vis: Visibility,
79
Alex Crichton62a0a592017-05-22 13:58:53 -070080 /// Name of the field, if any.
81 ///
82 /// Fields of tuple structs have no names.
83 pub ident: Option<Ident>,
Clar Charrd22b5702017-03-10 15:24:56 -050084
David Tolnay4a3f59a2017-12-28 21:21:12 -050085 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -050086
Alex Crichton62a0a592017-05-22 13:58:53 -070087 /// Type of the field.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080088 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -070089 }
David Tolnayf38cdf62016-09-23 19:07:09 -070090}
91
Alex Crichtonccbb45d2017-05-23 10:58:24 -070092ast_enum_of_structs! {
David Tolnay05658502018-01-07 09:56:37 -080093 /// The visibility level of an item: inherited or `pub` or
94 /// `pub(restricted)`.
David Tolnay614a0142018-01-07 10:25:43 -080095 ///
David Tolnay461d98e2018-01-07 11:07:19 -080096 /// *This type is available if Syn is built with the `"derive"` or `"full"`
97 /// feature.*
98 ///
David Tolnay614a0142018-01-07 10:25:43 -080099 /// # Syntax tree enum
100 ///
101 /// This type is a [syntax tree enum].
102 ///
103 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
Alex Crichton62a0a592017-05-22 13:58:53 -0700104 pub enum Visibility {
David Tolnay05658502018-01-07 09:56:37 -0800105 /// A public visibility level: `pub`.
David Tolnay461d98e2018-01-07 11:07:19 -0800106 ///
107 /// *This type is available if Syn is built with the `"derive"` or
108 /// `"full"` feature.*
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700109 pub Public(VisPublic {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800110 pub pub_token: Token![pub],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700111 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500112
David Tolnay05658502018-01-07 09:56:37 -0800113 /// A crate-level visibility: `pub(crate)`.
David Tolnay461d98e2018-01-07 11:07:19 -0800114 ///
115 /// *This type is available if Syn is built with the `"derive"` or
116 /// `"full"` feature.*
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700117 pub Crate(VisCrate {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800118 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -0500119 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800120 pub crate_token: Token![crate],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700121 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500122
David Tolnay05658502018-01-07 09:56:37 -0800123 /// A visibility level restricted to some path: `pub(self)` or
124 /// `pub(super)` or `pub(in some::module)`.
David Tolnay461d98e2018-01-07 11:07:19 -0800125 ///
126 /// *This type is available if Syn is built with the `"derive"` or
127 /// `"full"` feature.*
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700128 pub Restricted(VisRestricted {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800129 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -0500130 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800131 pub in_token: Option<Token![in]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700132 pub path: Box<Path>,
133 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500134
David Tolnay05658502018-01-07 09:56:37 -0800135 /// An inherited visibility, which usually means private.
David Tolnayfcfb9002017-12-28 22:04:29 -0500136 pub Inherited,
Alex Crichton62a0a592017-05-22 13:58:53 -0700137 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700138}
139
David Tolnayf38cdf62016-09-23 19:07:09 -0700140#[cfg(feature = "parsing")]
141pub mod parsing {
142 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700143
Michael Layzell92639a52017-06-01 00:07:44 -0400144 use synom::Synom;
David Tolnayf38cdf62016-09-23 19:07:09 -0700145
David Tolnaye3d41b72017-12-31 15:24:00 -0500146 impl Synom for Variant {
147 named!(parse -> Self, do_parse!(
148 attrs: many0!(Attribute::parse_outer) >>
149 id: syn!(Ident) >>
150 fields: alt!(
151 syn!(FieldsNamed) => { Fields::Named }
152 |
153 syn!(FieldsUnnamed) => { Fields::Unnamed }
154 |
155 epsilon!() => { |_| Fields::Unit }
156 ) >>
157 disr: option!(tuple!(punct!(=), syn!(Expr))) >>
158 (Variant {
159 ident: id,
160 attrs: attrs,
161 fields: fields,
162 discriminant: disr,
163 })
164 ));
165
166 fn description() -> Option<&'static str> {
167 Some("enum variant")
168 }
169 }
170
171 impl Synom for FieldsNamed {
172 named!(parse -> Self, map!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500173 braces!(call!(Punctuated::parse_terminated_with, Field::parse_named)),
David Tolnaye3d41b72017-12-31 15:24:00 -0500174 |(brace, fields)| FieldsNamed {
175 brace_token: brace,
David Tolnaybdafb102018-01-01 19:39:10 -0800176 named: fields,
David Tolnaye3d41b72017-12-31 15:24:00 -0500177 }
178 ));
David Tolnay79777332018-01-07 10:04:42 -0800179
180 fn description() -> Option<&'static str> {
181 Some("named fields in a struct or struct variant")
182 }
David Tolnaye3d41b72017-12-31 15:24:00 -0500183 }
184
185 impl Synom for FieldsUnnamed {
186 named!(parse -> Self, map!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500187 parens!(call!(Punctuated::parse_terminated_with, Field::parse_unnamed)),
David Tolnaye3d41b72017-12-31 15:24:00 -0500188 |(paren, fields)| FieldsUnnamed {
189 paren_token: paren,
David Tolnaybdafb102018-01-01 19:39:10 -0800190 unnamed: fields,
David Tolnaye3d41b72017-12-31 15:24:00 -0500191 }
192 ));
David Tolnay79777332018-01-07 10:04:42 -0800193
194 fn description() -> Option<&'static str> {
195 Some("unnamed fields in a tuple struct or tuple variant")
196 }
David Tolnaye3d41b72017-12-31 15:24:00 -0500197 }
198
Alex Crichton954046c2017-05-30 21:49:42 -0700199 impl Field {
David Tolnaye3d41b72017-12-31 15:24:00 -0500200 named!(pub parse_named -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500201 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400202 vis: syn!(Visibility) >>
203 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800204 colon: punct!(:) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800205 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400206 (Field {
207 ident: Some(id),
208 vis: vis,
209 attrs: attrs,
210 ty: ty,
211 colon_token: Some(colon),
212 })
213 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700214
David Tolnaye3d41b72017-12-31 15:24:00 -0500215 named!(pub parse_unnamed -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500216 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400217 vis: syn!(Visibility) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800218 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400219 (Field {
220 ident: None,
221 colon_token: None,
222 vis: vis,
223 attrs: attrs,
224 ty: ty,
225 })
226 ));
Michael Layzell416724e2017-05-24 21:12:34 -0400227 }
228
Alex Crichton954046c2017-05-30 21:49:42 -0700229 impl Synom for Visibility {
Michael Layzell92639a52017-06-01 00:07:44 -0400230 named!(parse -> Self, alt!(
231 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800232 pub_token: keyword!(pub) >>
233 other: parens!(keyword!(crate)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400234 (Visibility::Crate(VisCrate {
Michael Layzell92639a52017-06-01 00:07:44 -0400235 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500236 paren_token: other.0,
237 crate_token: other.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400238 }))
239 )
240 |
241 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800242 pub_token: keyword!(pub) >>
243 other: parens!(keyword!(self)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400244 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400245 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500246 paren_token: other.0,
247 in_token: None,
248 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400249 }))
250 )
251 |
252 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800253 pub_token: keyword!(pub) >>
254 other: parens!(keyword!(super)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400255 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400256 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500257 paren_token: other.0,
258 in_token: None,
259 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400260 }))
261 )
262 |
263 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800264 pub_token: keyword!(pub) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400265 other: parens!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800266 in_tok: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400267 restricted: call!(Path::parse_mod_style) >>
268 (in_tok, restricted)
269 )) >>
270 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400271 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500272 paren_token: other.0,
273 in_token: Some((other.1).0),
274 path: Box::new((other.1).1),
Michael Layzell92639a52017-06-01 00:07:44 -0400275 }))
276 )
277 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800278 keyword!(pub) => { |tok| {
Michael Layzell92639a52017-06-01 00:07:44 -0400279 Visibility::Public(VisPublic {
280 pub_token: tok,
281 })
282 } }
283 |
David Tolnayfcfb9002017-12-28 22:04:29 -0500284 epsilon!() => { |_| Visibility::Inherited }
Michael Layzell92639a52017-06-01 00:07:44 -0400285 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800286
287 fn description() -> Option<&'static str> {
David Tolnay05658502018-01-07 09:56:37 -0800288 Some("visibility qualifier such as `pub`")
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800289 }
Alex Crichton954046c2017-05-30 21:49:42 -0700290 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700291}
292
293#[cfg(feature = "printing")]
294mod printing {
295 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500296 use quote::{ToTokens, Tokens};
David Tolnayf38cdf62016-09-23 19:07:09 -0700297
298 impl ToTokens for Variant {
299 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700300 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700301 self.ident.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500302 self.fields.to_tokens(tokens);
David Tolnaye67902a2017-12-28 22:12:00 -0500303 if let Some((ref eq_token, ref disc)) = self.discriminant {
304 eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400305 disc.to_tokens(tokens);
306 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700307 }
308 }
309
David Tolnaye3d41b72017-12-31 15:24:00 -0500310 impl ToTokens for FieldsNamed {
David Tolnayf38cdf62016-09-23 19:07:09 -0700311 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye3d41b72017-12-31 15:24:00 -0500312 self.brace_token.surround(tokens, |tokens| {
David Tolnaybdafb102018-01-01 19:39:10 -0800313 self.named.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500314 });
315 }
316 }
317
318 impl ToTokens for FieldsUnnamed {
319 fn to_tokens(&self, tokens: &mut Tokens) {
320 self.paren_token.surround(tokens, |tokens| {
David Tolnaybdafb102018-01-01 19:39:10 -0800321 self.unnamed.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500322 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700323 }
324 }
325
326 impl ToTokens for Field {
327 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700328 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700329 self.vis.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400330 if let Some(ref ident) = self.ident {
331 ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -0700332 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400333 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700334 self.ty.to_tokens(tokens);
335 }
336 }
337
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700338 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700339 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700340 self.pub_token.to_tokens(tokens)
341 }
342 }
Arnaviond32b2942017-04-29 17:18:02 -0700343
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700344 impl ToTokens for VisCrate {
345 fn to_tokens(&self, tokens: &mut Tokens) {
346 self.pub_token.to_tokens(tokens);
347 self.paren_token.surround(tokens, |tokens| {
348 self.crate_token.to_tokens(tokens);
349 })
350 }
351 }
Arnaviond32b2942017-04-29 17:18:02 -0700352
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700353 impl ToTokens for VisRestricted {
354 fn to_tokens(&self, tokens: &mut Tokens) {
355 self.pub_token.to_tokens(tokens);
356 self.paren_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400357 // XXX: If we have a path which is not "self" or "super",
358 // automatically add the "in" token.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700359 self.in_token.to_tokens(tokens);
360 self.path.to_tokens(tokens);
361 });
362 }
363 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700364}