diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/associated_data.rs b/crates/bevy_reflect/bevy_reflect_derive/src/associated_data.rs deleted file mode 100644 index 69d28d852ee1b8..00000000000000 --- a/crates/bevy_reflect/bevy_reflect_derive/src/associated_data.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::field_attributes::{DefaultBehavior, ReflectFieldAttr, ReflectIgnoreBehavior}; -use crate::utility::ident_or_index; -use bevy_macro_utils::fq_std::{FQBox, FQDefault}; -use proc_macro2::{Ident, TokenStream}; -use quote::{format_ident, ToTokens}; -use syn::{parse_quote, Field, ItemFn, Path}; - -/// Associated data to generate alongside derived trait implementations. -/// -/// It's important these are generated within the context of an [_unnamed const_] -/// in order to avoid conflicts and keep the macro hygenic. -/// -/// [_unnamed const_]: https://doc.rust-lang.org/stable/reference/items/constant-items.html#unnamed-constant -#[derive(Clone)] -pub(crate) struct AssociatedData { - default_fn: Option, -} - -impl AssociatedData { - /// Generates a new `AssociatedData` for a given field. - pub fn new( - field: &Field, - index: usize, - attrs: &ReflectFieldAttr, - qualifier: &Ident, - bevy_reflect_path: &Path, - ) -> Self { - let field_ident = ident_or_index(field.ident.as_ref(), index); - let field_ty = &field.ty; - - let default_fn = match attrs.ignore { - ReflectIgnoreBehavior::IgnoreSerialization => { - let ident = format_ident!("get_default__{}__{}", qualifier, field_ident); - match &attrs.default { - DefaultBehavior::Required | DefaultBehavior::Default => Some(parse_quote! { - #[allow(non_snake_case)] - fn #ident() -> #FQBox { - #FQBox::new(<#field_ty as #FQDefault>::default()) - } - }), - DefaultBehavior::Func(func) => Some(parse_quote! { - #[allow(non_snake_case)] - fn #ident() -> #FQBox { - #FQBox::new(#func() as #field_ty) - } - }), - } - } - _ => None, - }; - - Self { default_fn } - } - - /// Returns the function used to generate a default instance of a field. - /// - /// Returns `None` if the field does not have or need such a function. - pub fn default_fn(&self) -> Option<&ItemFn> { - self.default_fn.as_ref() - } -} - -impl ToTokens for AssociatedData { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.default_fn.to_tokens(tokens); - } -} diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs index a4f10cb8fe77a3..85357978e03be7 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs @@ -1,4 +1,3 @@ -use crate::associated_data::AssociatedData; use crate::container_attributes::{FromReflectAttrs, ReflectTraits}; use crate::field_attributes::{parse_field_attrs, ReflectFieldAttr}; use crate::type_path::parse_path_no_leading_colon; @@ -95,8 +94,6 @@ pub(crate) struct StructField<'a> { pub data: &'a Field, /// The reflection-based attributes on the field. pub attrs: ReflectFieldAttr, - /// The associated data to be generated on behalf of this field. - pub associated_data: AssociatedData, /// The index of this field within the struct. pub declaration_index: usize, /// The index of this field as seen by the reflection API. @@ -279,13 +276,7 @@ impl<'a> ReflectDerive<'a> { return match &input.data { Data::Struct(data) => { - let fields = Self::collect_struct_fields( - &data.fields, - meta.type_path() - .get_ident() - .expect("structs should never be anonymous"), - meta.bevy_reflect_path(), - )?; + let fields = Self::collect_struct_fields(&data.fields)?; let reflect_struct = ReflectStruct { meta, serialization_data: SerializationDataDef::new(&fields)?, @@ -299,8 +290,7 @@ impl<'a> ReflectDerive<'a> { } } Data::Enum(data) => { - let variants = - Self::collect_enum_variants(&data.variants, meta.bevy_reflect_path())?; + let variants = Self::collect_enum_variants(&data.variants)?; let reflect_enum = ReflectEnum { meta, variants }; Ok(Self::Enum(reflect_enum)) @@ -322,11 +312,7 @@ impl<'a> ReflectDerive<'a> { } } - fn collect_struct_fields( - fields: &'a Fields, - qualifier: &Ident, - bevy_reflect_path: &Path, - ) -> Result>, syn::Error> { + fn collect_struct_fields(fields: &'a Fields) -> Result>, syn::Error> { let mut active_index = 0; let sifter: utility::ResultSifter> = fields .iter() @@ -334,13 +320,6 @@ impl<'a> ReflectDerive<'a> { .map( |(declaration_index, field)| -> Result { let attrs = parse_field_attrs(&field.attrs)?; - let associated_data = AssociatedData::new( - field, - declaration_index, - &attrs, - qualifier, - bevy_reflect_path, - ); let reflection_index = if attrs.ignore.is_ignored() { None @@ -353,7 +332,6 @@ impl<'a> ReflectDerive<'a> { declaration_index, reflection_index, attrs, - associated_data, data: field, #[cfg(feature = "documentation")] doc: crate::documentation::Documentation::from_attributes(&field.attrs), @@ -370,17 +348,12 @@ impl<'a> ReflectDerive<'a> { fn collect_enum_variants( variants: &'a Punctuated, - bevy_reflect_path: &Path, ) -> Result>, syn::Error> { let sifter: utility::ResultSifter> = variants .iter() .enumerate() .map(|(index, variant)| -> Result { - let fields = Self::collect_struct_fields( - &variant.fields, - &variant.ident, - bevy_reflect_path, - )?; + let fields = Self::collect_struct_fields(&variant.fields)?; let fields = match variant.fields { Fields::Named(..) => EnumVariantFields::Named(fields), @@ -403,23 +376,6 @@ impl<'a> ReflectDerive<'a> { sifter.finish() } - - /// The complete set of fields in this item. - pub fn fields(&self) -> Box> + '_> { - match self { - ReflectDerive::Struct(reflect_struct) - | ReflectDerive::TupleStruct(reflect_struct) - | ReflectDerive::UnitStruct(reflect_struct) => Box::new(reflect_struct.fields.iter()), - ReflectDerive::Enum(reflect_enum) => Box::new(reflect_enum.fields()), - ReflectDerive::Value(_) => Box::new(core::iter::empty()), - } - } - - /// Generate all [associated data](AssociatedData) into a `TokenStream`. - pub fn associated_data(&self) -> proc_macro2::TokenStream { - let associated_data = self.fields().map(|field| &field.associated_data); - quote!(#(#associated_data)*) - } } impl<'a> ReflectMeta<'a> { @@ -551,11 +507,6 @@ impl<'a> ReflectEnum<'a> { &self.variants } - /// The complete set of fields in this enum. - pub fn fields(&self) -> impl Iterator> { - self.variants().iter().flat_map(|variant| variant.fields()) - } - /// Get an iterator of fields which are exposed to the reflection API pub fn active_fields(&self) -> impl Iterator> { self.variants() diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs index a9c1dbb2f6479d..03ef4f2668aaa6 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs @@ -14,7 +14,6 @@ extern crate proc_macro; -mod associated_data; mod container_attributes; mod derive_data; #[cfg(feature = "documentation")] @@ -167,8 +166,6 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream { Err(err) => return err.into_compile_error().into(), }; - let associated_data = derive_data.associated_data(); - let (reflect_impls, from_reflect_impl) = match derive_data { ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => ( impls::impl_struct(&struct_data), @@ -206,7 +203,6 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream { TokenStream::from(quote! { const _: () = { - #associated_data #reflect_impls #from_reflect_impl }; diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/serialization.rs b/crates/bevy_reflect/bevy_reflect_derive/src/serialization.rs index c12fe5715bfc19..4421d5d66e5efa 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/serialization.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/serialization.rs @@ -1,6 +1,6 @@ use crate::derive_data::StructField; use crate::field_attributes::ReflectIgnoreBehavior; -use proc_macro2::Ident; +use bevy_macro_utils::fq_std::{FQBox, FQDefault}; use quote::quote; use std::collections::HashMap; use syn::spanned::Spanned; @@ -48,15 +48,15 @@ impl SerializationDataDef { /// Returns a `TokenStream` containing an initialized `SerializationData` type. pub fn as_serialization_data(&self, bevy_reflect_path: &Path) -> proc_macro2::TokenStream { - let fields = self.skipped.iter().map(|(reflection_index, data)| { - let SkippedFieldDef { - associated_default_fn: default_fn, - } = data; - quote! {( - #reflection_index, - #bevy_reflect_path::serde::SkippedField::new(#default_fn) - )} - }); + let fields = + self.skipped + .iter() + .map(|(reflection_index, SkippedFieldDef { default_fn })| { + quote! {( + #reflection_index, + #bevy_reflect_path::serde::SkippedField::new(#default_fn) + )} + }); quote! { #bevy_reflect_path::serde::SerializationData::new( ::core::iter::IntoIterator::into_iter([#(#fields),*]) @@ -67,30 +67,19 @@ impl SerializationDataDef { /// Collected field data used to generate a `SkippedField` type. pub(crate) struct SkippedFieldDef { - /// The identifier of the [default function] generated by [`AssociatedData`]. + /// The default function for this field. /// - /// [default function]: crate::associated_data::AssociatedData::default_fn - /// [`AssociatedData`]: crate::associated_data::AssociatedData - associated_default_fn: Ident, + /// This is of type `fn() -> Box`. + default_fn: proc_macro2::TokenStream, } impl SkippedFieldDef { pub fn new(field: &StructField<'_>) -> Result { - let associated_default_fn = field - .associated_data - .default_fn() - .ok_or_else(|| { - syn::Error::new( - field.data.span(), - "internal error: field is missing an associated default function", - ) - })? - .sig - .ident - .clone(); - + let ty = &field.data.ty; Ok(Self { - associated_default_fn, + default_fn: quote! { + || { #FQBox::new(<#ty as #FQDefault>::default()) } + }, }) } }