|
2 | 2 |
|
3 | 3 | //! Macros for deriving asset traits. |
4 | 4 |
|
5 | | -use bevy_macro_utils::BevyManifest; |
| 5 | +use bevy_macro_utils::{BevyManifest, as_member}; |
6 | 6 | use proc_macro::{Span, TokenStream}; |
7 | 7 | use quote::{format_ident, quote}; |
8 | | -use syn::{parse_macro_input, Data, DeriveInput, Path}; |
| 8 | +use syn::{Data, DataStruct, DeriveInput, Path, parse_macro_input}; |
9 | 9 |
|
10 | 10 | pub(crate) fn bevy_asset_path() -> Path { |
11 | 11 | BevyManifest::shared(|manifest| manifest.get_path("bevy_asset")) |
@@ -55,49 +55,32 @@ fn derive_dependency_visitor_internal( |
55 | 55 | let field_has_dep = |f: &syn::Field| f.attrs.iter().any(is_dep_attribute); |
56 | 56 |
|
57 | 57 | let body = match &ast.data { |
58 | | - Data::Struct(data_struct) => { |
59 | | - let fields = data_struct.fields.iter(); |
60 | | - let field_visitors = fields.enumerate().filter(|(_, f)| field_has_dep(f)); |
61 | | - let field_visitors = field_visitors.map(|(i, field)| match &field.ident { |
62 | | - Some(ident) => visit_dep(quote!(&self.#ident)), |
63 | | - None => { |
64 | | - let index = syn::Index::from(i); |
65 | | - visit_dep(quote!(&self.#index)) |
66 | | - } |
67 | | - }); |
68 | | - Some(quote!( #(#field_visitors)* )) |
| 58 | + Data::Struct(DataStruct { fields, .. }) => { |
| 59 | + let field_visitors = fields |
| 60 | + .iter() |
| 61 | + .enumerate() |
| 62 | + .filter(|(_, f)| field_has_dep(f)) |
| 63 | + .map(|(i, field)| as_member(field.ident.as_ref(), i)) |
| 64 | + .map(|member| visit_dep(quote!(&self.#member))); |
| 65 | + Some(quote!(#(#field_visitors)*)) |
69 | 66 | } |
70 | 67 | Data::Enum(data_enum) => { |
71 | 68 | let variant_has_dep = |v: &syn::Variant| v.fields.iter().any(field_has_dep); |
72 | 69 | let any_case_required = data_enum.variants.iter().any(variant_has_dep); |
73 | 70 | let cases = data_enum.variants.iter().filter(|v| variant_has_dep(v)); |
74 | 71 | let cases = cases.map(|variant| { |
75 | 72 | let ident = &variant.ident; |
76 | | - let fields = &variant.fields; |
77 | | - |
78 | | - let field_visitors = fields.iter().enumerate().filter(|(_, f)| field_has_dep(f)); |
79 | | - |
80 | | - let field_visitors = field_visitors.map(|(i, field)| match &field.ident { |
81 | | - Some(ident) => visit_dep(quote!(#ident)), |
82 | | - None => { |
83 | | - let ident = format_ident!("member{i}"); |
84 | | - visit_dep(quote!(#ident)) |
85 | | - } |
86 | | - }); |
87 | | - let fields = match fields { |
88 | | - syn::Fields::Named(fields) => { |
89 | | - let named = fields.named.iter().map(|f| f.ident.as_ref()); |
90 | | - quote!({ #(#named,)* .. }) |
91 | | - } |
92 | | - syn::Fields::Unnamed(fields) => { |
93 | | - let named = (0..fields.unnamed.len()).map(|i| format_ident!("member{i}")); |
94 | | - quote!( ( #(#named,)* ) ) |
95 | | - } |
96 | | - syn::Fields::Unit => unreachable!("Can't pass filter is_dep_attribute"), |
97 | | - }; |
98 | | - quote!(Self::#ident #fields => { |
| 73 | + let field_members = variant |
| 74 | + .fields |
| 75 | + .iter() |
| 76 | + .enumerate() |
| 77 | + .filter(|(_, f)| field_has_dep(f)) |
| 78 | + .map(|(i, field)| as_member(field.ident.as_ref(), i)); |
| 79 | + let field_locals = field_members.clone().map(|m| format_ident!("__self_{}", m)); |
| 80 | + let field_visitors = field_locals.clone().map(|i| visit_dep(quote!(#i))); |
| 81 | + quote!(Self::#ident {#(#field_members: #field_locals,)* ..} => { |
99 | 82 | #(#field_visitors)* |
100 | | - }) |
| 83 | + },) |
101 | 84 | }); |
102 | 85 |
|
103 | 86 | any_case_required.then(|| quote!(match self { #(#cases)*, _ => {} })) |
|
0 commit comments