Skip to content

Commit e9187e3

Browse files
committed
[reflection] cleanup derive_reflect
1 parent 00d8d5d commit e9187e3

File tree

1 file changed

+43
-59
lines changed
  • crates/bevy_reflect/bevy_reflect_derive/src

1 file changed

+43
-59
lines changed

crates/bevy_reflect/bevy_reflect_derive/src/lib.rs

Lines changed: 43 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use syn::{
1313
parse_macro_input,
1414
punctuated::Punctuated,
1515
token::{Comma, Paren, Where},
16-
Data, DataStruct, DeriveInput, Field, Fields, Generics, Ident, Index, Member, Meta, NestedMeta,
17-
Path,
16+
Attribute, Data, DataStruct, DeriveInput, Field, Fields, Generics, Ident, Index, Member, Meta,
17+
NestedMeta, Path,
1818
};
1919

2020
#[derive(Default)]
@@ -45,11 +45,47 @@ enum DeriveType {
4545
static REFLECT_ATTRIBUTE_NAME: &str = "reflect";
4646
static REFLECT_VALUE_ATTRIBUTE_NAME: &str = "reflect_value";
4747

48+
fn active_fields(punctuated: &Punctuated<Field, Comma>) -> impl Iterator<Item = (&Field, usize)> {
49+
punctuated.iter().enumerate().filter_map(|(idx, field)| {
50+
field
51+
.attrs
52+
.iter()
53+
.find(|attr| *attr.path.get_ident().as_ref().unwrap() == REFLECT_ATTRIBUTE_NAME)
54+
.map(|attr| {
55+
syn::custom_keyword!(ignore);
56+
attr.parse_args::<Option<ignore>>()
57+
.expect("Invalid 'property' attribute format.")
58+
.is_none()
59+
})
60+
.unwrap_or(true)
61+
.then(|| (field, idx))
62+
})
63+
}
64+
65+
fn reflect_attrs(attrs: &[Attribute]) -> (ReflectAttrs, Option<DeriveType>) {
66+
for attribute in attrs.iter().filter_map(|attr| attr.parse_meta().ok()) {
67+
if let Meta::List(meta_list) = attribute {
68+
if let Some(ident) = meta_list.path.get_ident() {
69+
if ident == REFLECT_ATTRIBUTE_NAME {
70+
return (ReflectAttrs::from_nested_metas(&meta_list.nested), None);
71+
} else if ident == REFLECT_VALUE_ATTRIBUTE_NAME {
72+
return (
73+
ReflectAttrs::from_nested_metas(&meta_list.nested),
74+
Some(DeriveType::Value),
75+
);
76+
}
77+
}
78+
}
79+
}
80+
81+
Default::default()
82+
}
83+
4884
#[proc_macro_derive(Reflect, attributes(reflect, reflect_value, module))]
4985
pub fn derive_reflect(input: TokenStream) -> TokenStream {
5086
let ast = parse_macro_input!(input as DeriveInput);
5187
let unit_struct_punctuated = Punctuated::new();
52-
let (fields, mut derive_type) = match &ast.data {
88+
let (fields, derive_type) = match &ast.data {
5389
Data::Struct(DataStruct {
5490
fields: Fields::Named(fields),
5591
..
@@ -65,66 +101,14 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream {
65101
_ => (&unit_struct_punctuated, DeriveType::Value),
66102
};
67103

68-
let fields_and_args = fields
69-
.iter()
70-
.enumerate()
71-
.map(|(i, f)| {
72-
(
73-
f,
74-
f.attrs
75-
.iter()
76-
.find(|a| *a.path.get_ident().as_ref().unwrap() == REFLECT_ATTRIBUTE_NAME)
77-
.map(|a| {
78-
syn::custom_keyword!(ignore);
79-
let mut attribute_args = PropAttributeArgs { ignore: None };
80-
a.parse_args_with(|input: ParseStream| {
81-
if input.parse::<Option<ignore>>()?.is_some() {
82-
attribute_args.ignore = Some(true);
83-
return Ok(());
84-
}
85-
Ok(())
86-
})
87-
.expect("Invalid 'property' attribute format.");
88-
89-
attribute_args
90-
}),
91-
i,
92-
)
93-
})
94-
.collect::<Vec<(&Field, Option<PropAttributeArgs>, usize)>>();
95-
let active_fields = fields_and_args
96-
.iter()
97-
.filter(|(_field, attrs, _i)| {
98-
attrs.is_none()
99-
|| match attrs.as_ref().unwrap().ignore {
100-
Some(ignore) => !ignore,
101-
None => true,
102-
}
103-
})
104-
.map(|(f, _attr, i)| (*f, *i))
105-
.collect::<Vec<(&Field, usize)>>();
104+
let active_fields = active_fields(&fields).collect::<Vec<_>>();
105+
106+
let (reflect_attrs, modified_derive_type) = reflect_attrs(&ast.attrs);
107+
let derive_type = modified_derive_type.unwrap_or(derive_type);
106108

107109
let bevy_reflect_path = BevyManifest::default().get_path("bevy_reflect");
108110
let type_name = &ast.ident;
109111

110-
let mut reflect_attrs = ReflectAttrs::default();
111-
for attribute in ast.attrs.iter().filter_map(|attr| attr.parse_meta().ok()) {
112-
let meta_list = if let Meta::List(meta_list) = attribute {
113-
meta_list
114-
} else {
115-
continue;
116-
};
117-
118-
if let Some(ident) = meta_list.path.get_ident() {
119-
if ident == REFLECT_ATTRIBUTE_NAME {
120-
reflect_attrs = ReflectAttrs::from_nested_metas(&meta_list.nested);
121-
} else if ident == REFLECT_VALUE_ATTRIBUTE_NAME {
122-
derive_type = DeriveType::Value;
123-
reflect_attrs = ReflectAttrs::from_nested_metas(&meta_list.nested);
124-
}
125-
}
126-
}
127-
128112
let registration_data = &reflect_attrs.data;
129113
let get_type_registration_impl = impl_get_type_registration(
130114
type_name,

0 commit comments

Comments
 (0)