#![cfg_attr(docsrs, feature(doc_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 container_attributes;19mod custom_attributes;20mod derive_data;21#[cfg(feature = "reflect_documentation")]22mod documentation;23mod enum_utility;24mod field_attributes;25mod from_reflect;26mod generics;27mod ident;28mod impls;29mod meta;30mod reflect_opaque;31mod registration;32mod remote;33mod serialization;34mod string_expr;35mod struct_utility;36mod trait_reflection;37mod type_path;38mod where_clause_options;3940use std::{fs, io::Read, path::PathBuf};4142use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct};43use container_attributes::ContainerAttributes;44use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath};45use proc_macro::TokenStream;46use quote::quote;47use reflect_opaque::ReflectOpaqueDef;48use syn::{parse_macro_input, DeriveInput};49use type_path::NamedTypePathDef;5051pub(crate) static REFLECT_ATTRIBUTE_NAME: &str = "reflect";52pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path";53pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";5455/// Used both for [`impl_reflect`] and [`derive_reflect`].56///57/// [`impl_reflect`]: macro@impl_reflect58/// [`derive_reflect`]: derive_reflect()59fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStream {60let derive_data = match ReflectDerive::from_input(61&ast,62ReflectProvenance {63source,64trait_: ReflectTraitToImpl::Reflect,65},66) {67Ok(data) => data,68Err(err) => return err.into_compile_error().into(),69};7071let assertions = impls::impl_assertions(&derive_data);7273let (reflect_impls, from_reflect_impl) = match derive_data {74ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => (75impls::impl_struct(&struct_data),76if struct_data.meta().from_reflect().should_auto_derive() {77Some(from_reflect::impl_struct(&struct_data))78} else {79None80},81),82ReflectDerive::TupleStruct(struct_data) => (83impls::impl_tuple_struct(&struct_data),84if struct_data.meta().from_reflect().should_auto_derive() {85Some(from_reflect::impl_tuple_struct(&struct_data))86} else {87None88},89),90ReflectDerive::Enum(enum_data) => (91impls::impl_enum(&enum_data),92if enum_data.meta().from_reflect().should_auto_derive() {93Some(from_reflect::impl_enum(&enum_data))94} else {95None96},97),98ReflectDerive::Opaque(meta) => (99impls::impl_opaque(&meta),100if meta.from_reflect().should_auto_derive() {101Some(from_reflect::impl_opaque(&meta))102} else {103None104},105),106};107108TokenStream::from(quote! {109const _: () = {110#reflect_impls111112#from_reflect_impl113114#assertions115};116})117}118119/// The main derive macro used by `bevy_reflect` for deriving its `Reflect` trait.120///121/// This macro can be used on all structs and enums (unions are not supported).122/// It will automatically generate implementations for `Reflect`, `Typed`, `GetTypeRegistration`, and `FromReflect`.123/// And, depending on the item's structure, will either implement `Struct`, `TupleStruct`, or `Enum`.124///125/// See the [`FromReflect`] derive macro for more information on how to customize the `FromReflect` implementation.126///127/// # Container Attributes128///129/// This macro comes with some helper attributes that can be added to the container item130/// in order to provide additional functionality or alter the generated implementations.131///132/// In addition to those listed, this macro can also use the attributes for [`TypePath`] derives.133///134/// ## `#[reflect(Ident)]`135///136/// The `#[reflect(Ident)]` attribute is used to add type data registrations to the `GetTypeRegistration`137/// implementation corresponding to the given identifier, prepended by `Reflect`.138///139/// For example, `#[reflect(Foo, Bar)]` would add two registrations:140/// one for `ReflectFoo` and another for `ReflectBar`.141/// This assumes these types are indeed in-scope wherever this macro is called.142///143/// This is often used with traits that have been marked by the [`#[reflect_trait]`](macro@reflect_trait)144/// macro in order to register the type's implementation of that trait.145///146/// ### Default Registrations147///148/// The following types are automatically registered when deriving `Reflect`:149///150/// * `ReflectFromReflect` (unless opting out of `FromReflect`)151/// * `SerializationData`152/// * `ReflectFromPtr`153///154/// ### Special Identifiers155///156/// There are a few "special" identifiers that work a bit differently:157///158/// * `#[reflect(Clone)]` will force the implementation of `Reflect::reflect_clone` to rely on159/// the type's [`Clone`] implementation.160/// A custom implementation may be provided using `#[reflect(Clone(my_clone_func))]` where161/// `my_clone_func` is the path to a function matching the signature:162/// `(&Self) -> Self`.163/// * `#[reflect(Debug)]` will force the implementation of `Reflect::debug` to rely on164/// the type's [`Debug`] implementation.165/// A custom implementation may be provided using `#[reflect(Debug(my_debug_func))]` where166/// `my_debug_func` is the path to a function matching the signature:167/// `(&Self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result`.168/// * `#[reflect(PartialEq)]` will force the implementation of `Reflect::reflect_partial_eq` to rely on169/// the type's [`PartialEq`] implementation.170/// A custom implementation may be provided using `#[reflect(PartialEq(my_partial_eq_func))]` where171/// `my_partial_eq_func` is the path to a function matching the signature:172/// `(&Self, value: &dyn #bevy_reflect_path::Reflect) -> bool`.173/// * `#[reflect(PartialOrd)]` will force the implementation of `PartialReflect::reflect_partial_cmp`174/// to rely on the type's [`PartialOrd`] implementation.175/// A custom implementation may be provided using `#[reflect(PartialOrd(my_partial_cmp_fn))]` where176/// `my_partial_cmp_fn` is the path to a function matching the signature:177/// `(&Self, value: &dyn #bevy_reflect_path::PartialReflect) -> Option<::core::cmp::Ordering>`.178/// * `#[reflect(Hash)]` will force the implementation of `Reflect::reflect_hash` to rely on179/// the type's [`Hash`] implementation.180/// A custom implementation may be provided using `#[reflect(Hash(my_hash_func))]` where181/// `my_hash_func` is the path to a function matching the signature: `(&Self) -> u64`.182/// * `#[reflect(Default)]` will register the `ReflectDefault` type data as normal.183/// However, it will also affect how certain other operations are performed in order184/// to improve performance and/or robustness.185/// An example of where this is used is in the [`FromReflect`] derive macro,186/// where adding this attribute will cause the `FromReflect` implementation to create187/// a base value using its [`Default`] implementation avoiding issues with ignored fields188/// (for structs and tuple structs only).189///190/// ## `#[reflect(opaque)]`191///192/// The `#[reflect(opaque)]` attribute denotes that the item should implement `Reflect` as an opaque type,193/// hiding its structure and fields from the reflection API.194/// This means that it will forgo implementing `Struct`, `TupleStruct`, or `Enum`.195///196/// Furthermore, it requires that the type implements [`Clone`].197/// If planning to serialize this type using the reflection serializers,198/// then the `Serialize` and `Deserialize` traits will need to be implemented and registered as well.199///200/// ## `#[reflect(from_reflect = false)]`201///202/// This attribute will opt-out of the default `FromReflect` implementation.203///204/// This is useful for when a type can't or shouldn't implement `FromReflect`,205/// or if a manual implementation is desired.206///207/// Note that in the latter case, `ReflectFromReflect` will no longer be automatically registered.208///209/// ## `#[reflect(type_path = false)]`210///211/// This attribute will opt-out of the default `TypePath` implementation.212///213/// This is useful for when a type can't or shouldn't implement `TypePath`,214/// or if a manual implementation is desired.215///216/// ## `#[reflect(no_field_bounds)]`217///218/// This attribute will opt-out of the default trait bounds added to all field types219/// for the generated reflection trait impls.220///221/// Normally, all fields will have the bounds `TypePath`, and either `FromReflect` or `Reflect`222/// depending on if `#[reflect(from_reflect = false)]` is used.223/// However, this might not always be desirable, and so this attribute may be used to remove those bounds.224///225/// ### Example226///227/// If a type is recursive the default bounds will cause an overflow error when building:228///229/// ```ignore (bevy_reflect is not accessible from this crate)230/// #[derive(Reflect)] // ERROR: overflow evaluating the requirement `Foo: FromReflect`231/// struct Foo {232/// foo: Vec<Foo>,233/// }234///235/// // Generates a where clause like:236/// // impl bevy_reflect::Reflect for Foo237/// // where238/// // Foo: Any + Send + Sync,239/// // Vec<Foo>: FromReflect + TypePath + MaybeTyped + RegisterForReflection,240/// ```241///242/// In this case, `Foo` is given the bounds `Vec<Foo>: FromReflect + ...`,243/// which requires that `Foo` implements `FromReflect`,244/// which requires that `Vec<Foo>` implements `FromReflect`,245/// and so on, resulting in the error.246///247/// To fix this, we can add `#[reflect(no_field_bounds)]` to `Foo` to remove the bounds on `Vec<Foo>`:248///249/// ```ignore (bevy_reflect is not accessible from this crate)250/// #[derive(Reflect)]251/// #[reflect(no_field_bounds)]252/// struct Foo {253/// foo: Vec<Foo>,254/// }255///256/// // Generates a where clause like:257/// // impl bevy_reflect::Reflect for Foo258/// // where259/// // Self: Any + Send + Sync,260/// ```261///262/// ## `#[reflect(where T: Trait, U::Assoc: Trait, ...)]`263///264/// This attribute can be used to add additional bounds to the generated reflection trait impls.265///266/// This is useful for when a type needs certain bounds only applied to the reflection impls267/// that are not otherwise automatically added by the derive macro.268///269/// ### Example270///271/// In the example below, we want to enforce that `T::Assoc: List` is required in order for272/// `Foo<T>` to be reflectable, but we don't want it to prevent `Foo<T>` from being used273/// in places where `T::Assoc: List` is not required.274///275/// ```ignore276/// trait Trait {277/// type Assoc;278/// }279///280/// #[derive(Reflect)]281/// #[reflect(where T::Assoc: List)]282/// struct Foo<T: Trait> where T::Assoc: Default {283/// value: T::Assoc,284/// }285///286/// // Generates a where clause like:287/// //288/// // impl<T: Trait> bevy_reflect::Reflect for Foo<T>289/// // where290/// // Foo<T>: Any + Send + Sync,291/// // T::Assoc: Default,292/// // T: TypePath,293/// // T::Assoc: FromReflect + TypePath + MaybeTyped + RegisterForReflection,294/// // T::Assoc: List,295/// // {/* ... */}296/// ```297///298/// ## `#[reflect(@...)]`299///300/// This attribute can be used to register custom attributes to the type's `TypeInfo`.301///302/// It accepts any expression after the `@` symbol that resolves to a value which implements `Reflect`.303///304/// Any number of custom attributes may be registered, however, each the type of each attribute must be unique.305/// If two attributes of the same type are registered, the last one will overwrite the first.306///307/// ### Example308///309/// ```ignore310/// #[derive(Reflect)]311/// struct Required;312///313/// #[derive(Reflect)]314/// struct EditorTooltip(String);315///316/// impl EditorTooltip {317/// fn new(text: &str) -> Self {318/// Self(text.to_string())319/// }320/// }321///322/// #[derive(Reflect)]323/// // Specify a "required" status and tooltip:324/// #[reflect(@Required, @EditorTooltip::new("An ID is required!"))]325/// struct Id(u8);326/// ```327/// ## `#[reflect(no_auto_register)]`328///329/// This attribute will opt-out of the automatic reflect type registration.330///331/// All non-generic types annotated with `#[derive(Reflect)]` are usually automatically registered on app startup.332/// If this behavior is not desired, this attribute may be used to disable it for the annotated type.333///334/// # Field Attributes335///336/// Along with the container attributes, this macro comes with some attributes that may be applied337/// to the contained fields themselves.338///339/// ## `#[reflect(ignore)]`340///341/// This attribute simply marks a field to be ignored by the reflection API.342///343/// This allows fields to completely opt-out of reflection,344/// which may be useful for maintaining invariants, keeping certain data private,345/// or allowing the use of types that do not implement `Reflect` within the container.346///347/// ## `#[reflect(skip_serializing)]`348///349/// This works similar to `#[reflect(ignore)]`, but rather than opting out of _all_ of reflection,350/// it simply opts the field out of both serialization and deserialization.351/// This can be useful when a field should be accessible via reflection, but may not make352/// sense in a serialized form, such as computed data.353///354/// What this does is register the `SerializationData` type within the `GetTypeRegistration` implementation,355/// which will be used by the reflection serializers to determine whether or not the field is serializable.356///357/// ## `#[reflect(clone)]`358///359/// This attribute affects the `Reflect::reflect_clone` implementation.360///361/// Without this attribute, the implementation will rely on the field's own `Reflect::reflect_clone` implementation.362/// When this attribute is present, the implementation will instead use the field's `Clone` implementation directly.363///364/// The attribute may also take the path to a custom function like `#[reflect(clone = "path::to::my_clone_func")]`,365/// where `my_clone_func` matches the signature `(&Self) -> Self`.366///367/// This attribute does nothing if the containing struct/enum has the `#[reflect(Clone)]` attribute.368///369/// ## `#[reflect(@...)]`370///371/// This attribute can be used to register custom attributes to the field's `TypeInfo`.372///373/// It accepts any expression after the `@` symbol that resolves to a value which implements `Reflect`.374///375/// Any number of custom attributes may be registered, however, each the type of each attribute must be unique.376/// If two attributes of the same type are registered, the last one will overwrite the first.377///378/// ### Example379///380/// ```ignore381/// #[derive(Reflect)]382/// struct EditorTooltip(String);383///384/// impl EditorTooltip {385/// fn new(text: &str) -> Self {386/// Self(text.to_string())387/// }388/// }389///390/// #[derive(Reflect)]391/// struct Slider {392/// // Specify a custom range and tooltip:393/// #[reflect(@0.0..=1.0, @EditorTooltip::new("Must be between 0 and 1"))]394/// value: f32,395/// }396/// ```397///398/// [`reflect_trait`]: macro@reflect_trait399#[proc_macro_derive(Reflect, attributes(reflect, type_path, type_name))]400pub fn derive_reflect(input: TokenStream) -> TokenStream {401let ast = parse_macro_input!(input as DeriveInput);402match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)403}404405/// Derives the `FromReflect` trait.406///407/// # Field Attributes408///409/// ## `#[reflect(ignore)]`410///411/// The `#[reflect(ignore)]` attribute is shared with the [`#[derive(Reflect)]`](Reflect) macro and has much of the same412/// functionality in that it denotes that a field will be ignored by the reflection API.413///414/// The only major difference is that using it with this derive requires that the field implements [`Default`].415/// Without this requirement, there would be no way for `FromReflect` to automatically construct missing fields416/// that have been ignored.417///418/// ## `#[reflect(default)]`419///420/// If a field cannot be read, this attribute specifies a default value to be used in its place.421///422/// By default, this attribute denotes that the field's type implements [`Default`].423/// However, it can also take in a path string to a user-defined function that will return the default value.424/// This takes the form: `#[reflect(default = "path::to::my_function")]` where `my_function` is a parameterless425/// function that must return some default value for the type.426///427/// Specifying a custom default can be used to give different fields their own specialized defaults,428/// or to remove the `Default` requirement on fields marked with `#[reflect(ignore)]`.429/// Additionally, either form of this attribute can be used to fill in fields that are simply missing,430/// such as when converting a partially-constructed dynamic type to a concrete one.431#[proc_macro_derive(FromReflect, attributes(reflect))]432pub fn derive_from_reflect(input: TokenStream) -> TokenStream {433let ast = parse_macro_input!(input as DeriveInput);434435let derive_data = match ReflectDerive::from_input(436&ast,437ReflectProvenance {438source: ReflectImplSource::DeriveLocalType,439trait_: ReflectTraitToImpl::FromReflect,440},441) {442Ok(data) => data,443Err(err) => return err.into_compile_error().into(),444};445446let from_reflect_impl = match derive_data {447ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => {448from_reflect::impl_struct(&struct_data)449}450ReflectDerive::TupleStruct(struct_data) => from_reflect::impl_tuple_struct(&struct_data),451ReflectDerive::Enum(meta) => from_reflect::impl_enum(&meta),452ReflectDerive::Opaque(meta) => from_reflect::impl_opaque(&meta),453};454455TokenStream::from(quote! {456const _: () = {457#from_reflect_impl458};459})460}461462/// Derives the `TypePath` trait, providing a stable alternative to [`std::any::type_name`].463///464/// # Container Attributes465///466/// ## `#[type_path = "my_crate::foo"]`467///468/// Optionally specifies a custom module path to use instead of [`module_path`].469///470/// This path does not include the final identifier.471///472/// ## `#[type_name = "RenamedType"]`473///474/// Optionally specifies a new terminating identifier for `TypePath`.475///476/// To use this attribute, `#[type_path = "..."]` must also be specified.477#[proc_macro_derive(TypePath, attributes(type_path, type_name))]478pub fn derive_type_path(input: TokenStream) -> TokenStream {479let ast = parse_macro_input!(input as DeriveInput);480let derive_data = match ReflectDerive::from_input(481&ast,482ReflectProvenance {483source: ReflectImplSource::DeriveLocalType,484trait_: ReflectTraitToImpl::TypePath,485},486) {487Ok(data) => data,488Err(err) => return err.into_compile_error().into(),489};490491let type_path_impl = impls::impl_type_path(derive_data.meta());492493TokenStream::from(quote! {494const _: () = {495#type_path_impl496};497})498}499500/// A macro that automatically generates type data for traits, which their implementors can then register.501///502/// The output of this macro is a struct that takes reflected instances of the implementor's type503/// and returns the value as a trait object.504/// Because of this, **it can only be used on [object-safe] traits.**505///506/// For a trait named `MyTrait`, this will generate the struct `ReflectMyTrait`.507/// The generated struct can be created using `FromType` with any type that implements the trait.508/// The creation and registration of this generated struct as type data can be automatically handled509/// by [`#[derive(Reflect)]`](Reflect).510///511/// # Example512///513/// ```ignore (bevy_reflect is not accessible from this crate)514/// # use std::any::TypeId;515/// # use bevy_reflect_derive::{Reflect, reflect_trait};516/// #[reflect_trait] // Generates `ReflectMyTrait`517/// trait MyTrait {518/// fn print(&self) -> &str;519/// }520///521/// #[derive(Reflect)]522/// #[reflect(MyTrait)] // Automatically registers `ReflectMyTrait`523/// struct SomeStruct;524///525/// impl MyTrait for SomeStruct {526/// fn print(&self) -> &str {527/// "Hello, World!"528/// }529/// }530///531/// // We can create the type data manually if we wanted:532/// let my_trait: ReflectMyTrait = FromType::<SomeStruct>::from_type();533///534/// // Or we can simply get it from the registry:535/// let mut registry = TypeRegistry::default();536/// registry.register::<SomeStruct>();537/// let my_trait = registry538/// .get_type_data::<ReflectMyTrait>(TypeId::of::<SomeStruct>())539/// .unwrap();540///541/// // Then use it on reflected data542/// let reflected: Box<dyn Reflect> = Box::new(SomeStruct);543/// let reflected_my_trait: &dyn MyTrait = my_trait.get(&*reflected).unwrap();544/// assert_eq!("Hello, World!", reflected_my_trait.print());545/// ```546///547/// [object-safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety548#[proc_macro_attribute]549pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream {550trait_reflection::reflect_trait(&args, input)551}552553/// Generates a wrapper type that can be used to "derive `Reflect`" for remote types.554///555/// This works by wrapping the remote type in a generated wrapper that has the `#[repr(transparent)]` attribute.556/// This allows the two types to be safely [transmuted] back-and-forth.557///558/// # Defining the Wrapper559///560/// Before defining the wrapper type, please note that it is _required_ that all fields of the remote type are public.561/// The generated code will, at times, need to access or mutate them,562/// and we do not currently have a way to assign getters/setters to each field563/// (but this may change in the future).564///565/// The wrapper definition should match the remote type 1-to-1.566/// This includes the naming and ordering of the fields and variants.567///568/// Generics and lifetimes do _not_ need to have the same names, however, they _do_ need to follow the same order.569/// Additionally, whether generics are inlined or placed in a where clause should not matter.570///571/// Lastly, all macros and doc-comments should be placed __below__ this attribute.572/// If they are placed above, they will not be properly passed to the generated wrapper type.573///574/// # Example575///576/// Given a remote type, `RemoteType`:577///578/// ```579/// #[derive(Default)]580/// struct RemoteType<T>581/// where582/// T: Default + Clone,583/// {584/// pub foo: T,585/// pub bar: usize586/// }587/// ```588///589/// We would define our wrapper type as such:590///591/// ```ignore592/// use external_crate::RemoteType;593///594/// #[reflect_remote(RemoteType<T>)]595/// #[derive(Default)]596/// pub struct WrapperType<T: Default + Clone> {597/// pub foo: T,598/// pub bar: usize599/// }600/// ```601///602/// Apart from all the reflection trait implementations, this generates something like the following:603///604/// ```ignore605/// use external_crate::RemoteType;606///607/// #[derive(Default)]608/// #[repr(transparent)]609/// pub struct Wrapper<T: Default + Clone>(RemoteType<T>);610/// ```611///612/// # Usage as a Field613///614/// You can tell `Reflect` to use a remote type's wrapper internally on fields of a struct or enum.615/// This allows the real type to be used as usual while `Reflect` handles everything internally.616/// To do this, add the `#[reflect(remote = path::to::MyType)]` attribute to your field:617///618/// ```ignore619/// #[derive(Reflect)]620/// struct SomeStruct {621/// #[reflect(remote = RemoteTypeWrapper)]622/// data: RemoteType623/// }624/// ```625///626/// ## Safety627///628/// When using the `#[reflect(remote = path::to::MyType)]` field attribute, be sure you are defining the correct wrapper type.629/// Internally, this field will be unsafely [transmuted], and is only sound if using a wrapper generated for the remote type.630/// This also means keeping your wrapper definitions up-to-date with the remote types.631///632/// [transmuted]: std::mem::transmute633#[proc_macro_attribute]634pub fn reflect_remote(args: TokenStream, input: TokenStream) -> TokenStream {635remote::reflect_remote(args, input)636}637638/// A macro used to generate reflection trait implementations for the given type.639///640/// This is functionally the same as [deriving `Reflect`] using the `#[reflect(opaque)]` container attribute.641///642/// The only reason for this macro's existence is so that `bevy_reflect` can easily implement the reflection traits643/// on primitives and other opaque types internally.644///645/// Since this macro also implements `TypePath`, the type path must be explicit.646/// See [`impl_type_path!`] for the exact syntax.647///648/// # Examples649///650/// Types can be passed with or without registering type data:651///652/// ```ignore (bevy_reflect is not accessible from this crate)653/// impl_reflect_opaque!(my_crate::Foo);654/// impl_reflect_opaque!(my_crate::Bar(Debug, Default, Serialize, Deserialize));655/// ```656///657/// Generic types can also specify their parameters and bounds:658///659/// ```ignore (bevy_reflect is not accessible from this crate)660/// impl_reflect_opaque!(my_crate::Foo<T1, T2: Baz> where T1: Bar (Default, Serialize, Deserialize));661/// ```662///663/// Custom type paths can be specified:664///665/// ```ignore (bevy_reflect is not accessible from this crate)666/// impl_reflect_opaque!((in not_my_crate as NotFoo) Foo(Debug, Default));667/// ```668///669/// [deriving `Reflect`]: Reflect670#[proc_macro]671pub fn impl_reflect_opaque(input: TokenStream) -> TokenStream {672let def = parse_macro_input!(input with ReflectOpaqueDef::parse_reflect);673674let default_name = &def.type_path.segments.last().unwrap().ident;675let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() {676ReflectTypePath::Primitive(default_name)677} else {678ReflectTypePath::External {679path: &def.type_path,680custom_path: def.custom_path.map(|path| path.into_path(default_name)),681generics: &def.generics,682}683};684685let meta = ReflectMeta::new(type_path, def.traits.unwrap_or_default());686687#[cfg(feature = "reflect_documentation")]688let meta = meta.with_docs(documentation::Documentation::from_attributes(&def.attrs));689690let reflect_impls = impls::impl_opaque(&meta);691let from_reflect_impl = from_reflect::impl_opaque(&meta);692693TokenStream::from(quote! {694const _: () = {695#reflect_impls696#from_reflect_impl697};698})699}700701/// A replacement for `#[derive(Reflect)]` to be used with foreign types which702/// the definitions of cannot be altered.703///704/// This macro is an alternative to [`impl_reflect_opaque!`] and [`impl_from_reflect_opaque!`]705/// which implement foreign types as Opaque types. Note that there is no `impl_from_reflect`,706/// as this macro will do the job of both. This macro implements them using one of the reflect707/// variant traits (`bevy_reflect::{Struct, TupleStruct, Enum}`, etc.),708/// which have greater functionality. The type being reflected must be in scope, as you cannot709/// qualify it in the macro as e.g. `bevy::prelude::Vec3`.710///711/// It is necessary to add a `#[type_path = "my_crate::foo"]` attribute to all types.712///713/// It may be necessary to add `#[reflect(Default)]` for some types, specifically non-constructible714/// foreign types. Without `Default` reflected for such types, you will usually get an arcane715/// error message and fail to compile. If the type does not implement `Default`, it may not716/// be possible to reflect without extending the macro.717///718///719/// # Example720/// Implementing `Reflect` for `bevy::prelude::Vec3` as a struct type:721/// ```ignore (bevy_reflect is not accessible from this crate)722/// use bevy::prelude::Vec3;723///724/// impl_reflect!(725/// #[reflect(PartialEq, Serialize, Deserialize, Default)]726/// #[type_path = "bevy::prelude"]727/// struct Vec3 {728/// x: f32,729/// y: f32,730/// z: f32731/// }732/// );733/// ```734#[proc_macro]735pub fn impl_reflect(input: TokenStream) -> TokenStream {736let ast = parse_macro_input!(input as DeriveInput);737match_reflect_impls(ast, ReflectImplSource::ImplRemoteType)738}739740/// A macro used to generate a `FromReflect` trait implementation for the given type.741///742/// This is functionally the same as [deriving `FromReflect`] on a type that [derives `Reflect`] using743/// the `#[reflect(opaque)]` container attribute.744///745/// The only reason this macro exists is so that `bevy_reflect` can easily implement `FromReflect` on746/// primitives and other opaque types internally.747///748/// Please note that this macro will not work with any type that [derives `Reflect`] normally749/// or makes use of the [`impl_reflect_opaque!`] macro, as those macros also implement `FromReflect`750/// by default.751///752/// # Examples753///754/// ```ignore (bevy_reflect is not accessible from this crate)755/// impl_from_reflect_opaque!(foo<T1, T2: Baz> where T1: Bar);756/// ```757///758/// [deriving `FromReflect`]: FromReflect759/// [derives `Reflect`]: Reflect760#[proc_macro]761pub fn impl_from_reflect_opaque(input: TokenStream) -> TokenStream {762let def = parse_macro_input!(input with ReflectOpaqueDef::parse_from_reflect);763764let default_name = &def.type_path.segments.last().unwrap().ident;765let type_path = if def.type_path.leading_colon.is_none()766&& def.custom_path.is_none()767&& def.generics.params.is_empty()768{769ReflectTypePath::Primitive(default_name)770} else {771ReflectTypePath::External {772path: &def.type_path,773custom_path: def.custom_path.map(|alias| alias.into_path(default_name)),774generics: &def.generics,775}776};777778let from_reflect_impl =779from_reflect::impl_opaque(&ReflectMeta::new(type_path, def.traits.unwrap_or_default()));780781TokenStream::from(quote! {782const _: () = {783#from_reflect_impl784};785})786}787788/// A replacement for [deriving `TypePath`] for use on foreign types.789///790/// Since (unlike the derive) this macro may be invoked in a different module to where the type is defined,791/// it requires an 'absolute' path definition.792///793/// Specifically, a leading `::` denoting a global path must be specified794/// or a preceding `(in my_crate::foo)` to specify the custom path must be used.795///796/// # Examples797///798/// Implementing `TypePath` on a foreign type:799/// ```ignore (bevy_reflect is not accessible from this crate)800/// impl_type_path!(::foreign_crate::foo::bar::Baz);801/// ```802///803/// On a generic type (this can also accept trait bounds):804/// ```ignore (bevy_reflect is not accessible from this crate)805/// impl_type_path!(::foreign_crate::Foo<T>);806/// impl_type_path!(::foreign_crate::Goo<T: ?Sized>);807/// ```808///809/// On a primitive (note this will not compile for a non-primitive type):810/// ```ignore (bevy_reflect is not accessible from this crate)811/// impl_type_path!(bool);812/// ```813///814/// With a custom type path:815/// ```ignore (bevy_reflect is not accessible from this crate)816/// impl_type_path!((in other_crate::foo::bar) Baz);817/// ```818///819/// With a custom type path and a custom type name:820/// ```ignore (bevy_reflect is not accessible from this crate)821/// impl_type_path!((in other_crate::foo as Baz) Bar);822/// ```823///824/// [deriving `TypePath`]: TypePath825#[proc_macro]826pub fn impl_type_path(input: TokenStream) -> TokenStream {827let def = parse_macro_input!(input as NamedTypePathDef);828829let type_path = match def {830NamedTypePathDef::External {831ref path,832custom_path,833ref generics,834} => {835let default_name = &path.segments.last().unwrap().ident;836837ReflectTypePath::External {838path,839custom_path: custom_path.map(|path| path.into_path(default_name)),840generics,841}842}843NamedTypePathDef::Primitive(ref ident) => ReflectTypePath::Primitive(ident),844};845846let meta = ReflectMeta::new(type_path, ContainerAttributes::default());847848let type_path_impl = impls::impl_type_path(&meta);849850TokenStream::from(quote! {851const _: () = {852#type_path_impl853};854})855}856857/// Collects and loads type registrations when using `auto_register_static` feature.858///859/// Correctly using this macro requires following:860/// 1. This macro must be called **last** during compilation. This can be achieved by putting your main function861/// in a separate crate or restructuring your project to be separated into `bin` and `lib`, and putting this macro in `bin`.862/// Any automatic type registrations using `#[derive(Reflect)]` within the same crate as this macro are not guaranteed to run.863/// 2. Your project must be compiled with `auto_register_static` feature **and** `BEVY_REFLECT_AUTO_REGISTER_STATIC=1` env variable.864/// Enabling the feature generates registration functions while setting the variable enables export and865/// caching of registration function names.866/// 3. Must be called before creating `App` or using `TypeRegistry::register_derived_types`.867///868/// If you're experiencing linking issues try running `cargo clean` before rebuilding.869#[proc_macro]870pub fn load_type_registrations(_input: TokenStream) -> TokenStream {871if !cfg!(feature = "auto_register_static") {872return TokenStream::new();873}874875let Ok(dir) = fs::read_dir(PathBuf::from("target").join("bevy_reflect_type_registrations"))876else {877return TokenStream::new();878};879let mut str_buf = String::new();880let mut registration_fns = Vec::new();881for file_path in dir {882let mut file = fs::OpenOptions::new()883.read(true)884.open(file_path.unwrap().path())885.unwrap();886file.read_to_string(&mut str_buf).unwrap();887registration_fns.extend(str_buf.lines().filter(|s| !s.is_empty()).map(|s| {888s.parse::<proc_macro2::TokenStream>()889.expect("Unexpected function name")890}));891str_buf.clear();892}893let bevy_reflect_path = meta::get_bevy_reflect_path();894TokenStream::from(quote! {895{896fn _register_types(){897unsafe extern "Rust" {898#( safe fn #registration_fns(registry_ptr: &mut #bevy_reflect_path::TypeRegistry); )*899};900#( #bevy_reflect_path::__macro_exports::auto_register::push_registration_fn(#registration_fns); )*901}902_register_types();903}904})905}906907908