1use crate::{fields::Fields, SimplePath};
9use proc_macro2::{Span, TokenStream};
10use proc_macro_error2::emit_error;
11use quote::{ToTokens, TokenStreamExt};
12use syn::punctuated::Punctuated;
13use syn::spanned::Spanned;
14use syn::token::{Brace, Comma, Semi};
15use syn::{
16 parse_quote, Attribute, FieldsNamed, GenericParam, Generics, Ident, ItemImpl, Path, Result,
17 Token, Type, Variant, Visibility,
18};
19
20pub use super::default::{find_impl_default, AttrImplDefault};
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::fields::parsing::data_struct;
238 use syn::parse::{Parse, ParseStream};
239 use syn::spanned::Spanned;
240 use syn::{braced, Error, Field, Lifetime, Path, TypePath, WhereClause};
241
242 impl Parse for ScopeModAttrs {
243 fn parse(_input: ParseStream) -> Result<Self> {
244 Ok(Self)
245 }
246 }
247
248 impl Parse for ScopeMod {
249 fn parse(input: ParseStream) -> Result<Self> {
250 let inner;
251
252 let token = input.parse()?;
253 let ident = input.parse::<Ident>()?;
254 let brace = syn::braced!(inner in input);
255 let contents: Scope = inner.parse()?;
256
257 if ident != contents.ident {
258 return Err(syn::Error::new(
259 contents.ident.span(),
260 "type name must match mod name",
261 ));
262 }
263
264 Ok(ScopeMod {
265 token,
266 ident,
267 brace,
268 contents,
269 })
270 }
271 }
272
273 impl Parse for Scope {
274 fn parse(input: ParseStream) -> Result<Self> {
275 let attrs = input.call(Attribute::parse_outer)?;
276 let vis = input.parse::<Visibility>()?;
277
278 enum Token {
279 Enum(Token![enum]),
280 Struct(Token![struct]),
281 Type(Token![type]),
282 Union(Token![union]),
283 }
284 let lookahead = input.lookahead1();
285 let token;
286 if lookahead.peek(Token![enum]) {
287 token = Token::Enum(input.parse()?);
288 } else if lookahead.peek(Token![struct]) {
289 token = Token::Struct(input.parse()?);
290 } else if lookahead.peek(Token![type]) {
291 token = Token::Type(input.parse()?);
292 } else if lookahead.peek(Token![union]) {
293 token = Token::Union(input.parse()?);
294 } else {
295 return Err(lookahead.error());
296 }
297
298 let ident = input.parse::<Ident>()?;
299 let mut generics = input.parse::<Generics>()?;
300
301 let item;
302 let mut semi = None;
303 match token {
304 Token::Enum(token) => {
305 let (wc, brace, variants) = data_enum(&input)?;
306 generics.where_clause = wc;
307 item = ScopeItem::Enum {
308 token,
309 brace,
310 variants,
311 };
312 }
313 Token::Struct(token) => {
314 let (wc, fields, semi_token) = data_struct(&input)?;
315 generics.where_clause = wc;
316 semi = semi_token;
317 item = ScopeItem::Struct { token, fields };
318 }
319 Token::Type(token) => {
320 let eq_token = input.parse()?;
321 let ty = input.parse()?;
322 let semi_token = input.parse()?;
323 semi = Some(semi_token);
324 item = ScopeItem::Type {
325 token,
326 eq_token,
327 ty,
328 };
329 }
330 Token::Union(token) => {
331 let (wc, fields) = data_union(&input)?;
332 generics.where_clause = wc;
333 item = ScopeItem::Union { token, fields };
334 }
335 }
336
337 let mut impls = Vec::new();
338 while !input.is_empty() {
339 impls.push(parse_impl(&ident, &input)?);
340 }
341
342 Ok(Scope {
343 attrs,
344 vis,
345 ident,
346 generics,
347 item,
348 semi,
349 impls,
350 generated: vec![],
351 })
352 }
353 }
354
355 fn parse_impl(in_ident: &Ident, input: ParseStream) -> Result<ItemImpl> {
356 let mut attrs = input.call(Attribute::parse_outer)?;
357 let defaultness: Option<Token![default]> = input.parse()?;
358 let unsafety: Option<Token![unsafe]> = input.parse()?;
359 let impl_token: Token![impl] = input.parse()?;
360
361 let has_generics = input.peek(Token![<])
362 && (input.peek2(Token![>])
363 || input.peek2(Token![#])
364 || (input.peek2(Ident) || input.peek2(Lifetime))
365 && (input.peek3(Token![:])
366 || input.peek3(Token![,])
367 || input.peek3(Token![>])
368 || input.peek3(Token![=]))
369 || input.peek2(Token![const]));
370 let mut generics: Generics = if has_generics {
371 input.parse()?
372 } else {
373 Generics::default()
374 };
375
376 let mut first_ty: Type = input.parse()?;
377 let self_ty: Type;
378 let trait_;
379
380 let is_impl_for = input.peek(Token![for]);
381 if is_impl_for {
382 let for_token: Token![for] = input.parse()?;
383 let mut first_ty_ref = &first_ty;
384 while let Type::Group(ty) = first_ty_ref {
385 first_ty_ref = &ty.elem;
386 }
387 if let Type::Path(_) = first_ty_ref {
388 while let Type::Group(ty) = first_ty {
389 first_ty = *ty.elem;
390 }
391 if let Type::Path(TypePath { qself: None, path }) = first_ty {
392 trait_ = Some((None, path, for_token));
393 } else {
394 unreachable!();
395 }
396 } else {
397 return Err(Error::new(for_token.span, "for without target trait"));
398 }
399 self_ty = input.parse()?;
400 } else {
401 trait_ = None;
402 self_ty = first_ty;
403 }
404
405 generics.where_clause = input.parse()?;
406
407 if self_ty != parse_quote! { Self }
408 && !matches!(self_ty, Type::Path(TypePath {
409 qself: None,
410 path: Path {
411 leading_colon: None,
412 ref segments,
413 }
414 }) if segments.len() == 1 && segments.first().unwrap().ident == *in_ident)
415 {
416 return Err(Error::new(
417 self_ty.span(),
418 format!(
419 "expected `Self` or `{0}` or `{0}<...>` or `Trait for Self`, etc",
420 in_ident
421 ),
422 ));
423 }
424
425 let content;
426 let brace_token = braced!(content in input);
427 attrs.extend(Attribute::parse_inner(&content)?);
428
429 let mut items = Vec::new();
430 while !content.is_empty() {
431 items.push(content.parse()?);
432 }
433
434 Ok(ItemImpl {
435 attrs,
436 defaultness,
437 unsafety,
438 impl_token,
439 generics,
440 trait_,
441 self_ty: Box::new(self_ty),
442 brace_token,
443 items,
444 })
445 }
446
447 pub fn data_enum(
448 input: ParseStream,
449 ) -> Result<(Option<WhereClause>, Brace, Punctuated<Variant, Token![,]>)> {
450 let where_clause = input.parse()?;
451
452 let content;
453 let brace = braced!(content in input);
454 let variants = content.parse_terminated(Variant::parse, Token![,])?;
455
456 Ok((where_clause, brace, variants))
457 }
458
459 pub fn data_union(input: ParseStream) -> Result<(Option<WhereClause>, FieldsNamed)> {
460 let where_clause = input.parse()?;
461 let fields = parse_braced(input)?;
462 Ok((where_clause, fields))
463 }
464
465 pub(crate) fn parse_braced(input: ParseStream) -> Result<FieldsNamed> {
466 let content;
467 let brace_token = braced!(content in input);
468 let named = content.parse_terminated(Field::parse_named, Token![,])?;
469 Ok(FieldsNamed { brace_token, named })
470 }
471}
472
473mod printing {
474 use super::*;
475
476 impl ToTokens for Scope {
477 fn to_tokens(&self, tokens: &mut TokenStream) {
478 tokens.append_all(self.attrs.iter());
479 self.vis.to_tokens(tokens);
480 match &self.item {
481 ScopeItem::Enum { token, .. } => token.to_tokens(tokens),
482 ScopeItem::Struct { token, .. } => token.to_tokens(tokens),
483 ScopeItem::Type { token, .. } => token.to_tokens(tokens),
484 ScopeItem::Union { token, .. } => token.to_tokens(tokens),
485 }
486 self.ident.to_tokens(tokens);
487 self.generics.to_tokens(tokens);
488 match &self.item {
489 ScopeItem::Enum {
490 brace, variants, ..
491 } => {
492 self.generics.where_clause.to_tokens(tokens);
493 brace.surround(tokens, |tokens| {
494 variants.to_tokens(tokens);
495 });
496 }
497 ScopeItem::Struct { fields, .. } => match fields {
498 Fields::Named(fields) => {
499 self.generics.where_clause.to_tokens(tokens);
500 fields.to_tokens(tokens);
501 }
502 Fields::Unnamed(fields) => {
503 fields.to_tokens(tokens);
504 self.generics.where_clause.to_tokens(tokens);
505 }
506 Fields::Unit => {
507 self.generics.where_clause.to_tokens(tokens);
508 }
509 },
510 ScopeItem::Type { eq_token, ty, .. } => {
511 self.generics.where_clause.to_tokens(tokens);
512 eq_token.to_tokens(tokens);
513 ty.to_tokens(tokens);
514 }
515 ScopeItem::Union { fields, .. } => {
516 self.generics.where_clause.to_tokens(tokens);
517 fields.to_tokens(tokens);
518 }
519 }
520 if let Some(semi) = self.semi.as_ref() {
521 semi.to_tokens(tokens);
522 }
523
524 tokens.append_all(self.impls.iter());
525 tokens.append_all(self.generated.iter());
526 }
527 }
528}
529
530fn extend_generics(generics: &mut Generics, in_generics: &Generics) {
532 if generics.lt_token.is_none() {
533 debug_assert!(generics.params.is_empty());
534 debug_assert!(generics.gt_token.is_none());
535 generics.lt_token = in_generics.lt_token;
536 generics.params = in_generics.params.clone();
537 generics.gt_token = in_generics.gt_token;
538 } else if in_generics.lt_token.is_none() {
539 debug_assert!(in_generics.params.is_empty());
540 debug_assert!(in_generics.gt_token.is_none());
541 } else {
542 if !generics.params.empty_or_trailing() {
543 generics.params.push_punct(Default::default());
544 }
545 generics
546 .params
547 .extend(in_generics.params.clone().into_pairs());
548 }
549
550 for param in &mut generics.params {
552 match param {
553 GenericParam::Type(p) => {
554 p.eq_token = None;
555 p.default = None;
556 }
557 GenericParam::Lifetime(_) => (),
558 GenericParam::Const(p) => {
559 p.eq_token = None;
560 p.default = None;
561 }
562 }
563 }
564
565 if let Some(ref mut clause1) = generics.where_clause {
566 if let Some(ref clause2) = in_generics.where_clause {
567 if !clause1.predicates.empty_or_trailing() {
568 clause1.predicates.push_punct(Default::default());
569 }
570 clause1
571 .predicates
572 .extend(clause2.predicates.clone().into_pairs());
573 }
574 } else {
575 generics.where_clause = in_generics.where_clause.clone();
576 }
577}