1 use crate::attr::Attribute; 2 use crate::data::{Fields, FieldsNamed, Variant}; 3 use crate::generics::Generics; 4 use crate::ident::Ident; 5 use crate::punctuated::Punctuated; 6 use crate::restriction::Visibility; 7 use crate::token; 8 9 ast_struct! { 10 /// Data structure sent to a `proc_macro_derive` macro. 11 #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] 12 pub struct DeriveInput { 13 pub attrs: Vec<Attribute>, 14 pub vis: Visibility, 15 pub ident: Ident, 16 pub generics: Generics, 17 pub data: Data, 18 } 19 } 20 21 ast_enum! { 22 /// The storage of a struct, enum or union data structure. 23 /// 24 /// # Syntax tree enum 25 /// 26 /// This type is a [syntax tree enum]. 27 /// 28 /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums 29 #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] 30 pub enum Data { 31 Struct(DataStruct), 32 Enum(DataEnum), 33 Union(DataUnion), 34 } 35 } 36 37 ast_struct! { 38 /// A struct input to a `proc_macro_derive` macro. 39 #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] 40 pub struct DataStruct { 41 pub struct_token: Token![struct], 42 pub fields: Fields, 43 pub semi_token: Option<Token![;]>, 44 } 45 } 46 47 ast_struct! { 48 /// An enum input to a `proc_macro_derive` macro. 49 #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] 50 pub struct DataEnum { 51 pub enum_token: Token![enum], 52 pub brace_token: token::Brace, 53 pub variants: Punctuated<Variant, Token![,]>, 54 } 55 } 56 57 ast_struct! { 58 /// An untagged union input to a `proc_macro_derive` macro. 59 #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] 60 pub struct DataUnion { 61 pub union_token: Token![union], 62 pub fields: FieldsNamed, 63 } 64 } 65 66 #[cfg(feature = "parsing")] 67 pub(crate) mod parsing { 68 use crate::attr::Attribute; 69 use crate::data::{Fields, FieldsNamed, Variant}; 70 use crate::derive::{Data, DataEnum, DataStruct, DataUnion, DeriveInput}; 71 use crate::error::Result; 72 use crate::generics::{Generics, WhereClause}; 73 use crate::ident::Ident; 74 use crate::parse::{Parse, ParseStream}; 75 use crate::punctuated::Punctuated; 76 use crate::restriction::Visibility; 77 use crate::token; 78 79 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 80 impl Parse for DeriveInput { parse(input: ParseStream) -> Result<Self>81 fn parse(input: ParseStream) -> Result<Self> { 82 let attrs = input.call(Attribute::parse_outer)?; 83 let vis = input.parse::<Visibility>()?; 84 85 let lookahead = input.lookahead1(); 86 if lookahead.peek(Token![struct]) { 87 let struct_token = input.parse::<Token![struct]>()?; 88 let ident = input.parse::<Ident>()?; 89 let generics = input.parse::<Generics>()?; 90 let (where_clause, fields, semi) = data_struct(input)?; 91 Ok(DeriveInput { 92 attrs, 93 vis, 94 ident, 95 generics: Generics { 96 where_clause, 97 ..generics 98 }, 99 data: Data::Struct(DataStruct { 100 struct_token, 101 fields, 102 semi_token: semi, 103 }), 104 }) 105 } else if lookahead.peek(Token![enum]) { 106 let enum_token = input.parse::<Token![enum]>()?; 107 let ident = input.parse::<Ident>()?; 108 let generics = input.parse::<Generics>()?; 109 let (where_clause, brace, variants) = data_enum(input)?; 110 Ok(DeriveInput { 111 attrs, 112 vis, 113 ident, 114 generics: Generics { 115 where_clause, 116 ..generics 117 }, 118 data: Data::Enum(DataEnum { 119 enum_token, 120 brace_token: brace, 121 variants, 122 }), 123 }) 124 } else if lookahead.peek(Token![union]) { 125 let union_token = input.parse::<Token![union]>()?; 126 let ident = input.parse::<Ident>()?; 127 let generics = input.parse::<Generics>()?; 128 let (where_clause, fields) = data_union(input)?; 129 Ok(DeriveInput { 130 attrs, 131 vis, 132 ident, 133 generics: Generics { 134 where_clause, 135 ..generics 136 }, 137 data: Data::Union(DataUnion { 138 union_token, 139 fields, 140 }), 141 }) 142 } else { 143 Err(lookahead.error()) 144 } 145 } 146 } 147 data_struct( input: ParseStream, ) -> Result<(Option<WhereClause>, Fields, Option<Token![;]>)>148 pub(crate) fn data_struct( 149 input: ParseStream, 150 ) -> Result<(Option<WhereClause>, Fields, Option<Token![;]>)> { 151 let mut lookahead = input.lookahead1(); 152 let mut where_clause = None; 153 if lookahead.peek(Token![where]) { 154 where_clause = Some(input.parse()?); 155 lookahead = input.lookahead1(); 156 } 157 158 if where_clause.is_none() && lookahead.peek(token::Paren) { 159 let fields = input.parse()?; 160 161 lookahead = input.lookahead1(); 162 if lookahead.peek(Token![where]) { 163 where_clause = Some(input.parse()?); 164 lookahead = input.lookahead1(); 165 } 166 167 if lookahead.peek(Token![;]) { 168 let semi = input.parse()?; 169 Ok((where_clause, Fields::Unnamed(fields), Some(semi))) 170 } else { 171 Err(lookahead.error()) 172 } 173 } else if lookahead.peek(token::Brace) { 174 let fields = input.parse()?; 175 Ok((where_clause, Fields::Named(fields), None)) 176 } else if lookahead.peek(Token![;]) { 177 let semi = input.parse()?; 178 Ok((where_clause, Fields::Unit, Some(semi))) 179 } else { 180 Err(lookahead.error()) 181 } 182 } 183 data_enum( input: ParseStream, ) -> Result<( Option<WhereClause>, token::Brace, Punctuated<Variant, Token![,]>, )>184 pub(crate) fn data_enum( 185 input: ParseStream, 186 ) -> Result<( 187 Option<WhereClause>, 188 token::Brace, 189 Punctuated<Variant, Token![,]>, 190 )> { 191 let where_clause = input.parse()?; 192 193 let content; 194 let brace = braced!(content in input); 195 let variants = content.parse_terminated(Variant::parse, Token![,])?; 196 197 Ok((where_clause, brace, variants)) 198 } 199 data_union(input: ParseStream) -> Result<(Option<WhereClause>, FieldsNamed)>200 pub(crate) fn data_union(input: ParseStream) -> Result<(Option<WhereClause>, FieldsNamed)> { 201 let where_clause = input.parse()?; 202 let fields = input.parse()?; 203 Ok((where_clause, fields)) 204 } 205 } 206 207 #[cfg(feature = "printing")] 208 mod printing { 209 use crate::attr::FilterAttrs; 210 use crate::data::Fields; 211 use crate::derive::{Data, DeriveInput}; 212 use crate::print::TokensOrDefault; 213 use proc_macro2::TokenStream; 214 use quote::ToTokens; 215 216 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 217 impl ToTokens for DeriveInput { to_tokens(&self, tokens: &mut TokenStream)218 fn to_tokens(&self, tokens: &mut TokenStream) { 219 for attr in self.attrs.outer() { 220 attr.to_tokens(tokens); 221 } 222 self.vis.to_tokens(tokens); 223 match &self.data { 224 Data::Struct(d) => d.struct_token.to_tokens(tokens), 225 Data::Enum(d) => d.enum_token.to_tokens(tokens), 226 Data::Union(d) => d.union_token.to_tokens(tokens), 227 } 228 self.ident.to_tokens(tokens); 229 self.generics.to_tokens(tokens); 230 match &self.data { 231 Data::Struct(data) => match &data.fields { 232 Fields::Named(fields) => { 233 self.generics.where_clause.to_tokens(tokens); 234 fields.to_tokens(tokens); 235 } 236 Fields::Unnamed(fields) => { 237 fields.to_tokens(tokens); 238 self.generics.where_clause.to_tokens(tokens); 239 TokensOrDefault(&data.semi_token).to_tokens(tokens); 240 } 241 Fields::Unit => { 242 self.generics.where_clause.to_tokens(tokens); 243 TokensOrDefault(&data.semi_token).to_tokens(tokens); 244 } 245 }, 246 Data::Enum(data) => { 247 self.generics.where_clause.to_tokens(tokens); 248 data.brace_token.surround(tokens, |tokens| { 249 data.variants.to_tokens(tokens); 250 }); 251 } 252 Data::Union(data) => { 253 self.generics.where_clause.to_tokens(tokens); 254 data.fields.to_tokens(tokens); 255 } 256 } 257 } 258 } 259 } 260