#![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 container_attributes;19mod custom_attributes;20mod derive_data;21#[cfg(feature = "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::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(Hash)]` will force the implementation of `Reflect::reflect_hash` to rely on174/// the type's [`Hash`] implementation.175/// A custom implementation may be provided using `#[reflect(Hash(my_hash_func))]` where176/// `my_hash_func` is the path to a function matching the signature: `(&Self) -> u64`.177/// * `#[reflect(Default)]` will register the `ReflectDefault` type data as normal.178/// However, it will also affect how certain other operations are performed in order179/// to improve performance and/or robustness.180/// An example of where this is used is in the [`FromReflect`] derive macro,181/// where adding this attribute will cause the `FromReflect` implementation to create182/// a base value using its [`Default`] implementation avoiding issues with ignored fields183/// (for structs and tuple structs only).184///185/// ## `#[reflect(opaque)]`186///187/// The `#[reflect(opaque)]` attribute denotes that the item should implement `Reflect` as an opaque type,188/// hiding its structure and fields from the reflection API.189/// This means that it will forgo implementing `Struct`, `TupleStruct`, or `Enum`.190///191/// Furthermore, it requires that the type implements [`Clone`].192/// If planning to serialize this type using the reflection serializers,193/// then the `Serialize` and `Deserialize` traits will need to be implemented and registered as well.194///195/// ## `#[reflect(from_reflect = false)]`196///197/// This attribute will opt-out of the default `FromReflect` implementation.198///199/// This is useful for when a type can't or shouldn't implement `FromReflect`,200/// or if a manual implementation is desired.201///202/// Note that in the latter case, `ReflectFromReflect` will no longer be automatically registered.203///204/// ## `#[reflect(type_path = false)]`205///206/// This attribute will opt-out of the default `TypePath` implementation.207///208/// This is useful for when a type can't or shouldn't implement `TypePath`,209/// or if a manual implementation is desired.210///211/// ## `#[reflect(no_field_bounds)]`212///213/// This attribute will opt-out of the default trait bounds added to all field types214/// for the generated reflection trait impls.215///216/// Normally, all fields will have the bounds `TypePath`, and either `FromReflect` or `Reflect`217/// depending on if `#[reflect(from_reflect = false)]` is used.218/// However, this might not always be desirable, and so this attribute may be used to remove those bounds.219///220/// ### Example221///222/// If a type is recursive the default bounds will cause an overflow error when building:223///224/// ```ignore (bevy_reflect is not accessible from this crate)225/// #[derive(Reflect)] // ERROR: overflow evaluating the requirement `Foo: FromReflect`226/// struct Foo {227/// foo: Vec<Foo>,228/// }229///230/// // Generates a where clause like:231/// // impl bevy_reflect::Reflect for Foo232/// // where233/// // Foo: Any + Send + Sync,234/// // Vec<Foo>: FromReflect + TypePath + MaybeTyped + RegisterForReflection,235/// ```236///237/// In this case, `Foo` is given the bounds `Vec<Foo>: FromReflect + ...`,238/// which requires that `Foo` implements `FromReflect`,239/// which requires that `Vec<Foo>` implements `FromReflect`,240/// and so on, resulting in the error.241///242/// To fix this, we can add `#[reflect(no_field_bounds)]` to `Foo` to remove the bounds on `Vec<Foo>`:243///244/// ```ignore (bevy_reflect is not accessible from this crate)245/// #[derive(Reflect)]246/// #[reflect(no_field_bounds)]247/// struct Foo {248/// foo: Vec<Foo>,249/// }250///251/// // Generates a where clause like:252/// // impl bevy_reflect::Reflect for Foo253/// // where254/// // Self: Any + Send + Sync,255/// ```256///257/// ## `#[reflect(where T: Trait, U::Assoc: Trait, ...)]`258///259/// This attribute can be used to add additional bounds to the generated reflection trait impls.260///261/// This is useful for when a type needs certain bounds only applied to the reflection impls262/// that are not otherwise automatically added by the derive macro.263///264/// ### Example265///266/// In the example below, we want to enforce that `T::Assoc: List` is required in order for267/// `Foo<T>` to be reflectable, but we don't want it to prevent `Foo<T>` from being used268/// in places where `T::Assoc: List` is not required.269///270/// ```ignore271/// trait Trait {272/// type Assoc;273/// }274///275/// #[derive(Reflect)]276/// #[reflect(where T::Assoc: List)]277/// struct Foo<T: Trait> where T::Assoc: Default {278/// value: T::Assoc,279/// }280///281/// // Generates a where clause like:282/// //283/// // impl<T: Trait> bevy_reflect::Reflect for Foo<T>284/// // where285/// // Foo<T>: Any + Send + Sync,286/// // T::Assoc: Default,287/// // T: TypePath,288/// // T::Assoc: FromReflect + TypePath + MaybeTyped + RegisterForReflection,289/// // T::Assoc: List,290/// // {/* ... */}291/// ```292///293/// ## `#[reflect(@...)]`294///295/// This attribute can be used to register custom attributes to the type's `TypeInfo`.296///297/// It accepts any expression after the `@` symbol that resolves to a value which implements `Reflect`.298///299/// Any number of custom attributes may be registered, however, each the type of each attribute must be unique.300/// If two attributes of the same type are registered, the last one will overwrite the first.301///302/// ### Example303///304/// ```ignore305/// #[derive(Reflect)]306/// struct Required;307///308/// #[derive(Reflect)]309/// struct EditorTooltip(String);310///311/// impl EditorTooltip {312/// fn new(text: &str) -> Self {313/// Self(text.to_string())314/// }315/// }316///317/// #[derive(Reflect)]318/// // Specify a "required" status and tooltip:319/// #[reflect(@Required, @EditorTooltip::new("An ID is required!"))]320/// struct Id(u8);321/// ```322/// ## `#[reflect(no_auto_register)]`323///324/// This attribute will opt-out of the automatic reflect type registration.325///326/// All non-generic types annotated with `#[derive(Reflect)]` are usually automatically registered on app startup.327/// If this behavior is not desired, this attribute may be used to disable it for the annotated type.328///329/// # Field Attributes330///331/// Along with the container attributes, this macro comes with some attributes that may be applied332/// to the contained fields themselves.333///334/// ## `#[reflect(ignore)]`335///336/// This attribute simply marks a field to be ignored by the reflection API.337///338/// This allows fields to completely opt-out of reflection,339/// which may be useful for maintaining invariants, keeping certain data private,340/// or allowing the use of types that do not implement `Reflect` within the container.341///342/// ## `#[reflect(skip_serializing)]`343///344/// This works similar to `#[reflect(ignore)]`, but rather than opting out of _all_ of reflection,345/// it simply opts the field out of both serialization and deserialization.346/// This can be useful when a field should be accessible via reflection, but may not make347/// sense in a serialized form, such as computed data.348///349/// What this does is register the `SerializationData` type within the `GetTypeRegistration` implementation,350/// which will be used by the reflection serializers to determine whether or not the field is serializable.351///352/// ## `#[reflect(clone)]`353///354/// This attribute affects the `Reflect::reflect_clone` implementation.355///356/// Without this attribute, the implementation will rely on the field's own `Reflect::reflect_clone` implementation.357/// When this attribute is present, the implementation will instead use the field's `Clone` implementation directly.358///359/// The attribute may also take the path to a custom function like `#[reflect(clone = "path::to::my_clone_func")]`,360/// where `my_clone_func` matches the signature `(&Self) -> Self`.361///362/// This attribute does nothing if the containing struct/enum has the `#[reflect(Clone)]` attribute.363///364/// ## `#[reflect(@...)]`365///366/// This attribute can be used to register custom attributes to the field's `TypeInfo`.367///368/// It accepts any expression after the `@` symbol that resolves to a value which implements `Reflect`.369///370/// Any number of custom attributes may be registered, however, each the type of each attribute must be unique.371/// If two attributes of the same type are registered, the last one will overwrite the first.372///373/// ### Example374///375/// ```ignore376/// #[derive(Reflect)]377/// struct EditorTooltip(String);378///379/// impl EditorTooltip {380/// fn new(text: &str) -> Self {381/// Self(text.to_string())382/// }383/// }384///385/// #[derive(Reflect)]386/// struct Slider {387/// // Specify a custom range and tooltip:388/// #[reflect(@0.0..=1.0, @EditorTooltip::new("Must be between 0 and 1"))]389/// value: f32,390/// }391/// ```392///393/// [`reflect_trait`]: macro@reflect_trait394#[proc_macro_derive(Reflect, attributes(reflect, type_path, type_name))]395pub fn derive_reflect(input: TokenStream) -> TokenStream {396let ast = parse_macro_input!(input as DeriveInput);397match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)398}399400/// Derives the `FromReflect` trait.401///402/// # Field Attributes403///404/// ## `#[reflect(ignore)]`405///406/// The `#[reflect(ignore)]` attribute is shared with the [`#[derive(Reflect)]`](Reflect) macro and has much of the same407/// functionality in that it denotes that a field will be ignored by the reflection API.408///409/// The only major difference is that using it with this derive requires that the field implements [`Default`].410/// Without this requirement, there would be no way for `FromReflect` to automatically construct missing fields411/// that have been ignored.412///413/// ## `#[reflect(default)]`414///415/// If a field cannot be read, this attribute specifies a default value to be used in its place.416///417/// By default, this attribute denotes that the field's type implements [`Default`].418/// However, it can also take in a path string to a user-defined function that will return the default value.419/// This takes the form: `#[reflect(default = "path::to::my_function")]` where `my_function` is a parameterless420/// function that must return some default value for the type.421///422/// Specifying a custom default can be used to give different fields their own specialized defaults,423/// or to remove the `Default` requirement on fields marked with `#[reflect(ignore)]`.424/// Additionally, either form of this attribute can be used to fill in fields that are simply missing,425/// such as when converting a partially-constructed dynamic type to a concrete one.426#[proc_macro_derive(FromReflect, attributes(reflect))]427pub fn derive_from_reflect(input: TokenStream) -> TokenStream {428let ast = parse_macro_input!(input as DeriveInput);429430let derive_data = match ReflectDerive::from_input(431&ast,432ReflectProvenance {433source: ReflectImplSource::DeriveLocalType,434trait_: ReflectTraitToImpl::FromReflect,435},436) {437Ok(data) => data,438Err(err) => return err.into_compile_error().into(),439};440441let from_reflect_impl = match derive_data {442ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => {443from_reflect::impl_struct(&struct_data)444}445ReflectDerive::TupleStruct(struct_data) => from_reflect::impl_tuple_struct(&struct_data),446ReflectDerive::Enum(meta) => from_reflect::impl_enum(&meta),447ReflectDerive::Opaque(meta) => from_reflect::impl_opaque(&meta),448};449450TokenStream::from(quote! {451const _: () = {452#from_reflect_impl453};454})455}456457/// Derives the `TypePath` trait, providing a stable alternative to [`std::any::type_name`].458///459/// # Container Attributes460///461/// ## `#[type_path = "my_crate::foo"]`462///463/// Optionally specifies a custom module path to use instead of [`module_path`].464///465/// This path does not include the final identifier.466///467/// ## `#[type_name = "RenamedType"]`468///469/// Optionally specifies a new terminating identifier for `TypePath`.470///471/// To use this attribute, `#[type_path = "..."]` must also be specified.472#[proc_macro_derive(TypePath, attributes(type_path, type_name))]473pub fn derive_type_path(input: TokenStream) -> TokenStream {474let ast = parse_macro_input!(input as DeriveInput);475let derive_data = match ReflectDerive::from_input(476&ast,477ReflectProvenance {478source: ReflectImplSource::DeriveLocalType,479trait_: ReflectTraitToImpl::TypePath,480},481) {482Ok(data) => data,483Err(err) => return err.into_compile_error().into(),484};485486let type_path_impl = impls::impl_type_path(derive_data.meta());487488TokenStream::from(quote! {489const _: () = {490#type_path_impl491};492})493}494495/// A macro that automatically generates type data for traits, which their implementors can then register.496///497/// The output of this macro is a struct that takes reflected instances of the implementor's type498/// and returns the value as a trait object.499/// Because of this, **it can only be used on [object-safe] traits.**500///501/// For a trait named `MyTrait`, this will generate the struct `ReflectMyTrait`.502/// The generated struct can be created using `FromType` with any type that implements the trait.503/// The creation and registration of this generated struct as type data can be automatically handled504/// by [`#[derive(Reflect)]`](Reflect).505///506/// # Example507///508/// ```ignore (bevy_reflect is not accessible from this crate)509/// # use std::any::TypeId;510/// # use bevy_reflect_derive::{Reflect, reflect_trait};511/// #[reflect_trait] // Generates `ReflectMyTrait`512/// trait MyTrait {513/// fn print(&self) -> &str;514/// }515///516/// #[derive(Reflect)]517/// #[reflect(MyTrait)] // Automatically registers `ReflectMyTrait`518/// struct SomeStruct;519///520/// impl MyTrait for SomeStruct {521/// fn print(&self) -> &str {522/// "Hello, World!"523/// }524/// }525///526/// // We can create the type data manually if we wanted:527/// let my_trait: ReflectMyTrait = FromType::<SomeStruct>::from_type();528///529/// // Or we can simply get it from the registry:530/// let mut registry = TypeRegistry::default();531/// registry.register::<SomeStruct>();532/// let my_trait = registry533/// .get_type_data::<ReflectMyTrait>(TypeId::of::<SomeStruct>())534/// .unwrap();535///536/// // Then use it on reflected data537/// let reflected: Box<dyn Reflect> = Box::new(SomeStruct);538/// let reflected_my_trait: &dyn MyTrait = my_trait.get(&*reflected).unwrap();539/// assert_eq!("Hello, World!", reflected_my_trait.print());540/// ```541///542/// [object-safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety543#[proc_macro_attribute]544pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream {545trait_reflection::reflect_trait(&args, input)546}547548/// Generates a wrapper type that can be used to "derive `Reflect`" for remote types.549///550/// This works by wrapping the remote type in a generated wrapper that has the `#[repr(transparent)]` attribute.551/// This allows the two types to be safely [transmuted] back-and-forth.552///553/// # Defining the Wrapper554///555/// Before defining the wrapper type, please note that it is _required_ that all fields of the remote type are public.556/// The generated code will, at times, need to access or mutate them,557/// and we do not currently have a way to assign getters/setters to each field558/// (but this may change in the future).559///560/// The wrapper definition should match the remote type 1-to-1.561/// This includes the naming and ordering of the fields and variants.562///563/// Generics and lifetimes do _not_ need to have the same names, however, they _do_ need to follow the same order.564/// Additionally, whether generics are inlined or placed in a where clause should not matter.565///566/// Lastly, all macros and doc-comments should be placed __below__ this attribute.567/// If they are placed above, they will not be properly passed to the generated wrapper type.568///569/// # Example570///571/// Given a remote type, `RemoteType`:572///573/// ```574/// #[derive(Default)]575/// struct RemoteType<T>576/// where577/// T: Default + Clone,578/// {579/// pub foo: T,580/// pub bar: usize581/// }582/// ```583///584/// We would define our wrapper type as such:585///586/// ```ignore587/// use external_crate::RemoteType;588///589/// #[reflect_remote(RemoteType<T>)]590/// #[derive(Default)]591/// pub struct WrapperType<T: Default + Clone> {592/// pub foo: T,593/// pub bar: usize594/// }595/// ```596///597/// Apart from all the reflection trait implementations, this generates something like the following:598///599/// ```ignore600/// use external_crate::RemoteType;601///602/// #[derive(Default)]603/// #[repr(transparent)]604/// pub struct Wrapper<T: Default + Clone>(RemoteType<T>);605/// ```606///607/// # Usage as a Field608///609/// You can tell `Reflect` to use a remote type's wrapper internally on fields of a struct or enum.610/// This allows the real type to be used as usual while `Reflect` handles everything internally.611/// To do this, add the `#[reflect(remote = path::to::MyType)]` attribute to your field:612///613/// ```ignore614/// #[derive(Reflect)]615/// struct SomeStruct {616/// #[reflect(remote = RemoteTypeWrapper)]617/// data: RemoteType618/// }619/// ```620///621/// ## Safety622///623/// When using the `#[reflect(remote = path::to::MyType)]` field attribute, be sure you are defining the correct wrapper type.624/// Internally, this field will be unsafely [transmuted], and is only sound if using a wrapper generated for the remote type.625/// This also means keeping your wrapper definitions up-to-date with the remote types.626///627/// [transmuted]: std::mem::transmute628#[proc_macro_attribute]629pub fn reflect_remote(args: TokenStream, input: TokenStream) -> TokenStream {630remote::reflect_remote(args, input)631}632633/// A macro used to generate reflection trait implementations for the given type.634///635/// This is functionally the same as [deriving `Reflect`] using the `#[reflect(opaque)]` container attribute.636///637/// The only reason for this macro's existence is so that `bevy_reflect` can easily implement the reflection traits638/// on primitives and other opaque types internally.639///640/// Since this macro also implements `TypePath`, the type path must be explicit.641/// See [`impl_type_path!`] for the exact syntax.642///643/// # Examples644///645/// Types can be passed with or without registering type data:646///647/// ```ignore (bevy_reflect is not accessible from this crate)648/// impl_reflect_opaque!(my_crate::Foo);649/// impl_reflect_opaque!(my_crate::Bar(Debug, Default, Serialize, Deserialize));650/// ```651///652/// Generic types can also specify their parameters and bounds:653///654/// ```ignore (bevy_reflect is not accessible from this crate)655/// impl_reflect_opaque!(my_crate::Foo<T1, T2: Baz> where T1: Bar (Default, Serialize, Deserialize));656/// ```657///658/// Custom type paths can be specified:659///660/// ```ignore (bevy_reflect is not accessible from this crate)661/// impl_reflect_opaque!((in not_my_crate as NotFoo) Foo(Debug, Default));662/// ```663///664/// [deriving `Reflect`]: Reflect665#[proc_macro]666pub fn impl_reflect_opaque(input: TokenStream) -> TokenStream {667let def = parse_macro_input!(input with ReflectOpaqueDef::parse_reflect);668669let default_name = &def.type_path.segments.last().unwrap().ident;670let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() {671ReflectTypePath::Primitive(default_name)672} else {673ReflectTypePath::External {674path: &def.type_path,675custom_path: def.custom_path.map(|path| path.into_path(default_name)),676generics: &def.generics,677}678};679680let meta = ReflectMeta::new(type_path, def.traits.unwrap_or_default());681682#[cfg(feature = "documentation")]683let meta = meta.with_docs(documentation::Documentation::from_attributes(&def.attrs));684685let reflect_impls = impls::impl_opaque(&meta);686let from_reflect_impl = from_reflect::impl_opaque(&meta);687688TokenStream::from(quote! {689const _: () = {690#reflect_impls691#from_reflect_impl692};693})694}695696/// A replacement for `#[derive(Reflect)]` to be used with foreign types which697/// the definitions of cannot be altered.698///699/// This macro is an alternative to [`impl_reflect_opaque!`] and [`impl_from_reflect_opaque!`]700/// which implement foreign types as Opaque types. Note that there is no `impl_from_reflect`,701/// as this macro will do the job of both. This macro implements them using one of the reflect702/// variant traits (`bevy_reflect::{Struct, TupleStruct, Enum}`, etc.),703/// which have greater functionality. The type being reflected must be in scope, as you cannot704/// qualify it in the macro as e.g. `bevy::prelude::Vec3`.705///706/// It is necessary to add a `#[type_path = "my_crate::foo"]` attribute to all types.707///708/// It may be necessary to add `#[reflect(Default)]` for some types, specifically non-constructible709/// foreign types. Without `Default` reflected for such types, you will usually get an arcane710/// error message and fail to compile. If the type does not implement `Default`, it may not711/// be possible to reflect without extending the macro.712///713///714/// # Example715/// Implementing `Reflect` for `bevy::prelude::Vec3` as a struct type:716/// ```ignore (bevy_reflect is not accessible from this crate)717/// use bevy::prelude::Vec3;718///719/// impl_reflect!(720/// #[reflect(PartialEq, Serialize, Deserialize, Default)]721/// #[type_path = "bevy::prelude"]722/// struct Vec3 {723/// x: f32,724/// y: f32,725/// z: f32726/// }727/// );728/// ```729#[proc_macro]730pub fn impl_reflect(input: TokenStream) -> TokenStream {731let ast = parse_macro_input!(input as DeriveInput);732match_reflect_impls(ast, ReflectImplSource::ImplRemoteType)733}734735/// A macro used to generate a `FromReflect` trait implementation for the given type.736///737/// This is functionally the same as [deriving `FromReflect`] on a type that [derives `Reflect`] using738/// the `#[reflect(opaque)]` container attribute.739///740/// The only reason this macro exists is so that `bevy_reflect` can easily implement `FromReflect` on741/// primitives and other opaque types internally.742///743/// Please note that this macro will not work with any type that [derives `Reflect`] normally744/// or makes use of the [`impl_reflect_opaque!`] macro, as those macros also implement `FromReflect`745/// by default.746///747/// # Examples748///749/// ```ignore (bevy_reflect is not accessible from this crate)750/// impl_from_reflect_opaque!(foo<T1, T2: Baz> where T1: Bar);751/// ```752///753/// [deriving `FromReflect`]: FromReflect754/// [derives `Reflect`]: Reflect755#[proc_macro]756pub fn impl_from_reflect_opaque(input: TokenStream) -> TokenStream {757let def = parse_macro_input!(input with ReflectOpaqueDef::parse_from_reflect);758759let default_name = &def.type_path.segments.last().unwrap().ident;760let type_path = if def.type_path.leading_colon.is_none()761&& def.custom_path.is_none()762&& def.generics.params.is_empty()763{764ReflectTypePath::Primitive(default_name)765} else {766ReflectTypePath::External {767path: &def.type_path,768custom_path: def.custom_path.map(|alias| alias.into_path(default_name)),769generics: &def.generics,770}771};772773let from_reflect_impl =774from_reflect::impl_opaque(&ReflectMeta::new(type_path, def.traits.unwrap_or_default()));775776TokenStream::from(quote! {777const _: () = {778#from_reflect_impl779};780})781}782783/// A replacement for [deriving `TypePath`] for use on foreign types.784///785/// Since (unlike the derive) this macro may be invoked in a different module to where the type is defined,786/// it requires an 'absolute' path definition.787///788/// Specifically, a leading `::` denoting a global path must be specified789/// or a preceding `(in my_crate::foo)` to specify the custom path must be used.790///791/// # Examples792///793/// Implementing `TypePath` on a foreign type:794/// ```ignore (bevy_reflect is not accessible from this crate)795/// impl_type_path!(::foreign_crate::foo::bar::Baz);796/// ```797///798/// On a generic type (this can also accept trait bounds):799/// ```ignore (bevy_reflect is not accessible from this crate)800/// impl_type_path!(::foreign_crate::Foo<T>);801/// impl_type_path!(::foreign_crate::Goo<T: ?Sized>);802/// ```803///804/// On a primitive (note this will not compile for a non-primitive type):805/// ```ignore (bevy_reflect is not accessible from this crate)806/// impl_type_path!(bool);807/// ```808///809/// With a custom type path:810/// ```ignore (bevy_reflect is not accessible from this crate)811/// impl_type_path!((in other_crate::foo::bar) Baz);812/// ```813///814/// With a custom type path and a custom type name:815/// ```ignore (bevy_reflect is not accessible from this crate)816/// impl_type_path!((in other_crate::foo as Baz) Bar);817/// ```818///819/// [deriving `TypePath`]: TypePath820#[proc_macro]821pub fn impl_type_path(input: TokenStream) -> TokenStream {822let def = parse_macro_input!(input as NamedTypePathDef);823824let type_path = match def {825NamedTypePathDef::External {826ref path,827custom_path,828ref generics,829} => {830let default_name = &path.segments.last().unwrap().ident;831832ReflectTypePath::External {833path,834custom_path: custom_path.map(|path| path.into_path(default_name)),835generics,836}837}838NamedTypePathDef::Primitive(ref ident) => ReflectTypePath::Primitive(ident),839};840841let meta = ReflectMeta::new(type_path, ContainerAttributes::default());842843let type_path_impl = impls::impl_type_path(&meta);844845TokenStream::from(quote! {846const _: () = {847#type_path_impl848};849})850}851852/// Collects and loads type registrations when using `auto_register_static` feature.853///854/// Correctly using this macro requires following:855/// 1. This macro must be called **last** during compilation. This can be achieved by putting your main function856/// in a separate crate or restructuring your project to be separated into `bin` and `lib`, and putting this macro in `bin`.857/// Any automatic type registrations using `#[derive(Reflect)]` within the same crate as this macro are not guaranteed to run.858/// 2. Your project must be compiled with `auto_register_static` feature **and** `BEVY_REFLECT_AUTO_REGISTER_STATIC=1` env variable.859/// Enabling the feature generates registration functions while setting the variable enables export and860/// caching of registration function names.861/// 3. Must be called before creating `App` or using `TypeRegistry::register_derived_types`.862///863/// If you're experiencing linking issues try running `cargo clean` before rebuilding.864#[proc_macro]865pub fn load_type_registrations(_input: TokenStream) -> TokenStream {866if !cfg!(feature = "auto_register_static") {867return TokenStream::new();868}869870let Ok(dir) = fs::read_dir(PathBuf::from("target").join("bevy_reflect_type_registrations"))871else {872return TokenStream::new();873};874let mut str_buf = String::new();875let mut registration_fns = Vec::new();876for file_path in dir {877let mut file = fs::OpenOptions::new()878.read(true)879.open(file_path.unwrap().path())880.unwrap();881file.read_to_string(&mut str_buf).unwrap();882registration_fns.extend(str_buf.lines().filter(|s| !s.is_empty()).map(|s| {883s.parse::<proc_macro2::TokenStream>()884.expect("Unexpected function name")885}));886str_buf.clear();887}888let bevy_reflect_path = meta::get_bevy_reflect_path();889TokenStream::from(quote! {890{891fn _register_types(){892unsafe extern "Rust" {893#( safe fn #registration_fns(registry_ptr: &mut #bevy_reflect_path::TypeRegistry); )*894};895#( #bevy_reflect_path::__macro_exports::auto_register::push_registration_fn(#registration_fns); )*896}897_register_types();898}899})900}901902903