#![cfg_attr(docsrs, feature(doc_auto_cfg))]12//! This crate contains macros used by Bevy's `Reflect` API.3//!4//! The main export of this crate is the derive macro for [`Reflect`]. This allows5//! types to easily implement `Reflect` along with other `bevy_reflect` traits,6//! such as `Struct`, `GetTypeRegistration`, and more— all with a single derive!7//!8//! Some other noteworthy exports include the derive macros for [`FromReflect`] and9//! [`TypePath`], as well as the [`reflect_trait`] attribute macro.10//!11//! [`Reflect`]: crate::derive_reflect12//! [`FromReflect`]: crate::derive_from_reflect13//! [`TypePath`]: crate::derive_type_path14//! [`reflect_trait`]: macro@reflect_trait1516extern crate proc_macro;1718mod attribute_parser;19mod container_attributes;20mod custom_attributes;21mod derive_data;22#[cfg(feature = "documentation")]23mod documentation;24mod enum_utility;25mod field_attributes;26mod from_reflect;27mod generics;28mod ident;29mod impls;30mod meta;31mod reflect_opaque;32mod registration;33mod remote;34mod result_sifter;35mod serialization;36mod string_expr;37mod struct_utility;38mod trait_reflection;39mod type_path;40mod where_clause_options;4142use std::{fs, io::Read, path::PathBuf};4344use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct};45use container_attributes::ContainerAttributes;46use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath};47use proc_macro::TokenStream;48use quote::quote;49use reflect_opaque::ReflectOpaqueDef;50use syn::{parse_macro_input, DeriveInput};51use type_path::NamedTypePathDef;5253pub(crate) static REFLECT_ATTRIBUTE_NAME: &str = "reflect";54pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path";55pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";5657/// Used both for [`impl_reflect`] and [`derive_reflect`].58///59/// [`impl_reflect`]: macro@impl_reflect60/// [`derive_reflect`]: derive_reflect()61fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStream {62let derive_data = match ReflectDerive::from_input(63&ast,64ReflectProvenance {65source,66trait_: ReflectTraitToImpl::Reflect,67},68) {69Ok(data) => data,70Err(err) => return err.into_compile_error().into(),71};7273let assertions = impls::impl_assertions(&derive_data);7475let (reflect_impls, from_reflect_impl) = match derive_data {76ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => (77impls::impl_struct(&struct_data),78if struct_data.meta().from_reflect().should_auto_derive() {79Some(from_reflect::impl_struct(&struct_data))80} else {81None82},83),84ReflectDerive::TupleStruct(struct_data) => (85impls::impl_tuple_struct(&struct_data),86if struct_data.meta().from_reflect().should_auto_derive() {87Some(from_reflect::impl_tuple_struct(&struct_data))88} else {89None90},91),92ReflectDerive::Enum(enum_data) => (93impls::impl_enum(&enum_data),94if enum_data.meta().from_reflect().should_auto_derive() {95Some(from_reflect::impl_enum(&enum_data))96} else {97None98},99),100ReflectDerive::Opaque(meta) => (101impls::impl_opaque(&meta),102if meta.from_reflect().should_auto_derive() {103Some(from_reflect::impl_opaque(&meta))104} else {105None106},107),108};109110TokenStream::from(quote! {111const _: () = {112#reflect_impls113114#from_reflect_impl115116#assertions117};118})119}120121/// The main derive macro used by `bevy_reflect` for deriving its `Reflect` trait.122///123/// This macro can be used on all structs and enums (unions are not supported).124/// It will automatically generate implementations for `Reflect`, `Typed`, `GetTypeRegistration`, and `FromReflect`.125/// And, depending on the item's structure, will either implement `Struct`, `TupleStruct`, or `Enum`.126///127/// See the [`FromReflect`] derive macro for more information on how to customize the `FromReflect` implementation.128///129/// # Container Attributes130///131/// This macro comes with some helper attributes that can be added to the container item132/// in order to provide additional functionality or alter the generated implementations.133///134/// In addition to those listed, this macro can also use the attributes for [`TypePath`] derives.135///136/// ## `#[reflect(Ident)]`137///138/// The `#[reflect(Ident)]` attribute is used to add type data registrations to the `GetTypeRegistration`139/// implementation corresponding to the given identifier, prepended by `Reflect`.140///141/// For example, `#[reflect(Foo, Bar)]` would add two registrations:142/// one for `ReflectFoo` and another for `ReflectBar`.143/// This assumes these types are indeed in-scope wherever this macro is called.144///145/// This is often used with traits that have been marked by the [`#[reflect_trait]`](macro@reflect_trait)146/// macro in order to register the type's implementation of that trait.147///148/// ### Default Registrations149///150/// The following types are automatically registered when deriving `Reflect`:151///152/// * `ReflectFromReflect` (unless opting out of `FromReflect`)153/// * `SerializationData`154/// * `ReflectFromPtr`155///156/// ### Special Identifiers157///158/// There are a few "special" identifiers that work a bit differently:159///160/// * `#[reflect(Clone)]` will force the implementation of `Reflect::reflect_clone` to rely on161/// the type's [`Clone`] implementation.162/// A custom implementation may be provided using `#[reflect(Clone(my_clone_func))]` where163/// `my_clone_func` is the path to a function matching the signature:164/// `(&Self) -> Self`.165/// * `#[reflect(Debug)]` will force the implementation of `Reflect::reflect_debug` to rely on166/// the type's [`Debug`] implementation.167/// A custom implementation may be provided using `#[reflect(Debug(my_debug_func))]` where168/// `my_debug_func` is the path to a function matching the signature:169/// `(&Self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result`.170/// * `#[reflect(PartialEq)]` will force the implementation of `Reflect::reflect_partial_eq` to rely on171/// the type's [`PartialEq`] implementation.172/// A custom implementation may be provided using `#[reflect(PartialEq(my_partial_eq_func))]` where173/// `my_partial_eq_func` is the path to a function matching the signature:174/// `(&Self, value: &dyn #bevy_reflect_path::Reflect) -> bool`.175/// * `#[reflect(Hash)]` will force the implementation of `Reflect::reflect_hash` to rely on176/// the type's [`Hash`] implementation.177/// A custom implementation may be provided using `#[reflect(Hash(my_hash_func))]` where178/// `my_hash_func` is the path to a function matching the signature: `(&Self) -> u64`.179/// * `#[reflect(Default)]` will register the `ReflectDefault` type data as normal.180/// However, it will also affect how certain other operations are performed in order181/// to improve performance and/or robustness.182/// An example of where this is used is in the [`FromReflect`] derive macro,183/// where adding this attribute will cause the `FromReflect` implementation to create184/// a base value using its [`Default`] implementation avoiding issues with ignored fields185/// (for structs and tuple structs only).186///187/// ## `#[reflect(opaque)]`188///189/// The `#[reflect(opaque)]` attribute denotes that the item should implement `Reflect` as an opaque type,190/// hiding its structure and fields from the reflection API.191/// This means that it will forgo implementing `Struct`, `TupleStruct`, or `Enum`.192///193/// Furthermore, it requires that the type implements [`Clone`].194/// If planning to serialize this type using the reflection serializers,195/// then the `Serialize` and `Deserialize` traits will need to be implemented and registered as well.196///197/// ## `#[reflect(from_reflect = false)]`198///199/// This attribute will opt-out of the default `FromReflect` implementation.200///201/// This is useful for when a type can't or shouldn't implement `FromReflect`,202/// or if a manual implementation is desired.203///204/// Note that in the latter case, `ReflectFromReflect` will no longer be automatically registered.205///206/// ## `#[reflect(type_path = false)]`207///208/// This attribute will opt-out of the default `TypePath` implementation.209///210/// This is useful for when a type can't or shouldn't implement `TypePath`,211/// or if a manual implementation is desired.212///213/// ## `#[reflect(no_field_bounds)]`214///215/// This attribute will opt-out of the default trait bounds added to all field types216/// for the generated reflection trait impls.217///218/// Normally, all fields will have the bounds `TypePath`, and either `FromReflect` or `Reflect`219/// depending on if `#[reflect(from_reflect = false)]` is used.220/// However, this might not always be desirable, and so this attribute may be used to remove those bounds.221///222/// ### Example223///224/// If a type is recursive the default bounds will cause an overflow error when building:225///226/// ```ignore (bevy_reflect is not accessible from this crate)227/// #[derive(Reflect)] // ERROR: overflow evaluating the requirement `Foo: FromReflect`228/// struct Foo {229/// foo: Vec<Foo>,230/// }231///232/// // Generates a where clause like:233/// // impl bevy_reflect::Reflect for Foo234/// // where235/// // Foo: Any + Send + Sync,236/// // Vec<Foo>: FromReflect + TypePath + MaybeTyped + RegisterForReflection,237/// ```238///239/// In this case, `Foo` is given the bounds `Vec<Foo>: FromReflect + ...`,240/// which requires that `Foo` implements `FromReflect`,241/// which requires that `Vec<Foo>` implements `FromReflect`,242/// and so on, resulting in the error.243///244/// To fix this, we can add `#[reflect(no_field_bounds)]` to `Foo` to remove the bounds on `Vec<Foo>`:245///246/// ```ignore (bevy_reflect is not accessible from this crate)247/// #[derive(Reflect)]248/// #[reflect(no_field_bounds)]249/// struct Foo {250/// foo: Vec<Foo>,251/// }252///253/// // Generates a where clause like:254/// // impl bevy_reflect::Reflect for Foo255/// // where256/// // Self: Any + Send + Sync,257/// ```258///259/// ## `#[reflect(where T: Trait, U::Assoc: Trait, ...)]`260///261/// This attribute can be used to add additional bounds to the generated reflection trait impls.262///263/// This is useful for when a type needs certain bounds only applied to the reflection impls264/// that are not otherwise automatically added by the derive macro.265///266/// ### Example267///268/// In the example below, we want to enforce that `T::Assoc: List` is required in order for269/// `Foo<T>` to be reflectable, but we don't want it to prevent `Foo<T>` from being used270/// in places where `T::Assoc: List` is not required.271///272/// ```ignore273/// trait Trait {274/// type Assoc;275/// }276///277/// #[derive(Reflect)]278/// #[reflect(where T::Assoc: List)]279/// struct Foo<T: Trait> where T::Assoc: Default {280/// value: T::Assoc,281/// }282///283/// // Generates a where clause like:284/// //285/// // impl<T: Trait> bevy_reflect::Reflect for Foo<T>286/// // where287/// // Foo<T>: Any + Send + Sync,288/// // T::Assoc: Default,289/// // T: TypePath,290/// // T::Assoc: FromReflect + TypePath + MaybeTyped + RegisterForReflection,291/// // T::Assoc: List,292/// // {/* ... */}293/// ```294///295/// ## `#[reflect(@...)]`296///297/// This attribute can be used to register custom attributes to the type's `TypeInfo`.298///299/// It accepts any expression after the `@` symbol that resolves to a value which implements `Reflect`.300///301/// Any number of custom attributes may be registered, however, each the type of each attribute must be unique.302/// If two attributes of the same type are registered, the last one will overwrite the first.303///304/// ### Example305///306/// ```ignore307/// #[derive(Reflect)]308/// struct Required;309///310/// #[derive(Reflect)]311/// struct EditorTooltip(String);312///313/// impl EditorTooltip {314/// fn new(text: &str) -> Self {315/// Self(text.to_string())316/// }317/// }318///319/// #[derive(Reflect)]320/// // Specify a "required" status and tooltip:321/// #[reflect(@Required, @EditorTooltip::new("An ID is required!"))]322/// struct Id(u8);323/// ```324/// ## `#[reflect(no_auto_register)]`325///326/// This attribute will opt-out of the automatic reflect type registration.327///328/// All non-generic types annotated with `#[derive(Reflect)]` are usually automatically registered on app startup.329/// If this behavior is not desired, this attribute may be used to disable it for the annotated type.330///331/// # Field Attributes332///333/// Along with the container attributes, this macro comes with some attributes that may be applied334/// to the contained fields themselves.335///336/// ## `#[reflect(ignore)]`337///338/// This attribute simply marks a field to be ignored by the reflection API.339///340/// This allows fields to completely opt-out of reflection,341/// which may be useful for maintaining invariants, keeping certain data private,342/// or allowing the use of types that do not implement `Reflect` within the container.343///344/// ## `#[reflect(skip_serializing)]`345///346/// This works similar to `#[reflect(ignore)]`, but rather than opting out of _all_ of reflection,347/// it simply opts the field out of both serialization and deserialization.348/// This can be useful when a field should be accessible via reflection, but may not make349/// sense in a serialized form, such as computed data.350///351/// What this does is register the `SerializationData` type within the `GetTypeRegistration` implementation,352/// which will be used by the reflection serializers to determine whether or not the field is serializable.353///354/// ## `#[reflect(clone)]`355///356/// This attribute affects the `Reflect::reflect_clone` implementation.357///358/// Without this attribute, the implementation will rely on the field's own `Reflect::reflect_clone` implementation.359/// When this attribute is present, the implementation will instead use the field's `Clone` implementation directly.360///361/// The attribute may also take the path to a custom function like `#[reflect(clone = "path::to::my_clone_func")]`,362/// where `my_clone_func` matches the signature `(&Self) -> Self`.363///364/// This attribute does nothing if the containing struct/enum has the `#[reflect(Clone)]` attribute.365///366/// ## `#[reflect(@...)]`367///368/// This attribute can be used to register custom attributes to the field's `TypeInfo`.369///370/// It accepts any expression after the `@` symbol that resolves to a value which implements `Reflect`.371///372/// Any number of custom attributes may be registered, however, each the type of each attribute must be unique.373/// If two attributes of the same type are registered, the last one will overwrite the first.374///375/// ### Example376///377/// ```ignore378/// #[derive(Reflect)]379/// struct EditorTooltip(String);380///381/// impl EditorTooltip {382/// fn new(text: &str) -> Self {383/// Self(text.to_string())384/// }385/// }386///387/// #[derive(Reflect)]388/// struct Slider {389/// // Specify a custom range and tooltip:390/// #[reflect(@0.0..=1.0, @EditorTooltip::new("Must be between 0 and 1"))]391/// value: f32,392/// }393/// ```394///395/// [`reflect_trait`]: macro@reflect_trait396#[proc_macro_derive(Reflect, attributes(reflect, type_path, type_name))]397pub fn derive_reflect(input: TokenStream) -> TokenStream {398let ast = parse_macro_input!(input as DeriveInput);399match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)400}401402/// Derives the `FromReflect` trait.403///404/// # Field Attributes405///406/// ## `#[reflect(ignore)]`407///408/// The `#[reflect(ignore)]` attribute is shared with the [`#[derive(Reflect)]`](Reflect) macro and has much of the same409/// functionality in that it denotes that a field will be ignored by the reflection API.410///411/// The only major difference is that using it with this derive requires that the field implements [`Default`].412/// Without this requirement, there would be no way for `FromReflect` to automatically construct missing fields413/// that have been ignored.414///415/// ## `#[reflect(default)]`416///417/// If a field cannot be read, this attribute specifies a default value to be used in its place.418///419/// By default, this attribute denotes that the field's type implements [`Default`].420/// However, it can also take in a path string to a user-defined function that will return the default value.421/// This takes the form: `#[reflect(default = "path::to::my_function")]` where `my_function` is a parameterless422/// function that must return some default value for the type.423///424/// Specifying a custom default can be used to give different fields their own specialized defaults,425/// or to remove the `Default` requirement on fields marked with `#[reflect(ignore)]`.426/// Additionally, either form of this attribute can be used to fill in fields that are simply missing,427/// such as when converting a partially-constructed dynamic type to a concrete one.428#[proc_macro_derive(FromReflect, attributes(reflect))]429pub fn derive_from_reflect(input: TokenStream) -> TokenStream {430let ast = parse_macro_input!(input as DeriveInput);431432let derive_data = match ReflectDerive::from_input(433&ast,434ReflectProvenance {435source: ReflectImplSource::DeriveLocalType,436trait_: ReflectTraitToImpl::FromReflect,437},438) {439Ok(data) => data,440Err(err) => return err.into_compile_error().into(),441};442443let from_reflect_impl = match derive_data {444ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => {445from_reflect::impl_struct(&struct_data)446}447ReflectDerive::TupleStruct(struct_data) => from_reflect::impl_tuple_struct(&struct_data),448ReflectDerive::Enum(meta) => from_reflect::impl_enum(&meta),449ReflectDerive::Opaque(meta) => from_reflect::impl_opaque(&meta),450};451452TokenStream::from(quote! {453const _: () = {454#from_reflect_impl455};456})457}458459/// Derives the `TypePath` trait, providing a stable alternative to [`std::any::type_name`].460///461/// # Container Attributes462///463/// ## `#[type_path = "my_crate::foo"]`464///465/// Optionally specifies a custom module path to use instead of [`module_path`].466///467/// This path does not include the final identifier.468///469/// ## `#[type_name = "RenamedType"]`470///471/// Optionally specifies a new terminating identifier for `TypePath`.472///473/// To use this attribute, `#[type_path = "..."]` must also be specified.474#[proc_macro_derive(TypePath, attributes(type_path, type_name))]475pub fn derive_type_path(input: TokenStream) -> TokenStream {476let ast = parse_macro_input!(input as DeriveInput);477let derive_data = match ReflectDerive::from_input(478&ast,479ReflectProvenance {480source: ReflectImplSource::DeriveLocalType,481trait_: ReflectTraitToImpl::TypePath,482},483) {484Ok(data) => data,485Err(err) => return err.into_compile_error().into(),486};487488let type_path_impl = impls::impl_type_path(derive_data.meta());489490TokenStream::from(quote! {491const _: () = {492#type_path_impl493};494})495}496497/// A macro that automatically generates type data for traits, which their implementors can then register.498///499/// The output of this macro is a struct that takes reflected instances of the implementor's type500/// and returns the value as a trait object.501/// Because of this, **it can only be used on [object-safe] traits.**502///503/// For a trait named `MyTrait`, this will generate the struct `ReflectMyTrait`.504/// The generated struct can be created using `FromType` with any type that implements the trait.505/// The creation and registration of this generated struct as type data can be automatically handled506/// by [`#[derive(Reflect)]`](Reflect).507///508/// # Example509///510/// ```ignore (bevy_reflect is not accessible from this crate)511/// # use std::any::TypeId;512/// # use bevy_reflect_derive::{Reflect, reflect_trait};513/// #[reflect_trait] // Generates `ReflectMyTrait`514/// trait MyTrait {515/// fn print(&self) -> &str;516/// }517///518/// #[derive(Reflect)]519/// #[reflect(MyTrait)] // Automatically registers `ReflectMyTrait`520/// struct SomeStruct;521///522/// impl MyTrait for SomeStruct {523/// fn print(&self) -> &str {524/// "Hello, World!"525/// }526/// }527///528/// // We can create the type data manually if we wanted:529/// let my_trait: ReflectMyTrait = FromType::<SomeStruct>::from_type();530///531/// // Or we can simply get it from the registry:532/// let mut registry = TypeRegistry::default();533/// registry.register::<SomeStruct>();534/// let my_trait = registry535/// .get_type_data::<ReflectMyTrait>(TypeId::of::<SomeStruct>())536/// .unwrap();537///538/// // Then use it on reflected data539/// let reflected: Box<dyn Reflect> = Box::new(SomeStruct);540/// let reflected_my_trait: &dyn MyTrait = my_trait.get(&*reflected).unwrap();541/// assert_eq!("Hello, World!", reflected_my_trait.print());542/// ```543///544/// [object-safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety545#[proc_macro_attribute]546pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream {547trait_reflection::reflect_trait(&args, input)548}549550/// Generates a wrapper type that can be used to "derive `Reflect`" for remote types.551///552/// This works by wrapping the remote type in a generated wrapper that has the `#[repr(transparent)]` attribute.553/// This allows the two types to be safely [transmuted] back-and-forth.554///555/// # Defining the Wrapper556///557/// Before defining the wrapper type, please note that it is _required_ that all fields of the remote type are public.558/// The generated code will, at times, need to access or mutate them,559/// and we do not currently have a way to assign getters/setters to each field560/// (but this may change in the future).561///562/// The wrapper definition should match the remote type 1-to-1.563/// This includes the naming and ordering of the fields and variants.564///565/// Generics and lifetimes do _not_ need to have the same names, however, they _do_ need to follow the same order.566/// Additionally, whether generics are inlined or placed in a where clause should not matter.567///568/// Lastly, all macros and doc-comments should be placed __below__ this attribute.569/// If they are placed above, they will not be properly passed to the generated wrapper type.570///571/// # Example572///573/// Given a remote type, `RemoteType`:574///575/// ```576/// #[derive(Default)]577/// struct RemoteType<T>578/// where579/// T: Default + Clone,580/// {581/// pub foo: T,582/// pub bar: usize583/// }584/// ```585///586/// We would define our wrapper type as such:587///588/// ```ignore589/// use external_crate::RemoteType;590///591/// #[reflect_remote(RemoteType<T>)]592/// #[derive(Default)]593/// pub struct WrapperType<T: Default + Clone> {594/// pub foo: T,595/// pub bar: usize596/// }597/// ```598///599/// Apart from all the reflection trait implementations, this generates something like the following:600///601/// ```ignore602/// use external_crate::RemoteType;603///604/// #[derive(Default)]605/// #[repr(transparent)]606/// pub struct Wrapper<T: Default + Clone>(RemoteType<T>);607/// ```608///609/// # Usage as a Field610///611/// You can tell `Reflect` to use a remote type's wrapper internally on fields of a struct or enum.612/// This allows the real type to be used as usual while `Reflect` handles everything internally.613/// To do this, add the `#[reflect(remote = path::to::MyType)]` attribute to your field:614///615/// ```ignore616/// #[derive(Reflect)]617/// struct SomeStruct {618/// #[reflect(remote = RemoteTypeWrapper)]619/// data: RemoteType620/// }621/// ```622///623/// ## Safety624///625/// When using the `#[reflect(remote = path::to::MyType)]` field attribute, be sure you are defining the correct wrapper type.626/// Internally, this field will be unsafely [transmuted], and is only sound if using a wrapper generated for the remote type.627/// This also means keeping your wrapper definitions up-to-date with the remote types.628///629/// [transmuted]: std::mem::transmute630#[proc_macro_attribute]631pub fn reflect_remote(args: TokenStream, input: TokenStream) -> TokenStream {632remote::reflect_remote(args, input)633}634635/// A macro used to generate reflection trait implementations for the given type.636///637/// This is functionally the same as [deriving `Reflect`] using the `#[reflect(opaque)]` container attribute.638///639/// The only reason for this macro's existence is so that `bevy_reflect` can easily implement the reflection traits640/// on primitives and other opaque types internally.641///642/// Since this macro also implements `TypePath`, the type path must be explicit.643/// See [`impl_type_path!`] for the exact syntax.644///645/// # Examples646///647/// Types can be passed with or without registering type data:648///649/// ```ignore (bevy_reflect is not accessible from this crate)650/// impl_reflect_opaque!(my_crate::Foo);651/// impl_reflect_opaque!(my_crate::Bar(Debug, Default, Serialize, Deserialize));652/// ```653///654/// Generic types can also specify their parameters and bounds:655///656/// ```ignore (bevy_reflect is not accessible from this crate)657/// impl_reflect_opaque!(my_crate::Foo<T1, T2: Baz> where T1: Bar (Default, Serialize, Deserialize));658/// ```659///660/// Custom type paths can be specified:661///662/// ```ignore (bevy_reflect is not accessible from this crate)663/// impl_reflect_opaque!((in not_my_crate as NotFoo) Foo(Debug, Default));664/// ```665///666/// [deriving `Reflect`]: Reflect667#[proc_macro]668pub fn impl_reflect_opaque(input: TokenStream) -> TokenStream {669let def = parse_macro_input!(input with ReflectOpaqueDef::parse_reflect);670671let default_name = &def.type_path.segments.last().unwrap().ident;672let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() {673ReflectTypePath::Primitive(default_name)674} else {675ReflectTypePath::External {676path: &def.type_path,677custom_path: def.custom_path.map(|path| path.into_path(default_name)),678generics: &def.generics,679}680};681682let meta = ReflectMeta::new(type_path, def.traits.unwrap_or_default());683684#[cfg(feature = "documentation")]685let meta = meta.with_docs(documentation::Documentation::from_attributes(&def.attrs));686687let reflect_impls = impls::impl_opaque(&meta);688let from_reflect_impl = from_reflect::impl_opaque(&meta);689690TokenStream::from(quote! {691const _: () = {692#reflect_impls693#from_reflect_impl694};695})696}697698/// A replacement for `#[derive(Reflect)]` to be used with foreign types which699/// the definitions of cannot be altered.700///701/// This macro is an alternative to [`impl_reflect_opaque!`] and [`impl_from_reflect_opaque!`]702/// which implement foreign types as Opaque types. Note that there is no `impl_from_reflect`,703/// as this macro will do the job of both. This macro implements them using one of the reflect704/// variant traits (`bevy_reflect::{Struct, TupleStruct, Enum}`, etc.),705/// which have greater functionality. The type being reflected must be in scope, as you cannot706/// qualify it in the macro as e.g. `bevy::prelude::Vec3`.707///708/// It is necessary to add a `#[type_path = "my_crate::foo"]` attribute to all types.709///710/// It may be necessary to add `#[reflect(Default)]` for some types, specifically non-constructible711/// foreign types. Without `Default` reflected for such types, you will usually get an arcane712/// error message and fail to compile. If the type does not implement `Default`, it may not713/// be possible to reflect without extending the macro.714///715///716/// # Example717/// Implementing `Reflect` for `bevy::prelude::Vec3` as a struct type:718/// ```ignore (bevy_reflect is not accessible from this crate)719/// use bevy::prelude::Vec3;720///721/// impl_reflect!(722/// #[reflect(PartialEq, Serialize, Deserialize, Default)]723/// #[type_path = "bevy::prelude"]724/// struct Vec3 {725/// x: f32,726/// y: f32,727/// z: f32728/// }729/// );730/// ```731#[proc_macro]732pub fn impl_reflect(input: TokenStream) -> TokenStream {733let ast = parse_macro_input!(input as DeriveInput);734match_reflect_impls(ast, ReflectImplSource::ImplRemoteType)735}736737/// A macro used to generate a `FromReflect` trait implementation for the given type.738///739/// This is functionally the same as [deriving `FromReflect`] on a type that [derives `Reflect`] using740/// the `#[reflect(opaque)]` container attribute.741///742/// The only reason this macro exists is so that `bevy_reflect` can easily implement `FromReflect` on743/// primitives and other opaque types internally.744///745/// Please note that this macro will not work with any type that [derives `Reflect`] normally746/// or makes use of the [`impl_reflect_opaque!`] macro, as those macros also implement `FromReflect`747/// by default.748///749/// # Examples750///751/// ```ignore (bevy_reflect is not accessible from this crate)752/// impl_from_reflect_opaque!(foo<T1, T2: Baz> where T1: Bar);753/// ```754///755/// [deriving `FromReflect`]: FromReflect756/// [derives `Reflect`]: Reflect757#[proc_macro]758pub fn impl_from_reflect_opaque(input: TokenStream) -> TokenStream {759let def = parse_macro_input!(input with ReflectOpaqueDef::parse_from_reflect);760761let default_name = &def.type_path.segments.last().unwrap().ident;762let type_path = if def.type_path.leading_colon.is_none()763&& def.custom_path.is_none()764&& def.generics.params.is_empty()765{766ReflectTypePath::Primitive(default_name)767} else {768ReflectTypePath::External {769path: &def.type_path,770custom_path: def.custom_path.map(|alias| alias.into_path(default_name)),771generics: &def.generics,772}773};774775let from_reflect_impl =776from_reflect::impl_opaque(&ReflectMeta::new(type_path, def.traits.unwrap_or_default()));777778TokenStream::from(quote! {779const _: () = {780#from_reflect_impl781};782})783}784785/// A replacement for [deriving `TypePath`] for use on foreign types.786///787/// Since (unlike the derive) this macro may be invoked in a different module to where the type is defined,788/// it requires an 'absolute' path definition.789///790/// Specifically, a leading `::` denoting a global path must be specified791/// or a preceding `(in my_crate::foo)` to specify the custom path must be used.792///793/// # Examples794///795/// Implementing `TypePath` on a foreign type:796/// ```ignore (bevy_reflect is not accessible from this crate)797/// impl_type_path!(::foreign_crate::foo::bar::Baz);798/// ```799///800/// On a generic type (this can also accept trait bounds):801/// ```ignore (bevy_reflect is not accessible from this crate)802/// impl_type_path!(::foreign_crate::Foo<T>);803/// impl_type_path!(::foreign_crate::Goo<T: ?Sized>);804/// ```805///806/// On a primitive (note this will not compile for a non-primitive type):807/// ```ignore (bevy_reflect is not accessible from this crate)808/// impl_type_path!(bool);809/// ```810///811/// With a custom type path:812/// ```ignore (bevy_reflect is not accessible from this crate)813/// impl_type_path!((in other_crate::foo::bar) Baz);814/// ```815///816/// With a custom type path and a custom type name:817/// ```ignore (bevy_reflect is not accessible from this crate)818/// impl_type_path!((in other_crate::foo as Baz) Bar);819/// ```820///821/// [deriving `TypePath`]: TypePath822#[proc_macro]823pub fn impl_type_path(input: TokenStream) -> TokenStream {824let def = parse_macro_input!(input as NamedTypePathDef);825826let type_path = match def {827NamedTypePathDef::External {828ref path,829custom_path,830ref generics,831} => {832let default_name = &path.segments.last().unwrap().ident;833834ReflectTypePath::External {835path,836custom_path: custom_path.map(|path| path.into_path(default_name)),837generics,838}839}840NamedTypePathDef::Primitive(ref ident) => ReflectTypePath::Primitive(ident),841};842843let meta = ReflectMeta::new(type_path, ContainerAttributes::default());844845let type_path_impl = impls::impl_type_path(&meta);846847TokenStream::from(quote! {848const _: () = {849#type_path_impl850};851})852}853854/// Collects and loads type registrations when using `auto_register_static` feature.855///856/// Correctly using this macro requires following:857/// 1. This macro must be called **last** during compilation. This can be achieved by putting your main function858/// in a separate crate or restructuring your project to be separated into `bin` and `lib`, and putting this macro in `bin`.859/// Any automatic type registrations using `#[derive(Reflect)]` within the same crate as this macro are not guaranteed to run.860/// 2. Your project must be compiled with `auto_register_static` feature **and** `BEVY_REFLECT_AUTO_REGISTER_STATIC=1` env variable.861/// Enabling the feature generates registration functions while setting the variable enables export and862/// caching of registration function names.863/// 3. Must be called before creating `App` or using `TypeRegistry::register_derived_types`.864///865/// If you're experiencing linking issues try running `cargo clean` before rebuilding.866#[proc_macro]867pub fn load_type_registrations(_input: TokenStream) -> TokenStream {868if !cfg!(feature = "auto_register_static") {869return TokenStream::new();870}871872let Ok(dir) = fs::read_dir(PathBuf::from("target").join("bevy_reflect_type_registrations"))873else {874return TokenStream::new();875};876let mut str_buf = String::new();877let mut registration_fns = Vec::new();878for file_path in dir {879let mut file = fs::OpenOptions::new()880.read(true)881.open(file_path.unwrap().path())882.unwrap();883file.read_to_string(&mut str_buf).unwrap();884registration_fns.extend(str_buf.lines().filter(|s| !s.is_empty()).map(|s| {885s.parse::<proc_macro2::TokenStream>()886.expect("Unexpected function name")887}));888str_buf.clear();889}890let bevy_reflect_path = meta::get_bevy_reflect_path();891TokenStream::from(quote! {892{893fn _register_types(){894unsafe extern "Rust" {895#( safe fn #registration_fns(registry_ptr: &mut #bevy_reflect_path::TypeRegistry); )*896};897#( #bevy_reflect_path::__macro_exports::auto_register::push_registration_fn(#registration_fns); )*898}899_register_types();900}901})902}903904905