1use crate::{SimplePath, fields::Fields, utils::extend_generics};
9use proc_macro_error3::emit_error;
10use proc_macro2::{Span, TokenStream};
11use quote::{ToTokens, TokenStreamExt};
12use syn::punctuated::Punctuated;
13use syn::spanned::Spanned;
14use syn::token::{Brace, Comma, Semi};
15use syn::{
16 Attribute, FieldsNamed, Generics, Ident, ItemImpl, Path, Result, Token, Type, Variant,
17 Visibility, parse_quote,
18};
19
20pub use super::default::{AttrImplDefault, find_impl_default};
21
22pub struct ScopeModAttrs;
24
25pub trait ScopeAttr {
32 fn path(&self) -> SimplePath;
40
41 fn support_repetition(&self) -> bool {
47 false
48 }
49
50 fn apply(&self, attr: Attribute, scope: &mut Scope) -> Result<()>;
60}
61
62#[derive(Debug)]
64pub enum ScopeItem {
65 Enum {
67 token: Token![enum],
69 brace: Brace,
71 variants: Punctuated<Variant, Comma>,
73 },
74 Struct {
78 token: Token![struct],
80 fields: Fields,
82 },
83 Type {
85 token: Token![type],
87 eq_token: Token![=],
89 ty: Box<Type>,
91 },
92 Union {
94 token: Token![union],
96 fields: FieldsNamed,
98 },
99}
100
101impl ScopeItem {
102 pub fn token_span(&self) -> Span {
104 match self {
105 ScopeItem::Enum { token, .. } => token.span,
106 ScopeItem::Struct { token, .. } => token.span,
107 ScopeItem::Type { token, .. } => token.span,
108 ScopeItem::Union { token, .. } => token.span,
109 }
110 }
111}
112
113#[derive(Debug)]
118pub struct ScopeMod {
119 pub token: Token![mod],
121 pub ident: Ident,
123 pub brace: Brace,
125 pub contents: Scope,
127}
128
129#[derive(Debug)]
147pub struct Scope {
148 pub attrs: Vec<Attribute>,
150 pub vis: Visibility,
152 pub ident: Ident,
154 pub generics: Generics,
156 pub item: ScopeItem,
158 pub semi: Option<Semi>,
160 pub impls: Vec<ItemImpl>,
162 pub generated: Vec<TokenStream>,
168}
169
170impl Scope {
171 pub fn apply_attrs(&mut self, find_rule: impl Fn(&Path) -> Option<&'static dyn ScopeAttr>) {
176 let mut applied: Vec<(Span, *const dyn ScopeAttr)> = Vec::new();
177
178 let mut i = 0;
179 while i < self.attrs.len() {
180 if let Some(rule) = find_rule(&self.attrs[i].path()) {
181 let attr = self.attrs.remove(i);
182
183 if !rule.support_repetition() {
184 let span = attr.span();
189 let ptr = rule as *const dyn ScopeAttr;
190 if let Some(first) = applied.iter().find(|(_, p)| std::ptr::eq(*p, ptr)) {
191 emit_error!(span, "repeated use of attribute not allowed");
192 emit_error!(first.0, "first usage here");
193 continue;
194 }
195 applied.push((span, ptr));
196 }
197
198 if let Err(err) = rule.apply(attr, self) {
199 emit_error!(err.span(), "{}", err);
200 }
201 continue;
202 }
203
204 i += 1;
205 }
206 }
207
208 pub fn expand_impl_self(&mut self) {
213 for impl_ in self.impls.iter_mut() {
214 if impl_.self_ty == parse_quote! { Self } {
215 let mut ident = self.ident.clone();
216 ident.set_span(impl_.self_ty.span());
217 let (_, ty_generics, _) = self.generics.split_for_impl();
218 impl_.self_ty = parse_quote! { #ident #ty_generics };
219 extend_generics(&mut impl_.generics, &self.generics);
220 }
221 }
222 }
223
224 pub fn expand(mut self) -> TokenStream {
230 self.expand_impl_self();
231 self.to_token_stream()
232 }
233}
234
235mod parsing {
236 use super::*;
237 use crate::error_on_attrs;
238 use crate::fields::parsing::data_struct;
239 use syn::parse::{Parse, ParseStream};
240 use syn::spanned::Spanned;
241 use syn::{Error, Field, Lifetime, Path, TypePath, WhereClause, braced};
242
243 impl Parse for ScopeModAttrs {
244 fn parse(_input: ParseStream) -> Result<Self> {
245 Ok(Self)
246 }
247 }
248
249 impl Parse for ScopeMod {
250 fn parse(input: ParseStream) -> Result<Self> {
251 let inner;
252
253 let token = input.parse()?;
254 let ident = input.parse::<Ident>()?;
255 let brace = syn::braced!(inner in input);
256 let contents: Scope = inner.parse()?;
257
258 if ident != contents.ident {
259 return Err(syn::Error::new(
260 contents.ident.span(),
261 "type name must match mod name",
262 ));
263 }
264
265 Ok(ScopeMod {
266 token,
267 ident,
268 brace,
269 contents,
270 })
271 }
272 }
273
274 impl Parse for Scope {
275 fn parse(input: ParseStream) -> Result<Self> {
276 let attrs = input.call(Attribute::parse_outer)?;
277 let vis = input.parse::<Visibility>()?;
278
279 enum Token {
280 Enum(Token![enum]),
281 Struct(Token![struct]),
282 Type(Token![type]),
283 Union(Token![union]),
284 }
285 let lookahead = input.lookahead1();
286 let token;
287 if lookahead.peek(Token![enum]) {
288 token = Token::Enum(input.parse()?);
289 } else if lookahead.peek(Token![struct]) {
290 token = Token::Struct(input.parse()?);
291 } else if lookahead.peek(Token![type]) {
292 token = Token::Type(input.parse()?);
293 } else if lookahead.peek(Token![union]) {
294 token = Token::Union(input.parse()?);
295 } else {
296 return Err(lookahead.error());
297 }
298
299 let ident = input.parse::<Ident>()?;
300 let mut generics = input.parse::<Generics>()?;
301
302 let item;
303 let mut semi = None;
304 match token {
305 Token::Enum(token) => {
306 let (wc, brace, variants) = data_enum(&input)?;
307 generics.where_clause = wc;
308 item = ScopeItem::Enum {
309 token,
310 brace,
311 variants,
312 };
313 }
314 Token::Struct(token) => {
315 let (wc, fields, semi_token) = data_struct(&input)?;
316 generics.where_clause = wc;
317 semi = semi_token;
318 item = ScopeItem::Struct { token, fields };
319 }
320 Token::Type(token) => {
321 let eq_token = input.parse()?;
322 let ty = input.parse()?;
323 let semi_token = input.parse()?;
324 semi = Some(semi_token);
325 item = ScopeItem::Type {
326 token,
327 eq_token,
328 ty,
329 };
330 }
331 Token::Union(token) => {
332 let (wc, fields) = data_union(&input)?;
333 generics.where_clause = wc;
334 item = ScopeItem::Union { token, fields };
335 }
336 }
337
338 let mut impls = Vec::new();
339 while !input.is_empty() {
340 impls.push(parse_impl(&ident, &input)?);
341 }
342
343 Ok(Scope {
344 attrs,
345 vis,
346 ident,
347 generics,
348 item,
349 semi,
350 impls,
351 generated: vec![],
352 })
353 }
354 }
355
356 fn parse_impl(in_ident: &Ident, input: ParseStream) -> Result<ItemImpl> {
357 let mut attrs = input.call(Attribute::parse_outer)?;
358 let defaultness: Option<Token![default]> = input.parse()?;
359 let unsafety: Option<Token![unsafe]> = input.parse()?;
360 let impl_token: Token![impl] = input.parse()?;
361
362 let has_generics = input.peek(Token![<])
363 && (input.peek2(Token![>])
364 || input.peek2(Token![#])
365 || (input.peek2(Ident) || input.peek2(Lifetime))
366 && (input.peek3(Token![:])
367 || input.peek3(Token![,])
368 || input.peek3(Token![>])
369 || input.peek3(Token![=]))
370 || input.peek2(Token![const]));
371 let mut generics: Generics = if has_generics {
372 input.parse()?
373 } else {
374 Generics::default()
375 };
376
377 let mut first_ty: Type = input.parse()?;
378 let self_ty: Type;
379 let trait_;
380
381 let is_impl_for = input.peek(Token![for]);
382 if is_impl_for {
383 let for_token: Token![for] = input.parse()?;
384 let mut first_ty_ref = &first_ty;
385 while let Type::Group(ty) = first_ty_ref {
386 first_ty_ref = &ty.elem;
387 }
388 if let Type::Path(_) = first_ty_ref {
389 while let Type::Group(ty) = first_ty {
390 first_ty = *ty.elem;
391 }
392 if let Type::Path(TypePath {
393 attrs,
394 qself: None,
395 path,
396 }) = first_ty
397 {
398 error_on_attrs(&attrs);
399 trait_ = Some((path, for_token));
400 } else {
401 unreachable!();
402 }
403 } else {
404 return Err(Error::new(for_token.span, "for without target trait"));
405 }
406 self_ty = input.parse()?;
407 } else {
408 trait_ = None;
409 self_ty = first_ty;
410 }
411
412 generics.where_clause = input.parse()?;
413
414 if self_ty != parse_quote! { Self }
415 && !matches!(self_ty, Type::Path(TypePath {
416 attrs: _,
417 qself: None,
418 path: Path {
419 leading_colon: None,
420 ref segments,
421 },
422 }) if segments.len() == 1 && segments.first().unwrap().ident == *in_ident)
423 {
424 return Err(Error::new(
425 self_ty.span(),
426 format!(
427 "expected `Self` or `{0}` or `{0}<...>` or `Trait for Self`, etc",
428 in_ident
429 ),
430 ));
431 }
432
433 let content;
434 let brace_token = braced!(content in input);
435 attrs.extend(Attribute::parse_inner(&content)?);
436
437 let mut items = Vec::new();
438 while !content.is_empty() {
439 items.push(content.parse()?);
440 }
441
442 let mut modifiers = syn::ImplModifiers::default();
443 modifiers.defaultness = defaultness;
444
445 Ok(ItemImpl {
446 attrs,
447 modifiers,
448 unsafety,
449 impl_token,
450 generics,
451 trait_,
452 self_ty: Box::new(self_ty),
453 brace_token,
454 items,
455 })
456 }
457
458 pub fn data_enum(
459 input: ParseStream,
460 ) -> Result<(Option<WhereClause>, Brace, Punctuated<Variant, Token![,]>)> {
461 let where_clause = input.parse()?;
462
463 let content;
464 let brace = braced!(content in input);
465 let variants = content.parse_terminated(Variant::parse, Token![,])?;
466
467 Ok((where_clause, brace, variants))
468 }
469
470 pub fn data_union(input: ParseStream) -> Result<(Option<WhereClause>, FieldsNamed)> {
471 let where_clause = input.parse()?;
472 let fields = parse_braced(input)?;
473 Ok((where_clause, fields))
474 }
475
476 pub(crate) fn parse_braced(input: ParseStream) -> Result<FieldsNamed> {
477 let content;
478 let brace_token = braced!(content in input);
479 let named = content.parse_terminated(Field::parse_named, Token![,])?;
480 Ok(FieldsNamed { brace_token, named })
481 }
482}
483
484mod printing {
485 use super::*;
486
487 impl ToTokens for Scope {
488 fn to_tokens(&self, tokens: &mut TokenStream) {
489 tokens.append_all(self.attrs.iter());
490 self.vis.to_tokens(tokens);
491 match &self.item {
492 ScopeItem::Enum { token, .. } => token.to_tokens(tokens),
493 ScopeItem::Struct { token, .. } => token.to_tokens(tokens),
494 ScopeItem::Type { token, .. } => token.to_tokens(tokens),
495 ScopeItem::Union { token, .. } => token.to_tokens(tokens),
496 }
497 self.ident.to_tokens(tokens);
498 self.generics.to_tokens(tokens);
499 match &self.item {
500 ScopeItem::Enum {
501 brace, variants, ..
502 } => {
503 self.generics.where_clause.to_tokens(tokens);
504 brace.surround(tokens, |tokens| {
505 variants.to_tokens(tokens);
506 });
507 }
508 ScopeItem::Struct { fields, .. } => match fields {
509 Fields::Named(fields) => {
510 self.generics.where_clause.to_tokens(tokens);
511 fields.to_tokens(tokens);
512 }
513 Fields::Unnamed(fields) => {
514 fields.to_tokens(tokens);
515 self.generics.where_clause.to_tokens(tokens);
516 }
517 Fields::Unit => {
518 self.generics.where_clause.to_tokens(tokens);
519 }
520 },
521 ScopeItem::Type { eq_token, ty, .. } => {
522 self.generics.where_clause.to_tokens(tokens);
523 eq_token.to_tokens(tokens);
524 ty.to_tokens(tokens);
525 }
526 ScopeItem::Union { fields, .. } => {
527 self.generics.where_clause.to_tokens(tokens);
528 fields.to_tokens(tokens);
529 }
530 }
531 if let Some(semi) = self.semi.as_ref() {
532 semi.to_tokens(tokens);
533 }
534
535 tokens.append_all(self.impls.iter());
536 tokens.append_all(self.generated.iter());
537 }
538 }
539}