From ac2ee03d0d284ce47f2648b57508ee4080a4412e Mon Sep 17 00:00:00 2001 From: soqb Date: Sat, 20 Jan 2024 15:13:24 +0000 Subject: [PATCH 1/7] impl_reflect --- .../src/container_attributes.rs | 17 +- .../bevy_reflect_derive/src/derive_data.rs | 54 +++++- .../bevy_reflect_derive/src/lib.rs | 180 ++++++++---------- .../bevy_reflect_derive/src/reflect_value.rs | 17 +- crates/bevy_reflect/src/impls/glam.rs | 72 +++---- crates/bevy_reflect/src/impls/rect.rs | 8 +- 6 files changed, 192 insertions(+), 156 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs index ee388731d7497..6a1f8a0fd11ec 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/container_attributes.rs @@ -5,11 +5,12 @@ //! the derive helper attribute for `Reflect`, which looks like: //! `#[reflect(PartialEq, Default, ...)]` and `#[reflect_value(PartialEq, Default, ...)]`. +use crate::derive_data::ReflectTraitToImpl; use crate::utility; use bevy_macro_utils::fq_std::{FQAny, FQOption}; use proc_macro2::{Ident, Span}; use quote::quote_spanned; -use syn::parse::{Parse, ParseStream}; +use syn::parse::ParseStream; use syn::punctuated::Punctuated; use syn::spanned::Spanned; use syn::token::Comma; @@ -217,7 +218,7 @@ pub(crate) struct ReflectTraits { impl ReflectTraits { pub fn from_metas( metas: Punctuated, - is_from_reflect_derive: bool, + trait_: ReflectTraitToImpl, ) -> Result { let mut traits = ReflectTraits::default(); for meta in &metas { @@ -294,7 +295,7 @@ impl ReflectTraits { // Override `lit` if this is a `FromReflect` derive. // This typically means a user is opting out of the default implementation // from the `Reflect` derive and using the `FromReflect` derive directly instead. - is_from_reflect_derive + (trait_ == ReflectTraitToImpl::FromReflect) .then(|| LitBool::new(true, Span::call_site())) .unwrap_or_else(|| lit.clone()) })?); @@ -311,6 +312,10 @@ impl ReflectTraits { Ok(traits) } + pub fn parse(input: ParseStream, trait_: ReflectTraitToImpl) -> syn::Result { + ReflectTraits::from_metas(Punctuated::parse_terminated(input)?, trait_) + } + /// Returns true if the given reflected trait name (i.e. `ReflectDefault` for `Default`) /// is registered for this type. pub fn contains(&self, name: &str) -> bool { @@ -418,12 +423,6 @@ impl ReflectTraits { } } -impl Parse for ReflectTraits { - fn parse(input: ParseStream) -> syn::Result { - ReflectTraits::from_metas(Punctuated::::parse_terminated(input)?, false) - } -} - /// Adds an identifier to a vector of identifiers if it is not already present. /// /// Returns an error if the identifier already exists in the list. 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 ce8777bbc041d..fa3059c6520bf 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs @@ -1,3 +1,5 @@ +use core::fmt; + use crate::container_attributes::{FromReflectAttrs, ReflectTraits}; use crate::field_attributes::{parse_field_attrs, ReflectFieldAttr}; use crate::type_path::parse_path_no_leading_colon; @@ -140,10 +142,46 @@ enum ReflectMode { Value, } +/// How the macro was invoked. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(crate) enum ReflectImplSource { + ImplRemoteType, + DeriveLocalType, +} + +/// Which trait the macro explicitly implements. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(crate) enum ReflectTraitToImpl { + Reflect, + FromReflect, + TypePath, +} + +/// The provenance of a macro invocation. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub(crate) struct ReflectProvenance { + pub source: ReflectImplSource, + pub trait_: ReflectTraitToImpl, +} + +impl fmt::Display for ReflectProvenance { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use self::{ReflectImplSource as S, ReflectTraitToImpl as T}; + let str = match (self.source, self.trait_) { + (S::ImplRemoteType, T::Reflect) => "`impl_reflect`", + (S::DeriveLocalType, T::Reflect) => "`#[derive(Reflect)]`", + (S::DeriveLocalType, T::FromReflect) => "`#[derive(FromReflect)]`", + (S::DeriveLocalType, T::TypePath) => "`#[derive(TypePath)]`", + (S::ImplRemoteType, T::FromReflect | T::TypePath) => unreachable!(), + }; + f.write_str(str) + } +} + impl<'a> ReflectDerive<'a> { pub fn from_input( input: &'a DeriveInput, - is_from_reflect_derive: bool, + provenance: ReflectProvenance, ) -> Result { let mut traits = ReflectTraits::default(); // Should indicate whether `#[reflect_value]` was used. @@ -169,7 +207,7 @@ impl<'a> ReflectDerive<'a> { reflect_mode = Some(ReflectMode::Normal); let new_traits = ReflectTraits::from_metas( meta_list.parse_args_with(Punctuated::::parse_terminated)?, - is_from_reflect_derive, + provenance.trait_, )?; traits.merge(new_traits)?; } @@ -184,7 +222,7 @@ impl<'a> ReflectDerive<'a> { reflect_mode = Some(ReflectMode::Value); let new_traits = ReflectTraits::from_metas( meta_list.parse_args_with(Punctuated::::parse_terminated)?, - is_from_reflect_derive, + provenance.trait_, )?; traits.merge(new_traits)?; } @@ -264,6 +302,16 @@ impl<'a> ReflectDerive<'a> { let meta = ReflectMeta::new(type_path, traits); + if provenance.source == ReflectImplSource::ImplRemoteType + && meta.traits.type_path_attrs().should_auto_derive() + && !meta.type_path().has_custom_path() + { + return Err(syn::Error::new( + meta.type_path().span(), + format!("a #[{TYPE_PATH_ATTRIBUTE_NAME} = \"...\"] attribute must be specified when using {provenance}") + )); + } + #[cfg(feature = "documentation")] let meta = meta.with_docs(doc); diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs index d0d59f3655a15..36b72016c1934 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs @@ -32,11 +32,10 @@ mod utility; use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct}; use container_attributes::ReflectTraits; -use derive_data::ReflectTypePath; +use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath}; use proc_macro::TokenStream; use quote::quote; use reflect_value::ReflectValueDef; -use syn::spanned::Spanned; use syn::{parse_macro_input, DeriveInput}; use type_path::NamedTypePathDef; @@ -45,6 +44,62 @@ pub(crate) static REFLECT_VALUE_ATTRIBUTE_NAME: &str = "reflect_value"; pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path"; pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name"; +/// Used both for [`impl_reflect`] and [`derive_reflect`]. +fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStream { + let derive_data = match ReflectDerive::from_input( + &ast, + ReflectProvenance { + source, + trait_: ReflectTraitToImpl::Reflect, + }, + ) { + Ok(data) => data, + Err(err) => return err.into_compile_error().into(), + }; + + let (reflect_impls, from_reflect_impl) = match derive_data { + ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => ( + impls::impl_struct(&struct_data), + if struct_data.meta().from_reflect().should_auto_derive() { + Some(from_reflect::impl_struct(&struct_data)) + } else { + None + }, + ), + ReflectDerive::TupleStruct(struct_data) => ( + impls::impl_tuple_struct(&struct_data), + if struct_data.meta().from_reflect().should_auto_derive() { + Some(from_reflect::impl_tuple_struct(&struct_data)) + } else { + None + }, + ), + ReflectDerive::Enum(enum_data) => ( + impls::impl_enum(&enum_data), + if enum_data.meta().from_reflect().should_auto_derive() { + Some(from_reflect::impl_enum(&enum_data)) + } else { + None + }, + ), + ReflectDerive::Value(meta) => ( + impls::impl_value(&meta), + if meta.from_reflect().should_auto_derive() { + Some(from_reflect::impl_value(&meta)) + } else { + None + }, + ), + }; + + TokenStream::from(quote! { + const _: () = { + #reflect_impls + #from_reflect_impl + }; + }) +} + /// The main derive macro used by `bevy_reflect` for deriving its `Reflect` trait. /// /// This macro can be used on all structs and enums (unions are not supported). @@ -159,53 +214,7 @@ pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name"; #[proc_macro_derive(Reflect, attributes(reflect, reflect_value, type_path, type_name))] pub fn derive_reflect(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - - let derive_data = match ReflectDerive::from_input(&ast, false) { - Ok(data) => data, - Err(err) => return err.into_compile_error().into(), - }; - - let (reflect_impls, from_reflect_impl) = match derive_data { - ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => ( - impls::impl_struct(&struct_data), - if struct_data.meta().from_reflect().should_auto_derive() { - Some(from_reflect::impl_struct(&struct_data)) - } else { - None - }, - ), - ReflectDerive::TupleStruct(struct_data) => ( - impls::impl_tuple_struct(&struct_data), - if struct_data.meta().from_reflect().should_auto_derive() { - Some(from_reflect::impl_tuple_struct(&struct_data)) - } else { - None - }, - ), - ReflectDerive::Enum(enum_data) => ( - impls::impl_enum(&enum_data), - if enum_data.meta().from_reflect().should_auto_derive() { - Some(from_reflect::impl_enum(&enum_data)) - } else { - None - }, - ), - ReflectDerive::Value(meta) => ( - impls::impl_value(&meta), - if meta.from_reflect().should_auto_derive() { - Some(from_reflect::impl_value(&meta)) - } else { - None - }, - ), - }; - - TokenStream::from(quote! { - const _: () = { - #reflect_impls - #from_reflect_impl - }; - }) + match_reflect_impls(ast, ReflectImplSource::DeriveLocalType) } /// Derives the `FromReflect` trait. @@ -238,7 +247,13 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream { pub fn derive_from_reflect(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let derive_data = match ReflectDerive::from_input(&ast, true) { + let derive_data = match ReflectDerive::from_input( + &ast, + ReflectProvenance { + source: ReflectImplSource::DeriveLocalType, + trait_: ReflectTraitToImpl::FromReflect, + }, + ) { Ok(data) => data, Err(err) => return err.into_compile_error().into(), }; @@ -277,7 +292,13 @@ pub fn derive_from_reflect(input: TokenStream) -> TokenStream { #[proc_macro_derive(TypePath, attributes(type_path, type_name))] pub fn derive_type_path(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let derive_data = match ReflectDerive::from_input(&ast, false) { + let derive_data = match ReflectDerive::from_input( + &ast, + ReflectProvenance { + source: ReflectImplSource::DeriveLocalType, + trait_: ReflectTraitToImpl::TypePath, + }, + ) { Ok(data) => data, Err(err) => return err.into_compile_error().into(), }; @@ -392,7 +413,7 @@ pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream { /// [deriving `Reflect`]: Reflect #[proc_macro] pub fn impl_reflect_value(input: TokenStream) -> TokenStream { - let def = parse_macro_input!(input as ReflectValueDef); + let def = parse_macro_input!(input with ReflectValueDef::parse_reflect); let default_name = &def.type_path.segments.last().unwrap().ident; let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() { @@ -425,8 +446,9 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream { /// the definitions of cannot be altered. /// /// This macro is an alternative to [`impl_reflect_value!`] and [`impl_from_reflect_value!`] -/// which implement foreign types as Value types. Note that there is no `impl_from_reflect_struct`, -/// as this macro will do the job of both. This macro implements them as `Struct` types, +/// which implement foreign types as Value types. Note that there is no `impl_from_reflect`, +/// as this macro will do the job of both. This macro implements them using one of the reflect +/// variant traits (`bevy_reflect::{Struct, TupleStruct, Enum}`, etc.), /// which have greater functionality. The type being reflected must be in scope, as you cannot /// qualify it in the macro as e.g. `bevy::prelude::Vec3`. /// @@ -443,7 +465,7 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream { /// ```ignore (bevy_reflect is not accessible from this crate) /// use bevy::prelude::Vec3; /// -/// impl_reflect_struct!( +/// impl_reflect!( /// #[reflect(PartialEq, Serialize, Deserialize, Default)] /// #[type_path = "bevy::prelude"] /// struct Vec3 { @@ -454,51 +476,9 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream { /// ); /// ``` #[proc_macro] -pub fn impl_reflect_struct(input: TokenStream) -> TokenStream { +pub fn impl_reflect(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - let derive_data = match ReflectDerive::from_input(&ast, false) { - Ok(data) => data, - Err(err) => return err.into_compile_error().into(), - }; - - let output = match derive_data { - ReflectDerive::Struct(struct_data) => { - if !struct_data.meta().type_path().has_custom_path() { - return syn::Error::new( - struct_data.meta().type_path().span(), - format!("a #[{TYPE_PATH_ATTRIBUTE_NAME} = \"...\"] attribute must be specified when using `impl_reflect_struct`") - ) - .into_compile_error() - .into(); - } - - let impl_struct = impls::impl_struct(&struct_data); - let impl_from_struct = from_reflect::impl_struct(&struct_data); - - quote! { - #impl_struct - #impl_from_struct - } - } - ReflectDerive::TupleStruct(..) => syn::Error::new( - ast.span(), - "impl_reflect_struct does not support tuple structs", - ) - .into_compile_error(), - ReflectDerive::UnitStruct(..) => syn::Error::new( - ast.span(), - "impl_reflect_struct does not support unit structs", - ) - .into_compile_error(), - _ => syn::Error::new(ast.span(), "impl_reflect_struct only supports structs") - .into_compile_error(), - }; - - TokenStream::from(quote! { - const _: () = { - #output - }; - }) + match_reflect_impls(ast, ReflectImplSource::ImplRemoteType) } /// A macro used to generate a `FromReflect` trait implementation for the given type. @@ -523,7 +503,7 @@ pub fn impl_reflect_struct(input: TokenStream) -> TokenStream { /// [derives `Reflect`]: Reflect #[proc_macro] pub fn impl_from_reflect_value(input: TokenStream) -> TokenStream { - let def = parse_macro_input!(input as ReflectValueDef); + let def = parse_macro_input!(input with ReflectValueDef::parse_from_reflect); let default_name = &def.type_path.segments.last().unwrap().ident; let type_path = if def.type_path.leading_colon.is_none() diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/reflect_value.rs b/crates/bevy_reflect/bevy_reflect_derive/src/reflect_value.rs index da06e78667bf7..dc20166a73ec3 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/reflect_value.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/reflect_value.rs @@ -1,6 +1,7 @@ use crate::container_attributes::ReflectTraits; +use crate::derive_data::ReflectTraitToImpl; use crate::type_path::CustomPathDef; -use syn::parse::{Parse, ParseStream}; +use syn::parse::ParseStream; use syn::token::Paren; use syn::{parenthesized, Attribute, Generics, Path}; @@ -32,8 +33,16 @@ pub(crate) struct ReflectValueDef { pub custom_path: Option, } -impl Parse for ReflectValueDef { - fn parse(input: ParseStream) -> syn::Result { +impl ReflectValueDef { + pub fn parse_reflect(input: ParseStream) -> syn::Result { + Self::parse(input, ReflectTraitToImpl::Reflect) + } + + pub fn parse_from_reflect(input: ParseStream) -> syn::Result { + Self::parse(input, ReflectTraitToImpl::FromReflect) + } + + fn parse(input: ParseStream, trait_: ReflectTraitToImpl) -> syn::Result { let attrs = input.call(Attribute::parse_outer)?; let custom_path = CustomPathDef::parse_parenthesized(input)?; @@ -46,7 +55,7 @@ impl Parse for ReflectValueDef { if input.peek(Paren) { let content; parenthesized!(content in input); - traits = Some(content.parse::()?); + traits = Some(ReflectTraits::parse(&content, trait_)?); } Ok(ReflectValueDef { attrs, diff --git a/crates/bevy_reflect/src/impls/glam.rs b/crates/bevy_reflect/src/impls/glam.rs index 64b3a1ea5220a..06823374b0c08 100644 --- a/crates/bevy_reflect/src/impls/glam.rs +++ b/crates/bevy_reflect/src/impls/glam.rs @@ -1,9 +1,9 @@ use crate as bevy_reflect; use crate::prelude::ReflectDefault; -use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value}; +use bevy_reflect_derive::{impl_reflect, impl_reflect_value}; use glam::*; -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct IVec2 { @@ -11,7 +11,7 @@ impl_reflect_struct!( y: i32, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct IVec3 { @@ -20,7 +20,7 @@ impl_reflect_struct!( z: i32, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct IVec4 { @@ -31,7 +31,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct I64Vec2 { @@ -40,7 +40,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct I64Vec3 { @@ -50,7 +50,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct I64Vec4 { @@ -61,7 +61,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct UVec2 { @@ -69,7 +69,7 @@ impl_reflect_struct!( y: u32, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct UVec3 { @@ -78,7 +78,7 @@ impl_reflect_struct!( z: u32, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct UVec4 { @@ -89,7 +89,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct U64Vec2 { @@ -97,7 +97,7 @@ impl_reflect_struct!( y: u64, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct U64Vec3 { @@ -106,7 +106,7 @@ impl_reflect_struct!( z: u64, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, Hash, PartialEq, Default)] #[type_path = "glam"] struct U64Vec4 { @@ -117,7 +117,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Vec2 { @@ -125,7 +125,7 @@ impl_reflect_struct!( y: f32, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Vec3 { @@ -134,7 +134,7 @@ impl_reflect_struct!( z: f32, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Vec3A { @@ -143,7 +143,7 @@ impl_reflect_struct!( z: f32, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Vec4 { @@ -154,7 +154,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct BVec2 { @@ -162,7 +162,7 @@ impl_reflect_struct!( y: bool, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct BVec3 { @@ -171,7 +171,7 @@ impl_reflect_struct!( z: bool, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct BVec4 { @@ -182,7 +182,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct DVec2 { @@ -190,7 +190,7 @@ impl_reflect_struct!( y: f64, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct DVec3 { @@ -199,7 +199,7 @@ impl_reflect_struct!( z: f64, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct DVec4 { @@ -210,7 +210,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Mat2 { @@ -218,7 +218,7 @@ impl_reflect_struct!( y_axis: Vec2, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Mat3 { @@ -227,7 +227,7 @@ impl_reflect_struct!( z_axis: Vec3, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Mat3A { @@ -236,7 +236,7 @@ impl_reflect_struct!( z_axis: Vec3A, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Mat4 { @@ -247,7 +247,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct DMat2 { @@ -255,7 +255,7 @@ impl_reflect_struct!( y_axis: DVec2, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct DMat3 { @@ -264,7 +264,7 @@ impl_reflect_struct!( z_axis: DVec3, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct DMat4 { @@ -275,7 +275,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Affine2 { @@ -283,7 +283,7 @@ impl_reflect_struct!( translation: Vec2, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Affine3A { @@ -292,7 +292,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct DAffine2 { @@ -300,7 +300,7 @@ impl_reflect_struct!( translation: DVec2, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct DAffine3 { @@ -309,7 +309,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct Quat { @@ -319,7 +319,7 @@ impl_reflect_struct!( w: f32, } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Default)] #[type_path = "glam"] struct DQuat { diff --git a/crates/bevy_reflect/src/impls/rect.rs b/crates/bevy_reflect/src/impls/rect.rs index 8f882eab27cc6..4389e0be1920f 100644 --- a/crates/bevy_reflect/src/impls/rect.rs +++ b/crates/bevy_reflect/src/impls/rect.rs @@ -2,9 +2,9 @@ use crate as bevy_reflect; use crate::prelude::ReflectDefault; use crate::{ReflectDeserialize, ReflectSerialize}; use bevy_math::{IRect, IVec2, Rect, URect, UVec2, Vec2}; -use bevy_reflect_derive::impl_reflect_struct; +use bevy_reflect_derive::impl_reflect; -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)] #[type_path = "bevy_math"] struct IRect { @@ -13,7 +13,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize, Default)] #[type_path = "bevy_math"] struct Rect { @@ -22,7 +22,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Hash, Serialize, Deserialize, Default)] #[type_path = "bevy_math"] struct URect { From 5fbcd1eab875af1c281417cb9953ba5fa30952f7 Mon Sep 17 00:00:00 2001 From: soqb Date: Sat, 20 Jan 2024 18:35:41 +0000 Subject: [PATCH 2/7] doc-fixes & tests --- .../bevy_reflect_derive/src/lib.rs | 3 ++ crates/bevy_reflect/src/lib.rs | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs index 36b72016c1934..53a7c10d51d60 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs @@ -45,6 +45,9 @@ pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path"; pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name"; /// Used both for [`impl_reflect`] and [`derive_reflect`]. +/// +/// [`impl_reflect`]: impl_reflect@macro +/// [`derive_reflect`]: derive_reflect@macro fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStream { let derive_data = match ReflectDerive::from_input( &ast, diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 231ab7d0e0c58..b6547af75e996 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -1995,6 +1995,38 @@ bevy_reflect::tests::Test { ); } + #[test] + fn assert_impl_reflect_on_all() { + struct Struct { + foo: (), + } + struct TupleStruct(()); + enum Enum { + Foo { foo: () }, + Bar(()), + } + + impl_reflect!( + #[type_path = "my_crate::foo"] + struct Struct { + foo: (), + } + ); + + impl_reflect!( + #[type_path = "my_crate::foo"] + struct TupleStruct(()); + ); + + impl_reflect!( + #[type_path = "my_crate::foo"] + enum Enum { + Foo { foo: () }, + Bar(()), + } + ); + } + #[cfg(feature = "glam")] mod glam { use super::*; From d827ce4f280637c9bbff2667e76e2d861980890c Mon Sep 17 00:00:00 2001 From: soqb Date: Sat, 20 Jan 2024 18:41:52 +0000 Subject: [PATCH 3/7] fix doc fixes --- crates/bevy_reflect/bevy_reflect_derive/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs index 53a7c10d51d60..b7ba2122d8b1d 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs @@ -46,8 +46,8 @@ pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name"; /// Used both for [`impl_reflect`] and [`derive_reflect`]. /// -/// [`impl_reflect`]: impl_reflect@macro -/// [`derive_reflect`]: derive_reflect@macro +/// [`impl_reflect`]: macro@impl_reflect +/// [`derive_reflect`]: macro@derive_reflect fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStream { let derive_data = match ReflectDerive::from_input( &ast, From 7a6e0667349db8dd6ed22040c6db43f3cdf9fc39 Mon Sep 17 00:00:00 2001 From: soqb Date: Sun, 21 Jan 2024 14:08:32 +0000 Subject: [PATCH 4/7] doc fix^3 --- crates/bevy_reflect/bevy_reflect_derive/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs index b7ba2122d8b1d..c01e8b6fcc3c4 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs @@ -47,7 +47,7 @@ pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name"; /// Used both for [`impl_reflect`] and [`derive_reflect`]. /// /// [`impl_reflect`]: macro@impl_reflect -/// [`derive_reflect`]: macro@derive_reflect +/// [`derive_reflect`]: derive_reflect() fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStream { let derive_data = match ReflectDerive::from_input( &ast, From ad027ea9017894096babea1b333ddf6a2b188d76 Mon Sep 17 00:00:00 2001 From: soqb Date: Tue, 30 Jan 2024 11:37:24 +0000 Subject: [PATCH 5/7] merge support --- .../src/impls/math/primitives2d.rs | 24 +++++++++---------- .../src/impls/math/primitives3d.rs | 24 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/crates/bevy_reflect/src/impls/math/primitives2d.rs b/crates/bevy_reflect/src/impls/math/primitives2d.rs index e584dee9ce721..29f93eb5611a0 100644 --- a/crates/bevy_reflect/src/impls/math/primitives2d.rs +++ b/crates/bevy_reflect/src/impls/math/primitives2d.rs @@ -1,7 +1,7 @@ use crate as bevy_reflect; use crate::{ReflectDeserialize, ReflectSerialize}; use bevy_math::{primitives::*, Vec2}; -use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value}; +use bevy_reflect_derive::{impl_reflect, impl_reflect_value}; impl_reflect_value!(::bevy_math::primitives::Direction2d( Debug, @@ -10,7 +10,7 @@ impl_reflect_value!(::bevy_math::primitives::Direction2d( Deserialize )); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Circle { @@ -18,7 +18,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Ellipse { @@ -26,7 +26,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Plane2d { @@ -34,7 +34,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Line2d { @@ -42,7 +42,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Segment2d { @@ -51,7 +51,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq)] #[type_path = "bevy_math::primitives"] struct Polyline2d { @@ -59,7 +59,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Triangle2d { @@ -67,7 +67,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Rectangle { @@ -75,7 +75,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq)] #[type_path = "bevy_math::primitives"] struct Polygon { @@ -83,7 +83,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct RegularPolygon { @@ -92,7 +92,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Capsule2d { diff --git a/crates/bevy_reflect/src/impls/math/primitives3d.rs b/crates/bevy_reflect/src/impls/math/primitives3d.rs index 9724ae19a1ffc..3c986fc1a63fc 100644 --- a/crates/bevy_reflect/src/impls/math/primitives3d.rs +++ b/crates/bevy_reflect/src/impls/math/primitives3d.rs @@ -1,7 +1,7 @@ use crate as bevy_reflect; use crate::{ReflectDeserialize, ReflectSerialize}; use bevy_math::{primitives::*, Vec3}; -use bevy_reflect_derive::{impl_reflect_struct, impl_reflect_value}; +use bevy_reflect_derive::{impl_reflect, impl_reflect_value}; impl_reflect_value!(::bevy_math::primitives::Direction3d( Debug, @@ -10,7 +10,7 @@ impl_reflect_value!(::bevy_math::primitives::Direction3d( Deserialize )); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Sphere { @@ -18,7 +18,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Plane3d { @@ -26,7 +26,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Line3d { @@ -34,7 +34,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Segment3d { @@ -43,7 +43,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq)] #[type_path = "bevy_math::primitives"] struct Polyline3d { @@ -51,7 +51,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Cuboid { @@ -59,7 +59,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Cylinder { @@ -68,7 +68,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Capsule3d { @@ -77,7 +77,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Cone { @@ -86,7 +86,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct ConicalFrustum { @@ -96,7 +96,7 @@ impl_reflect_struct!( } ); -impl_reflect_struct!( +impl_reflect!( #[reflect(Debug, PartialEq, Serialize, Deserialize)] #[type_path = "bevy_math::primitives"] struct Torus { From 07e331732282cf41ec70930da42dee5aac7f94b4 Mon Sep 17 00:00:00 2001 From: soqb Date: Tue, 30 Jan 2024 11:38:05 +0000 Subject: [PATCH 6/7] fix test --- crates/bevy_reflect/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index bd1511402c907..9447cd41a6701 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -1565,7 +1565,7 @@ mod tests { let info = ::type_info(); assert_eq!( - Some(" Some struct.\n\n # Example\n\n ```ignore\n let some_struct = SomeStruct;\n ```"), + Some(" Some struct.\n\n # Example\n\n ```ignore (This is only used for a unit test, no need to doc test)\n let some_struct = SomeStruct;\n ```"), info.docs() ); From 07afa74939702021d9f5b652f44ca24dbc70dc9e Mon Sep 17 00:00:00 2001 From: radiish Date: Tue, 30 Jan 2024 11:54:50 +0000 Subject: [PATCH 7/7] simplify `type_path_attrs` call Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com> --- crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6e8df7319fe93..804584cea0bd3 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs @@ -297,7 +297,7 @@ impl<'a> ReflectDerive<'a> { let meta = ReflectMeta::new(type_path, traits); if provenance.source == ReflectImplSource::ImplRemoteType - && meta.traits.type_path_attrs().should_auto_derive() + && meta.type_path_attrs().should_auto_derive() && !meta.type_path().has_custom_path() { return Err(syn::Error::new(