# Objective The code in `bevy_reflect_derive` could use some cleanup. ## Solution Took some of the changes in #11659 to create a dedicated PR for cleaning up the field and container attribute logic. #### Updated Naming I renamed `ReflectTraits` and `ReflectFieldAttr` to `ContainerAttributes` and `FieldAttributes`, respectively. I think these are clearer. #### Updated Parsing ##### Readability The parsing logic wasn't too bad before, but it was getting difficult to read. There was some duplicated logic between `Meta::List` and `Meta::Path` attributes. Additionally, all the logic was kept inside a large method. To simply things, I replaced the nested meta parsing with `ParseStream` parsing. In my opinion, this is easier to follow since it breaks up the large match statement into a small set of single-line if statements, where each if-block contains a single call to the appropriate attribute parsing method. ##### Flexibility On top of the added simplicity, this also makes our attribute parsing much more flexible. It allows us to more elegantly handle custom where clauses (i.e. `#[reflect(where T: Foo)]`) and it opens the door for more non-standard attribute syntax (e.g. #11659). ##### Errors This also allows us to automatically provide certain errors when parsing. For example, since we can use `stream.lookahead1()`, we get errors like the following for free: ``` error: expected one of: `ignore`, `skip_serializing`, `default` --> crates/bevy_reflect/src/lib.rs:1988:23 | 1988 | #[reflect(foo)] | ^^^ ``` --- ## Changelog > [!note] > All changes are internal to `bevy_reflect_derive` and should not affect the public API[^1]. - Renamed `ReflectTraits` to `ContainerAttributes` - Renamed `ReflectMeta::traits` to `ReflectMeta::attrs` - Renamed `ReflectFieldAttr` to `FieldAttributes` - Updated parsing logic for field/container attribute parsing - Now uses a `ParseStream` directly instead of nested meta parsing - General code cleanup of the field/container attribute modules for `bevy_reflect_derive` [^1]: Does not include errors, which may look slightly different. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
50 lines
2.0 KiB
Rust
50 lines
2.0 KiB
Rust
//! Contains code related specifically to Bevy's type registration.
|
|
|
|
use crate::derive_data::ReflectMeta;
|
|
use crate::serialization::SerializationDataDef;
|
|
use crate::utility::WhereClauseOptions;
|
|
use quote::quote;
|
|
|
|
/// Creates the `GetTypeRegistration` impl for the given type data.
|
|
#[allow(clippy::too_many_arguments)]
|
|
pub(crate) fn impl_get_type_registration(
|
|
meta: &ReflectMeta,
|
|
where_clause_options: &WhereClauseOptions,
|
|
serialization_data: Option<&SerializationDataDef>,
|
|
) -> proc_macro2::TokenStream {
|
|
let type_path = meta.type_path();
|
|
let bevy_reflect_path = meta.bevy_reflect_path();
|
|
let registration_data = meta.attrs().idents();
|
|
let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl();
|
|
let where_reflect_clause = where_clause_options.extend_where_clause(where_clause);
|
|
|
|
let from_reflect_data = if meta.from_reflect().should_auto_derive() {
|
|
Some(quote! {
|
|
registration.insert::<#bevy_reflect_path::ReflectFromReflect>(#bevy_reflect_path::FromType::<Self>::from_type());
|
|
})
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let serialization_data = serialization_data.map(|data| {
|
|
let serialization_data = data.as_serialization_data(bevy_reflect_path);
|
|
quote! {
|
|
registration.insert::<#bevy_reflect_path::serde::SerializationData>(#serialization_data);
|
|
}
|
|
});
|
|
|
|
quote! {
|
|
#[allow(unused_mut)]
|
|
impl #impl_generics #bevy_reflect_path::GetTypeRegistration for #type_path #ty_generics #where_reflect_clause {
|
|
fn get_type_registration() -> #bevy_reflect_path::TypeRegistration {
|
|
let mut registration = #bevy_reflect_path::TypeRegistration::of::<Self>();
|
|
registration.insert::<#bevy_reflect_path::ReflectFromPtr>(#bevy_reflect_path::FromType::<Self>::from_type());
|
|
#from_reflect_data
|
|
#serialization_data
|
|
#(registration.insert::<#registration_data>(#bevy_reflect_path::FromType::<Self>::from_type());)*
|
|
registration
|
|
}
|
|
}
|
|
}
|
|
}
|