blob: cfea802784402259229c29ef3290df55059aa3fc [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 Tolnaye3d41b72017-12-31 15:24:00 -050031 pub enum Fields {
32 /// Named fields of a struct or struct variant such as `Point { x: f64,
33 /// y: f64 }`.
34 pub Named(FieldsNamed {
35 pub brace_token: token::Brace,
David Tolnaybdafb102018-01-01 19:39:10 -080036 pub named: Punctuated<Field, Token![,]>,
David Tolnaye3d41b72017-12-31 15:24:00 -050037 }),
Clar Charrd22b5702017-03-10 15:24:56 -050038
David Tolnaye3d41b72017-12-31 15:24:00 -050039 /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
40 pub Unnamed(FieldsUnnamed {
41 pub paren_token: token::Paren,
David Tolnaybdafb102018-01-01 19:39:10 -080042 pub unnamed: 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 /// Unit struct or unit variant such as `None`.
46 pub Unit,
Alex Crichton62a0a592017-05-22 13:58:53 -070047 }
David Tolnayf38cdf62016-09-23 19:07:09 -070048}
49
Alex Crichton62a0a592017-05-22 13:58:53 -070050ast_struct! {
51 /// A field of a struct or enum variant.
52 pub struct Field {
David Tolnay4a3f59a2017-12-28 21:21:12 -050053 /// Attributes tagged on the field.
54 pub attrs: Vec<Attribute>,
55
56 /// Visibility of the field.
57 pub vis: Visibility,
58
Alex Crichton62a0a592017-05-22 13:58:53 -070059 /// Name of the field, if any.
60 ///
61 /// Fields of tuple structs have no names.
62 pub ident: Option<Ident>,
Clar Charrd22b5702017-03-10 15:24:56 -050063
David Tolnay4a3f59a2017-12-28 21:21:12 -050064 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -050065
Alex Crichton62a0a592017-05-22 13:58:53 -070066 /// Type of the field.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080067 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -070068 }
David Tolnayf38cdf62016-09-23 19:07:09 -070069}
70
Alex Crichtonccbb45d2017-05-23 10:58:24 -070071ast_enum_of_structs! {
David Tolnay05658502018-01-07 09:56:37 -080072 /// The visibility level of an item: inherited or `pub` or
73 /// `pub(restricted)`.
Alex Crichton62a0a592017-05-22 13:58:53 -070074 pub enum Visibility {
David Tolnay05658502018-01-07 09:56:37 -080075 /// A public visibility level: `pub`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070076 pub Public(VisPublic {
David Tolnayf8db7ba2017-11-11 22:52:16 -080077 pub pub_token: Token![pub],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070078 }),
Clar Charrd22b5702017-03-10 15:24:56 -050079
David Tolnay05658502018-01-07 09:56:37 -080080 /// A crate-level visibility: `pub(crate)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070081 pub Crate(VisCrate {
David Tolnayf8db7ba2017-11-11 22:52:16 -080082 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050083 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080084 pub crate_token: Token![crate],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070085 }),
Clar Charrd22b5702017-03-10 15:24:56 -050086
David Tolnay05658502018-01-07 09:56:37 -080087 /// A visibility level restricted to some path: `pub(self)` or
88 /// `pub(super)` or `pub(in some::module)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070089 pub Restricted(VisRestricted {
David Tolnayf8db7ba2017-11-11 22:52:16 -080090 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050091 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080092 pub in_token: Option<Token![in]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070093 pub path: Box<Path>,
94 }),
Clar Charrd22b5702017-03-10 15:24:56 -050095
David Tolnay05658502018-01-07 09:56:37 -080096 /// An inherited visibility, which usually means private.
David Tolnayfcfb9002017-12-28 22:04:29 -050097 pub Inherited,
Alex Crichton62a0a592017-05-22 13:58:53 -070098 }
David Tolnayf38cdf62016-09-23 19:07:09 -070099}
100
David Tolnayf38cdf62016-09-23 19:07:09 -0700101#[cfg(feature = "parsing")]
102pub mod parsing {
103 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700104
Michael Layzell92639a52017-06-01 00:07:44 -0400105 use synom::Synom;
David Tolnayf38cdf62016-09-23 19:07:09 -0700106
David Tolnaye3d41b72017-12-31 15:24:00 -0500107 impl Synom for Variant {
108 named!(parse -> Self, do_parse!(
109 attrs: many0!(Attribute::parse_outer) >>
110 id: syn!(Ident) >>
111 fields: alt!(
112 syn!(FieldsNamed) => { Fields::Named }
113 |
114 syn!(FieldsUnnamed) => { Fields::Unnamed }
115 |
116 epsilon!() => { |_| Fields::Unit }
117 ) >>
118 disr: option!(tuple!(punct!(=), syn!(Expr))) >>
119 (Variant {
120 ident: id,
121 attrs: attrs,
122 fields: fields,
123 discriminant: disr,
124 })
125 ));
126
127 fn description() -> Option<&'static str> {
128 Some("enum variant")
129 }
130 }
131
132 impl Synom for FieldsNamed {
133 named!(parse -> Self, map!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500134 braces!(call!(Punctuated::parse_terminated_with, Field::parse_named)),
David Tolnaye3d41b72017-12-31 15:24:00 -0500135 |(brace, fields)| FieldsNamed {
136 brace_token: brace,
David Tolnaybdafb102018-01-01 19:39:10 -0800137 named: fields,
David Tolnaye3d41b72017-12-31 15:24:00 -0500138 }
139 ));
David Tolnay79777332018-01-07 10:04:42 -0800140
141 fn description() -> Option<&'static str> {
142 Some("named fields in a struct or struct variant")
143 }
David Tolnaye3d41b72017-12-31 15:24:00 -0500144 }
145
146 impl Synom for FieldsUnnamed {
147 named!(parse -> Self, map!(
David Tolnayf2cfd722017-12-31 18:02:51 -0500148 parens!(call!(Punctuated::parse_terminated_with, Field::parse_unnamed)),
David Tolnaye3d41b72017-12-31 15:24:00 -0500149 |(paren, fields)| FieldsUnnamed {
150 paren_token: paren,
David Tolnaybdafb102018-01-01 19:39:10 -0800151 unnamed: fields,
David Tolnaye3d41b72017-12-31 15:24:00 -0500152 }
153 ));
David Tolnay79777332018-01-07 10:04:42 -0800154
155 fn description() -> Option<&'static str> {
156 Some("unnamed fields in a tuple struct or tuple variant")
157 }
David Tolnaye3d41b72017-12-31 15:24:00 -0500158 }
159
Alex Crichton954046c2017-05-30 21:49:42 -0700160 impl Field {
David Tolnaye3d41b72017-12-31 15:24:00 -0500161 named!(pub parse_named -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500162 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400163 vis: syn!(Visibility) >>
164 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800165 colon: punct!(:) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800166 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400167 (Field {
168 ident: Some(id),
169 vis: vis,
170 attrs: attrs,
171 ty: ty,
172 colon_token: Some(colon),
173 })
174 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700175
David Tolnaye3d41b72017-12-31 15:24:00 -0500176 named!(pub parse_unnamed -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500177 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400178 vis: syn!(Visibility) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800179 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400180 (Field {
181 ident: None,
182 colon_token: None,
183 vis: vis,
184 attrs: attrs,
185 ty: ty,
186 })
187 ));
Michael Layzell416724e2017-05-24 21:12:34 -0400188 }
189
Alex Crichton954046c2017-05-30 21:49:42 -0700190 impl Synom for Visibility {
Michael Layzell92639a52017-06-01 00:07:44 -0400191 named!(parse -> Self, alt!(
192 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800193 pub_token: keyword!(pub) >>
194 other: parens!(keyword!(crate)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400195 (Visibility::Crate(VisCrate {
Michael Layzell92639a52017-06-01 00:07:44 -0400196 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500197 paren_token: other.0,
198 crate_token: other.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400199 }))
200 )
201 |
202 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800203 pub_token: keyword!(pub) >>
204 other: parens!(keyword!(self)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400205 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400206 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500207 paren_token: other.0,
208 in_token: None,
209 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400210 }))
211 )
212 |
213 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800214 pub_token: keyword!(pub) >>
215 other: parens!(keyword!(super)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400216 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400217 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500218 paren_token: other.0,
219 in_token: None,
220 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400221 }))
222 )
223 |
224 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800225 pub_token: keyword!(pub) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400226 other: parens!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800227 in_tok: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400228 restricted: call!(Path::parse_mod_style) >>
229 (in_tok, restricted)
230 )) >>
231 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400232 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500233 paren_token: other.0,
234 in_token: Some((other.1).0),
235 path: Box::new((other.1).1),
Michael Layzell92639a52017-06-01 00:07:44 -0400236 }))
237 )
238 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800239 keyword!(pub) => { |tok| {
Michael Layzell92639a52017-06-01 00:07:44 -0400240 Visibility::Public(VisPublic {
241 pub_token: tok,
242 })
243 } }
244 |
David Tolnayfcfb9002017-12-28 22:04:29 -0500245 epsilon!() => { |_| Visibility::Inherited }
Michael Layzell92639a52017-06-01 00:07:44 -0400246 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800247
248 fn description() -> Option<&'static str> {
David Tolnay05658502018-01-07 09:56:37 -0800249 Some("visibility qualifier such as `pub`")
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800250 }
Alex Crichton954046c2017-05-30 21:49:42 -0700251 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700252}
253
254#[cfg(feature = "printing")]
255mod printing {
256 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500257 use quote::{ToTokens, Tokens};
David Tolnayf38cdf62016-09-23 19:07:09 -0700258
259 impl ToTokens for Variant {
260 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700261 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700262 self.ident.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500263 self.fields.to_tokens(tokens);
David Tolnaye67902a2017-12-28 22:12:00 -0500264 if let Some((ref eq_token, ref disc)) = self.discriminant {
265 eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400266 disc.to_tokens(tokens);
267 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700268 }
269 }
270
David Tolnaye3d41b72017-12-31 15:24:00 -0500271 impl ToTokens for FieldsNamed {
David Tolnayf38cdf62016-09-23 19:07:09 -0700272 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye3d41b72017-12-31 15:24:00 -0500273 self.brace_token.surround(tokens, |tokens| {
David Tolnaybdafb102018-01-01 19:39:10 -0800274 self.named.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500275 });
276 }
277 }
278
279 impl ToTokens for FieldsUnnamed {
280 fn to_tokens(&self, tokens: &mut Tokens) {
281 self.paren_token.surround(tokens, |tokens| {
David Tolnaybdafb102018-01-01 19:39:10 -0800282 self.unnamed.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500283 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700284 }
285 }
286
287 impl ToTokens for Field {
288 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700289 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700290 self.vis.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400291 if let Some(ref ident) = self.ident {
292 ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -0700293 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400294 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700295 self.ty.to_tokens(tokens);
296 }
297 }
298
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700299 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700300 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700301 self.pub_token.to_tokens(tokens)
302 }
303 }
Arnaviond32b2942017-04-29 17:18:02 -0700304
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700305 impl ToTokens for VisCrate {
306 fn to_tokens(&self, tokens: &mut Tokens) {
307 self.pub_token.to_tokens(tokens);
308 self.paren_token.surround(tokens, |tokens| {
309 self.crate_token.to_tokens(tokens);
310 })
311 }
312 }
Arnaviond32b2942017-04-29 17:18:02 -0700313
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700314 impl ToTokens for VisRestricted {
315 fn to_tokens(&self, tokens: &mut Tokens) {
316 self.pub_token.to_tokens(tokens);
317 self.paren_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400318 // XXX: If we have a path which is not "self" or "super",
319 // automatically add the "in" token.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700320 self.in_token.to_tokens(tokens);
321 self.path.to_tokens(tokens);
322 });
323 }
324 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700325}