blob: 77dc725142b094b00ebdb5985635947285adcb29 [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.
14 pub struct Variant {
Alex Crichton62a0a592017-05-22 13:58:53 -070015 /// Attributes tagged on the variant.
16 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -050017
David Tolnay4a3f59a2017-12-28 21:21:12 -050018 /// Name of the variant.
19 pub ident: Ident,
20
David Tolnaye3d41b72017-12-31 15:24:00 -050021 /// Content stored in the variant.
22 pub fields: Fields,
Clar Charrd22b5702017-03-10 15:24:56 -050023
David Tolnay05658502018-01-07 09:56:37 -080024 /// Explicit discriminant: `Variant = 1`
David Tolnaye67902a2017-12-28 22:12:00 -050025 pub discriminant: Option<(Token![=], Expr)>,
Alex Crichton62a0a592017-05-22 13:58:53 -070026 }
David Tolnayf38cdf62016-09-23 19:07:09 -070027}
28
David Tolnaye3d41b72017-12-31 15:24:00 -050029ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -070030 /// Data stored within an enum variant or struct.
David Tolnay614a0142018-01-07 10:25:43 -080031 ///
32 /// # Syntax tree enum
33 ///
34 /// This type is a [syntax tree enum].
35 ///
36 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
David Tolnaye3d41b72017-12-31 15:24:00 -050037 pub enum Fields {
38 /// Named fields of a struct or struct variant such as `Point { x: f64,
39 /// y: f64 }`.
40 pub Named(FieldsNamed {
41 pub brace_token: token::Brace,
David Tolnaybdafb102018-01-01 19:39:10 -080042 pub named: Punctuated<Field, Token![,]>,
David Tolnaye3d41b72017-12-31 15:24:00 -050043 }),
Clar Charrd22b5702017-03-10 15:24:56 -050044
David Tolnaye3d41b72017-12-31 15:24:00 -050045 /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
46 pub Unnamed(FieldsUnnamed {
47 pub paren_token: token::Paren,
David Tolnaybdafb102018-01-01 19:39:10 -080048 pub unnamed: Punctuated<Field, Token![,]>,
David Tolnaye3d41b72017-12-31 15:24:00 -050049 }),
Clar Charrd22b5702017-03-10 15:24:56 -050050
David Tolnaye3d41b72017-12-31 15:24:00 -050051 /// Unit struct or unit variant such as `None`.
52 pub Unit,
Alex Crichton62a0a592017-05-22 13:58:53 -070053 }
David Tolnayf38cdf62016-09-23 19:07:09 -070054}
55
Alex Crichton62a0a592017-05-22 13:58:53 -070056ast_struct! {
57 /// A field of a struct or enum variant.
58 pub struct Field {
David Tolnay4a3f59a2017-12-28 21:21:12 -050059 /// Attributes tagged on the field.
60 pub attrs: Vec<Attribute>,
61
62 /// Visibility of the field.
63 pub vis: Visibility,
64
Alex Crichton62a0a592017-05-22 13:58:53 -070065 /// Name of the field, if any.
66 ///
67 /// Fields of tuple structs have no names.
68 pub ident: Option<Ident>,
Clar Charrd22b5702017-03-10 15:24:56 -050069
David Tolnay4a3f59a2017-12-28 21:21:12 -050070 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -050071
Alex Crichton62a0a592017-05-22 13:58:53 -070072 /// Type of the field.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080073 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -070074 }
David Tolnayf38cdf62016-09-23 19:07:09 -070075}
76
Alex Crichtonccbb45d2017-05-23 10:58:24 -070077ast_enum_of_structs! {
David Tolnay05658502018-01-07 09:56:37 -080078 /// The visibility level of an item: inherited or `pub` or
79 /// `pub(restricted)`.
David Tolnay614a0142018-01-07 10:25:43 -080080 ///
81 /// # Syntax tree enum
82 ///
83 /// This type is a [syntax tree enum].
84 ///
85 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
Alex Crichton62a0a592017-05-22 13:58:53 -070086 pub enum Visibility {
David Tolnay05658502018-01-07 09:56:37 -080087 /// A public visibility level: `pub`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070088 pub Public(VisPublic {
David Tolnayf8db7ba2017-11-11 22:52:16 -080089 pub pub_token: Token![pub],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070090 }),
Clar Charrd22b5702017-03-10 15:24:56 -050091
David Tolnay05658502018-01-07 09:56:37 -080092 /// A crate-level visibility: `pub(crate)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070093 pub Crate(VisCrate {
David Tolnayf8db7ba2017-11-11 22:52:16 -080094 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050095 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080096 pub crate_token: Token![crate],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070097 }),
Clar Charrd22b5702017-03-10 15:24:56 -050098
David Tolnay05658502018-01-07 09:56:37 -080099 /// A visibility level restricted to some path: `pub(self)` or
100 /// `pub(super)` or `pub(in some::module)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700101 pub Restricted(VisRestricted {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800102 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -0500103 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800104 pub in_token: Option<Token![in]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700105 pub path: Box<Path>,
106 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500107
David Tolnay05658502018-01-07 09:56:37 -0800108 /// An inherited visibility, which usually means private.
David Tolnayfcfb9002017-12-28 22:04:29 -0500109 pub Inherited,
Alex Crichton62a0a592017-05-22 13:58:53 -0700110 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700111}
112
David Tolnayf38cdf62016-09-23 19:07:09 -0700113#[cfg(feature = "parsing")]
114pub mod parsing {
115 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700116
Michael Layzell92639a52017-06-01 00:07:44 -0400117 use synom::Synom;
David Tolnayf38cdf62016-09-23 19:07:09 -0700118
David Tolnaye3d41b72017-12-31 15:24:00 -0500119 impl Synom for Variant {
120 named!(parse -> Self, do_parse!(
121 attrs: many0!(Attribute::parse_outer) >>
122 id: syn!(Ident) >>
123 fields: alt!(
124 syn!(FieldsNamed) => { Fields::Named }
125 |
126 syn!(FieldsUnnamed) => { Fields::Unnamed }
127 |
128 epsilon!() => { |_| Fields::Unit }
129 ) >>
130 disr: option!(tuple!(punct!(=), syn!(Expr))) >>
131 (Variant {
132 ident: id,
133 attrs: attrs,
134 fields: fields,
135 discriminant: disr,
136 })
137 ));
138
139 fn description() -> Option<&'static str> {
140 Some("enum variant")
141 }
142 }
143
144 impl Synom for FieldsNamed {
145 named!(parse -> Self, map!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500146 braces!(call!(Punctuated::parse_terminated_with, Field::parse_named)),
David Tolnaye3d41b72017-12-31 15:24:00 -0500147 |(brace, fields)| FieldsNamed {
148 brace_token: brace,
David Tolnaybdafb102018-01-01 19:39:10 -0800149 named: fields,
David Tolnaye3d41b72017-12-31 15:24:00 -0500150 }
151 ));
David Tolnay79777332018-01-07 10:04:42 -0800152
153 fn description() -> Option<&'static str> {
154 Some("named fields in a struct or struct variant")
155 }
David Tolnaye3d41b72017-12-31 15:24:00 -0500156 }
157
158 impl Synom for FieldsUnnamed {
159 named!(parse -> Self, map!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500160 parens!(call!(Punctuated::parse_terminated_with, Field::parse_unnamed)),
David Tolnaye3d41b72017-12-31 15:24:00 -0500161 |(paren, fields)| FieldsUnnamed {
162 paren_token: paren,
David Tolnaybdafb102018-01-01 19:39:10 -0800163 unnamed: fields,
David Tolnaye3d41b72017-12-31 15:24:00 -0500164 }
165 ));
David Tolnay79777332018-01-07 10:04:42 -0800166
167 fn description() -> Option<&'static str> {
168 Some("unnamed fields in a tuple struct or tuple variant")
169 }
David Tolnaye3d41b72017-12-31 15:24:00 -0500170 }
171
Alex Crichton954046c2017-05-30 21:49:42 -0700172 impl Field {
David Tolnaye3d41b72017-12-31 15:24:00 -0500173 named!(pub parse_named -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500174 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400175 vis: syn!(Visibility) >>
176 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800177 colon: punct!(:) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800178 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400179 (Field {
180 ident: Some(id),
181 vis: vis,
182 attrs: attrs,
183 ty: ty,
184 colon_token: Some(colon),
185 })
186 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700187
David Tolnaye3d41b72017-12-31 15:24:00 -0500188 named!(pub parse_unnamed -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500189 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400190 vis: syn!(Visibility) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800191 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400192 (Field {
193 ident: None,
194 colon_token: None,
195 vis: vis,
196 attrs: attrs,
197 ty: ty,
198 })
199 ));
Michael Layzell416724e2017-05-24 21:12:34 -0400200 }
201
Alex Crichton954046c2017-05-30 21:49:42 -0700202 impl Synom for Visibility {
Michael Layzell92639a52017-06-01 00:07:44 -0400203 named!(parse -> Self, alt!(
204 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800205 pub_token: keyword!(pub) >>
206 other: parens!(keyword!(crate)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400207 (Visibility::Crate(VisCrate {
Michael Layzell92639a52017-06-01 00:07:44 -0400208 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500209 paren_token: other.0,
210 crate_token: other.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400211 }))
212 )
213 |
214 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800215 pub_token: keyword!(pub) >>
216 other: parens!(keyword!(self)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400217 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400218 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500219 paren_token: other.0,
220 in_token: None,
221 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400222 }))
223 )
224 |
225 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800226 pub_token: keyword!(pub) >>
227 other: parens!(keyword!(super)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400228 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400229 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500230 paren_token: other.0,
231 in_token: None,
232 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400233 }))
234 )
235 |
236 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800237 pub_token: keyword!(pub) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400238 other: parens!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800239 in_tok: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400240 restricted: call!(Path::parse_mod_style) >>
241 (in_tok, restricted)
242 )) >>
243 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400244 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500245 paren_token: other.0,
246 in_token: Some((other.1).0),
247 path: Box::new((other.1).1),
Michael Layzell92639a52017-06-01 00:07:44 -0400248 }))
249 )
250 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800251 keyword!(pub) => { |tok| {
Michael Layzell92639a52017-06-01 00:07:44 -0400252 Visibility::Public(VisPublic {
253 pub_token: tok,
254 })
255 } }
256 |
David Tolnayfcfb9002017-12-28 22:04:29 -0500257 epsilon!() => { |_| Visibility::Inherited }
Michael Layzell92639a52017-06-01 00:07:44 -0400258 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800259
260 fn description() -> Option<&'static str> {
David Tolnay05658502018-01-07 09:56:37 -0800261 Some("visibility qualifier such as `pub`")
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800262 }
Alex Crichton954046c2017-05-30 21:49:42 -0700263 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700264}
265
266#[cfg(feature = "printing")]
267mod printing {
268 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500269 use quote::{ToTokens, Tokens};
David Tolnayf38cdf62016-09-23 19:07:09 -0700270
271 impl ToTokens for Variant {
272 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700273 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700274 self.ident.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500275 self.fields.to_tokens(tokens);
David Tolnaye67902a2017-12-28 22:12:00 -0500276 if let Some((ref eq_token, ref disc)) = self.discriminant {
277 eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400278 disc.to_tokens(tokens);
279 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700280 }
281 }
282
David Tolnaye3d41b72017-12-31 15:24:00 -0500283 impl ToTokens for FieldsNamed {
David Tolnayf38cdf62016-09-23 19:07:09 -0700284 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye3d41b72017-12-31 15:24:00 -0500285 self.brace_token.surround(tokens, |tokens| {
David Tolnaybdafb102018-01-01 19:39:10 -0800286 self.named.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500287 });
288 }
289 }
290
291 impl ToTokens for FieldsUnnamed {
292 fn to_tokens(&self, tokens: &mut Tokens) {
293 self.paren_token.surround(tokens, |tokens| {
David Tolnaybdafb102018-01-01 19:39:10 -0800294 self.unnamed.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500295 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700296 }
297 }
298
299 impl ToTokens for Field {
300 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700301 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700302 self.vis.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400303 if let Some(ref ident) = self.ident {
304 ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -0700305 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400306 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700307 self.ty.to_tokens(tokens);
308 }
309 }
310
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700311 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700312 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700313 self.pub_token.to_tokens(tokens)
314 }
315 }
Arnaviond32b2942017-04-29 17:18:02 -0700316
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700317 impl ToTokens for VisCrate {
318 fn to_tokens(&self, tokens: &mut Tokens) {
319 self.pub_token.to_tokens(tokens);
320 self.paren_token.surround(tokens, |tokens| {
321 self.crate_token.to_tokens(tokens);
322 })
323 }
324 }
Arnaviond32b2942017-04-29 17:18:02 -0700325
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700326 impl ToTokens for VisRestricted {
327 fn to_tokens(&self, tokens: &mut Tokens) {
328 self.pub_token.to_tokens(tokens);
329 self.paren_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400330 // XXX: If we have a path which is not "self" or "super",
331 // automatically add the "in" token.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700332 self.in_token.to_tokens(tokens);
333 self.path.to_tokens(tokens);
334 });
335 }
336 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700337}