blob: fa635f41a4adc70a18a0252defd440d85ea83b0b [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! {
David Tolnaye3d41b72017-12-31 15:24:00 -050013 /// Data structure sent to a `proc_macro_derive` macro.
Alex Crichton62a0a592017-05-22 13:58:53 -070014 pub struct DeriveInput {
David Tolnay4a3f59a2017-12-28 21:21:12 -050015 /// Attributes tagged on the whole struct or enum.
16 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -050017
Alex Crichton62a0a592017-05-22 13:58:53 -070018 /// Visibility of the struct or enum.
19 pub vis: Visibility,
Clar Charrd22b5702017-03-10 15:24:56 -050020
David Tolnay4a3f59a2017-12-28 21:21:12 -050021 /// Name of the struct or enum.
22 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -050023
Alex Crichton62a0a592017-05-22 13:58:53 -070024 /// Generics required to complete the definition.
25 pub generics: Generics,
Clar Charrd22b5702017-03-10 15:24:56 -050026
Alex Crichton62a0a592017-05-22 13:58:53 -070027 /// Data within the struct or enum.
David Tolnaye3d41b72017-12-31 15:24:00 -050028 pub data: Data,
Alex Crichton62a0a592017-05-22 13:58:53 -070029 }
David Tolnayf38cdf62016-09-23 19:07:09 -070030}
31
Alex Crichtonccbb45d2017-05-23 10:58:24 -070032ast_enum_of_structs! {
David Tolnaye3d41b72017-12-31 15:24:00 -050033 /// The storage of a struct, enum or union data structure.
34 pub enum Data {
David Tolnayd2aa8832018-01-07 01:05:09 -080035 /// A struct input to a `proc_macro_derive` macro.
David Tolnaye3d41b72017-12-31 15:24:00 -050036 pub Struct(DataStruct {
37 pub struct_token: Token![struct],
38 pub fields: Fields,
39 pub semi_token: Option<Token![;]>,
40 }),
41
David Tolnayd2aa8832018-01-07 01:05:09 -080042 /// An enum input to a `proc_macro_derive` macro.
David Tolnaye3d41b72017-12-31 15:24:00 -050043 pub Enum(DataEnum {
David Tolnayf8db7ba2017-11-11 22:52:16 -080044 pub enum_token: Token![enum],
David Tolnay32954ef2017-12-26 22:43:16 -050045 pub brace_token: token::Brace,
David Tolnayf2cfd722017-12-31 18:02:51 -050046 pub variants: Punctuated<Variant, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070047 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070048
David Tolnayd2aa8832018-01-07 01:05:09 -080049 /// A tagged union input to a `proc_macro_derive` macro.
David Tolnaye3d41b72017-12-31 15:24:00 -050050 pub Union(DataUnion {
51 pub union_token: Token![union],
52 pub fields: FieldsNamed,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070053 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070054 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -070055
56 do_not_generate_to_tokens
David Tolnayf38cdf62016-09-23 19:07:09 -070057}
58
59#[cfg(feature = "parsing")]
60pub mod parsing {
61 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -070062
Michael Layzell92639a52017-06-01 00:07:44 -040063 use synom::Synom;
Alex Crichton954046c2017-05-30 21:49:42 -070064
65 impl Synom for DeriveInput {
Michael Layzell92639a52017-06-01 00:07:44 -040066 named!(parse -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -050067 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -040068 vis: syn!(Visibility) >>
69 which: alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -080070 keyword!(struct) => { Ok }
Michael Layzell92639a52017-06-01 00:07:44 -040071 |
David Tolnayf8db7ba2017-11-11 22:52:16 -080072 keyword!(enum) => { Err }
Michael Layzell92639a52017-06-01 00:07:44 -040073 ) >>
74 id: syn!(Ident) >>
75 generics: syn!(Generics) >>
76 item: switch!(value!(which),
David Tolnaye3d41b72017-12-31 15:24:00 -050077 Ok(s) => map!(data_struct, move |(wh, fields, semi)| DeriveInput {
Michael Layzell92639a52017-06-01 00:07:44 -040078 ident: id,
79 vis: vis,
80 attrs: attrs,
81 generics: Generics {
82 where_clause: wh,
83 .. generics
84 },
David Tolnaye3d41b72017-12-31 15:24:00 -050085 data: Data::Struct(DataStruct {
Michael Layzell92639a52017-06-01 00:07:44 -040086 struct_token: s,
David Tolnaye3d41b72017-12-31 15:24:00 -050087 fields: fields,
Michael Layzell92639a52017-06-01 00:07:44 -040088 semi_token: semi,
89 }),
90 })
91 |
David Tolnaye3d41b72017-12-31 15:24:00 -050092 Err(e) => map!(data_enum, move |(wh, brace, variants)| DeriveInput {
Michael Layzell92639a52017-06-01 00:07:44 -040093 ident: id,
94 vis: vis,
95 attrs: attrs,
96 generics: Generics {
97 where_clause: wh,
98 .. generics
99 },
David Tolnaye3d41b72017-12-31 15:24:00 -0500100 data: Data::Enum(DataEnum {
101 variants: variants,
Michael Layzell92639a52017-06-01 00:07:44 -0400102 brace_token: brace,
103 enum_token: e,
104 }),
105 })
106 ) >>
107 (item)
108 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700109
110 fn description() -> Option<&'static str> {
111 Some("derive input")
112 }
113 }
114
David Tolnaye3d41b72017-12-31 15:24:00 -0500115 named!(data_struct -> (Option<WhereClause>, Fields, Option<Token![;]>), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700116 do_parse!(
David Tolnayac997dd2017-12-27 23:18:22 -0500117 wh: option!(syn!(WhereClause)) >>
David Tolnaye3d41b72017-12-31 15:24:00 -0500118 fields: syn!(FieldsNamed) >>
119 (wh, Fields::Named(fields), None)
Alex Crichton954046c2017-05-30 21:49:42 -0700120 )
121 |
122 do_parse!(
David Tolnaye3d41b72017-12-31 15:24:00 -0500123 fields: syn!(FieldsUnnamed) >>
David Tolnayac997dd2017-12-27 23:18:22 -0500124 wh: option!(syn!(WhereClause)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800125 semi: punct!(;) >>
David Tolnaye3d41b72017-12-31 15:24:00 -0500126 (wh, Fields::Unnamed(fields), Some(semi))
Alex Crichton954046c2017-05-30 21:49:42 -0700127 )
128 |
129 do_parse!(
David Tolnayac997dd2017-12-27 23:18:22 -0500130 wh: option!(syn!(WhereClause)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800131 semi: punct!(;) >>
David Tolnaye3d41b72017-12-31 15:24:00 -0500132 (wh, Fields::Unit, Some(semi))
Alex Crichton954046c2017-05-30 21:49:42 -0700133 )
David Tolnayf38cdf62016-09-23 19:07:09 -0700134 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700135
David Tolnayf2cfd722017-12-31 18:02:51 -0500136 named!(data_enum -> (Option<WhereClause>, token::Brace, Punctuated<Variant, Token![,]>), do_parse!(
David Tolnayac997dd2017-12-27 23:18:22 -0500137 wh: option!(syn!(WhereClause)) >>
David Tolnayf2cfd722017-12-31 18:02:51 -0500138 data: braces!(Punctuated::parse_terminated) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700139 (wh, data.0, data.1)
140 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700141}
142
David Tolnayc2dfbf42016-09-23 23:52:15 -0700143#[cfg(feature = "printing")]
David Tolnayf38cdf62016-09-23 19:07:09 -0700144mod printing {
145 use super::*;
David Tolnay4a51dc72016-10-01 00:40:31 -0700146 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -0500147 use quote::{ToTokens, Tokens};
David Tolnayf38cdf62016-09-23 19:07:09 -0700148
David Tolnay0e837402016-12-22 17:25:55 -0500149 impl ToTokens for DeriveInput {
David Tolnayf38cdf62016-09-23 19:07:09 -0700150 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4a51dc72016-10-01 00:40:31 -0700151 for attr in self.attrs.outer() {
David Tolnayf38cdf62016-09-23 19:07:09 -0700152 attr.to_tokens(tokens);
153 }
David Tolnay47a877c2016-10-01 16:50:55 -0700154 self.vis.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500155 match self.data {
156 Data::Struct(ref d) => d.struct_token.to_tokens(tokens),
157 Data::Enum(ref d) => d.enum_token.to_tokens(tokens),
158 Data::Union(ref d) => d.union_token.to_tokens(tokens),
David Tolnayf38cdf62016-09-23 19:07:09 -0700159 }
160 self.ident.to_tokens(tokens);
161 self.generics.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500162 match self.data {
David Tolnay61037c62018-01-05 16:21:03 -0800163 Data::Struct(ref data) => match data.fields {
164 Fields::Named(ref fields) => {
165 self.generics.where_clause.to_tokens(tokens);
166 fields.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500167 }
David Tolnay61037c62018-01-05 16:21:03 -0800168 Fields::Unnamed(ref fields) => {
169 fields.to_tokens(tokens);
170 self.generics.where_clause.to_tokens(tokens);
171 TokensOrDefault(&data.semi_token).to_tokens(tokens);
172 }
173 Fields::Unit => {
174 self.generics.where_clause.to_tokens(tokens);
175 TokensOrDefault(&data.semi_token).to_tokens(tokens);
176 }
177 },
David Tolnaye3d41b72017-12-31 15:24:00 -0500178 Data::Enum(ref data) => {
David Tolnay28c1db62016-10-27 22:48:18 -0700179 self.generics.where_clause.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700180 data.brace_token.surround(tokens, |tokens| {
181 data.variants.to_tokens(tokens);
182 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700183 }
David Tolnaye3d41b72017-12-31 15:24:00 -0500184 Data::Union(ref data) => {
185 self.generics.where_clause.to_tokens(tokens);
186 data.fields.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700187 }
188 }
189 }
190 }
191}