bevy_reflect_derive/lib.rs
1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3//! This crate contains macros used by Bevy's `Reflect` API.
4//!
5//! The main export of this crate is the derive macro for [`Reflect`]. This allows
6//! types to easily implement `Reflect` along with other `bevy_reflect` traits,
7//! such as `Struct`, `GetTypeRegistration`, and more— all with a single derive!
8//!
9//! Some other noteworthy exports include the derive macros for [`FromReflect`] and
10//! [`TypePath`], as well as the [`reflect_trait`] attribute macro.
11//!
12//! [`Reflect`]: crate::derive_reflect
13//! [`FromReflect`]: crate::derive_from_reflect
14//! [`TypePath`]: crate::derive_type_path
15//! [`reflect_trait`]: macro@reflect_trait
16
17extern crate proc_macro;
18
19mod container_attributes;
20mod custom_attributes;
21mod derive_data;
22#[cfg(feature = "reflect_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 serialization;
35mod string_expr;
36mod struct_utility;
37mod trait_reflection;
38mod type_path;
39mod where_clause_options;
40
41use std::{fs, io::Read, path::PathBuf};
42
43use crate::derive_data::{ReflectDerive, ReflectMeta, ReflectStruct};
44use container_attributes::ContainerAttributes;
45use derive_data::{ReflectImplSource, ReflectProvenance, ReflectTraitToImpl, ReflectTypePath};
46use proc_macro::TokenStream;
47use quote::quote;
48use reflect_opaque::ReflectOpaqueDef;
49use syn::{parse_macro_input, DeriveInput};
50use type_path::NamedTypePathDef;
51
52pub(crate) static REFLECT_ATTRIBUTE_NAME: &str = "reflect";
53pub(crate) static TYPE_PATH_ATTRIBUTE_NAME: &str = "type_path";
54pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";
55
56/// Used both for [`impl_reflect`] and [`derive_reflect`].
57///
58/// [`impl_reflect`]: macro@impl_reflect
59/// [`derive_reflect`]: derive_reflect()
60fn match_reflect_impls(ast: DeriveInput, source: ReflectImplSource) -> TokenStream {
61 let derive_data = match ReflectDerive::from_input(
62 &ast,
63 ReflectProvenance {
64 source,
65 trait_: ReflectTraitToImpl::Reflect,
66 },
67 ) {
68 Ok(data) => data,
69 Err(err) => return err.into_compile_error().into(),
70 };
71
72 let assertions = impls::impl_assertions(&derive_data);
73
74 let (reflect_impls, from_reflect_impl) = match derive_data {
75 ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => (
76 impls::impl_struct(&struct_data),
77 if struct_data.meta().from_reflect().should_auto_derive() {
78 Some(from_reflect::impl_struct(&struct_data))
79 } else {
80 None
81 },
82 ),
83 ReflectDerive::TupleStruct(struct_data) => (
84 impls::impl_tuple_struct(&struct_data),
85 if struct_data.meta().from_reflect().should_auto_derive() {
86 Some(from_reflect::impl_tuple_struct(&struct_data))
87 } else {
88 None
89 },
90 ),
91 ReflectDerive::Enum(enum_data) => (
92 impls::impl_enum(&enum_data),
93 if enum_data.meta().from_reflect().should_auto_derive() {
94 Some(from_reflect::impl_enum(&enum_data))
95 } else {
96 None
97 },
98 ),
99 ReflectDerive::Opaque(meta) => (
100 impls::impl_opaque(&meta),
101 if meta.from_reflect().should_auto_derive() {
102 Some(from_reflect::impl_opaque(&meta))
103 } else {
104 None
105 },
106 ),
107 };
108
109 TokenStream::from(quote! {
110 const _: () = {
111 #reflect_impls
112
113 #from_reflect_impl
114
115 #assertions
116 };
117 })
118}
119
120/// The main derive macro used by `bevy_reflect` for deriving its `Reflect` trait.
121///
122/// This macro can be used on all structs and enums (unions are not supported).
123/// It will automatically generate implementations for `Reflect`, `Typed`, `GetTypeRegistration`, and `FromReflect`.
124/// And, depending on the item's structure, will either implement `Struct`, `TupleStruct`, or `Enum`.
125///
126/// See the [`FromReflect`] derive macro for more information on how to customize the [`FromReflect`] implementation.
127/// To implement [`FromReflect`] manually while deriving [`Reflect`], [opt out](#reflectfrom_reflect--false) of the default implementation.
128///
129/// # Container Attributes
130///
131/// This macro comes with some helper attributes that can be added to the container item
132/// 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 Registrations
149///
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 Identifiers
157///
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 on
161/// the type's [`Clone`] implementation.
162/// A custom implementation may be provided using `#[reflect(Clone(my_clone_func))]` where
163/// `my_clone_func` is the path to a function matching the signature:
164/// `(&Self) -> Self`.
165/// * `#[reflect(Debug)]` will force the implementation of `Reflect::debug` to rely on
166/// the type's [`Debug`] implementation.
167/// A custom implementation may be provided using `#[reflect(Debug(my_debug_func))]` where
168/// `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 on
171/// the type's [`PartialEq`] implementation.
172/// A custom implementation may be provided using `#[reflect(PartialEq(my_partial_eq_func))]` where
173/// `my_partial_eq_func` is the path to a function matching the signature:
174/// `(&Self, value: &dyn #bevy_reflect_path::Reflect) -> bool`.
175/// * `#[reflect(PartialOrd)]` will force the implementation of `PartialReflect::reflect_partial_cmp`
176/// to rely on the type's [`PartialOrd`] implementation.
177/// A custom implementation may be provided using `#[reflect(PartialOrd(my_partial_cmp_fn))]` where
178/// `my_partial_cmp_fn` is the path to a function matching the signature:
179/// `(&Self, value: &dyn #bevy_reflect_path::PartialReflect) -> Option<::core::cmp::Ordering>`.
180/// * `#[reflect(Hash)]` will force the implementation of `Reflect::reflect_hash` to rely on
181/// the type's [`Hash`] implementation.
182/// A custom implementation may be provided using `#[reflect(Hash(my_hash_func))]` where
183/// `my_hash_func` is the path to a function matching the signature: `(&Self) -> u64`.
184/// * `#[reflect(Default)]` will register the `ReflectDefault` type data as normal.
185/// However, it will also affect how certain other operations are performed in order
186/// to improve performance and/or robustness.
187/// An example of where this is used is in the [`FromReflect`] derive macro,
188/// where adding this attribute will cause the `FromReflect` implementation to create
189/// a base value using its [`Default`] implementation avoiding issues with ignored fields
190/// (for structs and tuple structs only).
191///
192/// ## `#[reflect(opaque)]`
193///
194/// The `#[reflect(opaque)]` attribute denotes that the item should implement `Reflect` as an opaque type,
195/// hiding its structure and fields from the reflection API.
196/// This means that it will forgo implementing `Struct`, `TupleStruct`, or `Enum`.
197///
198/// Furthermore, it requires that the type implements [`Clone`].
199/// If planning to serialize this type using the reflection serializers,
200/// then the `Serialize` and `Deserialize` traits will need to be implemented and registered as well.
201///
202/// ## `#[reflect(from_reflect = false)]`
203///
204/// This attribute will opt-out of the default `FromReflect` implementation.
205///
206/// This is useful for when a type can't or shouldn't implement `FromReflect`,
207/// or if a manual implementation is desired.
208///
209/// Note that in the latter case, `ReflectFromReflect` will no longer be automatically registered.
210///
211/// ## `#[reflect(type_path = false)]`
212///
213/// This attribute will opt-out of the default `TypePath` implementation.
214///
215/// This is useful for when a type can't or shouldn't implement `TypePath`,
216/// or if a manual implementation is desired.
217///
218/// ## `#[reflect(no_field_bounds)]`
219///
220/// This attribute will opt-out of the default trait bounds added to all field types
221/// for the generated reflection trait impls.
222///
223/// Normally, all fields will have the bounds `TypePath`, and either `FromReflect` or `Reflect`
224/// depending on if `#[reflect(from_reflect = false)]` is used.
225/// However, this might not always be desirable, and so this attribute may be used to remove those bounds.
226///
227/// ### Example
228///
229/// If a type is recursive the default bounds will cause an overflow error when building:
230///
231/// ```ignore (bevy_reflect is not accessible from this crate)
232/// #[derive(Reflect)] // ERROR: overflow evaluating the requirement `Foo: FromReflect`
233/// struct Foo {
234/// foo: Vec<Foo>,
235/// }
236///
237/// // Generates a where clause like:
238/// // impl bevy_reflect::Reflect for Foo
239/// // where
240/// // Foo: Any + Send + Sync,
241/// // Vec<Foo>: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
242/// ```
243///
244/// In this case, `Foo` is given the bounds `Vec<Foo>: FromReflect + ...`,
245/// which requires that `Foo` implements `FromReflect`,
246/// which requires that `Vec<Foo>` implements `FromReflect`,
247/// and so on, resulting in the error.
248///
249/// To fix this, we can add `#[reflect(no_field_bounds)]` to `Foo` to remove the bounds on `Vec<Foo>`:
250///
251/// ```ignore (bevy_reflect is not accessible from this crate)
252/// #[derive(Reflect)]
253/// #[reflect(no_field_bounds)]
254/// struct Foo {
255/// foo: Vec<Foo>,
256/// }
257///
258/// // Generates a where clause like:
259/// // impl bevy_reflect::Reflect for Foo
260/// // where
261/// // Self: Any + Send + Sync,
262/// ```
263///
264/// ## `#[reflect(where T: Trait, U::Assoc: Trait, ...)]`
265///
266/// This attribute can be used to add additional bounds to the generated reflection trait impls.
267///
268/// This is useful for when a type needs certain bounds only applied to the reflection impls
269/// that are not otherwise automatically added by the derive macro.
270///
271/// ### Example
272///
273/// In the example below, we want to enforce that `T::Assoc: List` is required in order for
274/// `Foo<T>` to be reflectable, but we don't want it to prevent `Foo<T>` from being used
275/// in places where `T::Assoc: List` is not required.
276///
277/// ```ignore
278/// trait Trait {
279/// type Assoc;
280/// }
281///
282/// #[derive(Reflect)]
283/// #[reflect(where T::Assoc: List)]
284/// struct Foo<T: Trait> where T::Assoc: Default {
285/// value: T::Assoc,
286/// }
287///
288/// // Generates a where clause like:
289/// //
290/// // impl<T: Trait> bevy_reflect::Reflect for Foo<T>
291/// // where
292/// // Foo<T>: Any + Send + Sync,
293/// // T::Assoc: Default,
294/// // T: TypePath,
295/// // T::Assoc: FromReflect + TypePath + MaybeTyped + RegisterForReflection,
296/// // T::Assoc: List,
297/// // {/* ... */}
298/// ```
299///
300/// ## `#[reflect(@...)]`
301///
302/// This attribute can be used to register custom attributes to the type's `TypeInfo`.
303///
304/// It accepts any expression after the `@` symbol that resolves to a value which implements `Reflect`.
305///
306/// Any number of custom attributes may be registered, however, each the type of each attribute must be unique.
307/// If two attributes of the same type are registered, the last one will overwrite the first.
308///
309/// ### Example
310///
311/// ```ignore
312/// #[derive(Reflect)]
313/// struct Required;
314///
315/// #[derive(Reflect)]
316/// struct EditorTooltip(String);
317///
318/// impl EditorTooltip {
319/// fn new(text: &str) -> Self {
320/// Self(text.to_string())
321/// }
322/// }
323///
324/// #[derive(Reflect)]
325/// // Specify a "required" status and tooltip:
326/// #[reflect(@Required, @EditorTooltip::new("An ID is required!"))]
327/// struct Id(u8);
328/// ```
329/// ## `#[reflect(no_auto_register)]`
330///
331/// This attribute will opt-out of the automatic reflect type registration.
332///
333/// All non-generic types annotated with `#[derive(Reflect)]` are usually automatically registered on app startup.
334/// If this behavior is not desired, this attribute may be used to disable it for the annotated type.
335///
336/// # Field Attributes
337///
338/// Along with the container attributes, this macro comes with some attributes that may be applied
339/// to the contained fields themselves.
340///
341/// ## `#[reflect(ignore)]`
342///
343/// This attribute simply marks a field to be ignored by the reflection API.
344///
345/// This allows fields to completely opt-out of reflection,
346/// which may be useful for maintaining invariants, keeping certain data private,
347/// or allowing the use of types that do not implement `Reflect` within the container.
348///
349/// ## `#[reflect(skip_serializing)]`
350///
351/// This works similar to `#[reflect(ignore)]`, but rather than opting out of _all_ of reflection,
352/// it simply opts the field out of both serialization and deserialization.
353/// This can be useful when a field should be accessible via reflection, but may not make
354/// sense in a serialized form, such as computed data.
355///
356/// What this does is register the `SerializationData` type within the `GetTypeRegistration` implementation,
357/// which will be used by the reflection serializers to determine whether or not the field is serializable.
358///
359/// ## `#[reflect(clone)]`
360///
361/// This attribute affects the `Reflect::reflect_clone` implementation.
362///
363/// Without this attribute, the implementation will rely on the field's own `Reflect::reflect_clone` implementation.
364/// When this attribute is present, the implementation will instead use the field's `Clone` implementation directly.
365///
366/// The attribute may also take the path to a custom function like `#[reflect(clone = "path::to::my_clone_func")]`,
367/// where `my_clone_func` matches the signature `(&Self) -> Self`.
368///
369/// This attribute does nothing if the containing struct/enum has the `#[reflect(Clone)]` attribute.
370///
371/// ## `#[reflect(@...)]`
372///
373/// This attribute can be used to register custom attributes to the field's `TypeInfo`.
374///
375/// It accepts any expression after the `@` symbol that resolves to a value which implements `Reflect`.
376///
377/// Any number of custom attributes may be registered, however, each the type of each attribute must be unique.
378/// If two attributes of the same type are registered, the last one will overwrite the first.
379///
380/// ### Example
381///
382/// ```ignore
383/// #[derive(Reflect)]
384/// struct EditorTooltip(String);
385///
386/// impl EditorTooltip {
387/// fn new(text: &str) -> Self {
388/// Self(text.to_string())
389/// }
390/// }
391///
392/// #[derive(Reflect)]
393/// struct Slider {
394/// // Specify a custom range and tooltip:
395/// #[reflect(@0.0..=1.0, @EditorTooltip::new("Must be between 0 and 1"))]
396/// value: f32,
397/// }
398/// ```
399///
400/// [`reflect_trait`]: macro@reflect_trait
401#[proc_macro_derive(Reflect, attributes(reflect, type_path, type_name))]
402pub fn derive_reflect(input: TokenStream) -> TokenStream {
403 let ast = parse_macro_input!(input as DeriveInput);
404 match_reflect_impls(ast, ReflectImplSource::DeriveLocalType)
405}
406
407/// Derives the `FromReflect` trait.
408///
409/// # Field Attributes
410///
411/// ## `#[reflect(ignore)]`
412///
413/// The `#[reflect(ignore)]` attribute is shared with the [`#[derive(Reflect)]`](Reflect) macro and has much of the same
414/// functionality in that it denotes that a field will be ignored by the reflection API.
415///
416/// The only major difference is that using it with this derive requires that the field implements [`Default`].
417/// Without this requirement, there would be no way for `FromReflect` to automatically construct missing fields
418/// that have been ignored.
419///
420/// ## `#[reflect(default)]`
421///
422/// If a field cannot be read, this attribute specifies a default value to be used in its place.
423///
424/// By default, this attribute denotes that the field's type implements [`Default`].
425/// However, it can also take in a path string to a user-defined function that will return the default value.
426/// This takes the form: `#[reflect(default = "path::to::my_function")]` where `my_function` is a parameterless
427/// function that must return some default value for the type.
428///
429/// Specifying a custom default can be used to give different fields their own specialized defaults,
430/// or to remove the `Default` requirement on fields marked with `#[reflect(ignore)]`.
431/// Additionally, either form of this attribute can be used to fill in fields that are simply missing,
432/// such as when converting a partially-constructed dynamic type to a concrete one.
433#[proc_macro_derive(FromReflect, attributes(reflect))]
434pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
435 let ast = parse_macro_input!(input as DeriveInput);
436
437 let derive_data = match ReflectDerive::from_input(
438 &ast,
439 ReflectProvenance {
440 source: ReflectImplSource::DeriveLocalType,
441 trait_: ReflectTraitToImpl::FromReflect,
442 },
443 ) {
444 Ok(data) => data,
445 Err(err) => return err.into_compile_error().into(),
446 };
447
448 let from_reflect_impl = match derive_data {
449 ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => {
450 from_reflect::impl_struct(&struct_data)
451 }
452 ReflectDerive::TupleStruct(struct_data) => from_reflect::impl_tuple_struct(&struct_data),
453 ReflectDerive::Enum(meta) => from_reflect::impl_enum(&meta),
454 ReflectDerive::Opaque(meta) => from_reflect::impl_opaque(&meta),
455 };
456
457 TokenStream::from(quote! {
458 const _: () = {
459 #from_reflect_impl
460 };
461 })
462}
463
464/// Derives the `TypePath` trait, providing a stable alternative to [`std::any::type_name`].
465///
466/// # Container Attributes
467///
468/// ## `#[type_path = "my_crate::foo"]`
469///
470/// Optionally specifies a custom module path to use instead of [`module_path`].
471///
472/// This path does not include the final identifier.
473///
474/// ## `#[type_name = "RenamedType"]`
475///
476/// Optionally specifies a new terminating identifier for `TypePath`.
477///
478/// To use this attribute, `#[type_path = "..."]` must also be specified.
479#[proc_macro_derive(TypePath, attributes(type_path, type_name))]
480pub fn derive_type_path(input: TokenStream) -> TokenStream {
481 let ast = parse_macro_input!(input as DeriveInput);
482 let derive_data = match ReflectDerive::from_input(
483 &ast,
484 ReflectProvenance {
485 source: ReflectImplSource::DeriveLocalType,
486 trait_: ReflectTraitToImpl::TypePath,
487 },
488 ) {
489 Ok(data) => data,
490 Err(err) => return err.into_compile_error().into(),
491 };
492
493 let type_path_impl = impls::impl_type_path(derive_data.meta());
494
495 TokenStream::from(quote! {
496 const _: () = {
497 #type_path_impl
498 };
499 })
500}
501
502/// A macro that automatically generates type data for traits, which their implementors can then register.
503///
504/// The output of this macro is a struct that takes reflected instances of the implementor's type
505/// and returns the value as a trait object.
506/// Because of this, **it can only be used on [object-safe] traits.**
507///
508/// For a trait named `MyTrait`, this will generate the struct `ReflectMyTrait`.
509/// The generated struct can be created using `FromType` with any type that implements the trait.
510/// The creation and registration of this generated struct as type data can be automatically handled
511/// by [`#[derive(Reflect)]`](Reflect).
512///
513/// # Example
514///
515/// ```ignore (bevy_reflect is not accessible from this crate)
516/// # use std::any::TypeId;
517/// # use bevy_reflect_derive::{Reflect, reflect_trait};
518/// #[reflect_trait] // Generates `ReflectMyTrait`
519/// trait MyTrait {
520/// fn print(&self) -> &str;
521/// }
522///
523/// #[derive(Reflect)]
524/// #[reflect(MyTrait)] // Automatically registers `ReflectMyTrait`
525/// struct SomeStruct;
526///
527/// impl MyTrait for SomeStruct {
528/// fn print(&self) -> &str {
529/// "Hello, World!"
530/// }
531/// }
532///
533/// // We can create the type data manually if we wanted:
534/// let my_trait: ReflectMyTrait = FromType::<SomeStruct>::from_type();
535///
536/// // Or we can simply get it from the registry:
537/// let mut registry = TypeRegistry::default();
538/// registry.register::<SomeStruct>();
539/// let my_trait = registry
540/// .get_type_data::<ReflectMyTrait>(TypeId::of::<SomeStruct>())
541/// .unwrap();
542///
543/// // Then use it on reflected data
544/// let reflected: Box<dyn Reflect> = Box::new(SomeStruct);
545/// let reflected_my_trait: &dyn MyTrait = my_trait.get(&*reflected).unwrap();
546/// assert_eq!("Hello, World!", reflected_my_trait.print());
547/// ```
548///
549/// [object-safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety
550#[proc_macro_attribute]
551pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream {
552 trait_reflection::reflect_trait(&args, input)
553}
554
555/// Generates a wrapper type that can be used to "derive `Reflect`" for remote types.
556///
557/// This works by wrapping the remote type in a generated wrapper that has the `#[repr(transparent)]` attribute.
558/// This allows the two types to be safely [transmuted] back-and-forth.
559///
560/// # Defining the Wrapper
561///
562/// Before defining the wrapper type, please note that it is _required_ that all fields of the remote type are public.
563/// The generated code will, at times, need to access or mutate them,
564/// and we do not currently have a way to assign getters/setters to each field
565/// (but this may change in the future).
566///
567/// The wrapper definition should match the remote type 1-to-1.
568/// This includes the naming and ordering of the fields and variants.
569///
570/// Generics and lifetimes do _not_ need to have the same names, however, they _do_ need to follow the same order.
571/// Additionally, whether generics are inlined or placed in a where clause should not matter.
572///
573/// Lastly, all macros and doc-comments should be placed __below__ this attribute.
574/// If they are placed above, they will not be properly passed to the generated wrapper type.
575///
576/// # Example
577///
578/// Given a remote type, `RemoteType`:
579///
580/// ```
581/// #[derive(Default)]
582/// struct RemoteType<T>
583/// where
584/// T: Default + Clone,
585/// {
586/// pub foo: T,
587/// pub bar: usize
588/// }
589/// ```
590///
591/// We would define our wrapper type as such:
592///
593/// ```ignore
594/// use external_crate::RemoteType;
595///
596/// #[reflect_remote(RemoteType<T>)]
597/// #[derive(Default)]
598/// pub struct WrapperType<T: Default + Clone> {
599/// pub foo: T,
600/// pub bar: usize
601/// }
602/// ```
603///
604/// Apart from all the reflection trait implementations, this generates something like the following:
605///
606/// ```ignore
607/// use external_crate::RemoteType;
608///
609/// #[derive(Default)]
610/// #[repr(transparent)]
611/// pub struct Wrapper<T: Default + Clone>(RemoteType<T>);
612/// ```
613///
614/// # Usage as a Field
615///
616/// You can tell `Reflect` to use a remote type's wrapper internally on fields of a struct or enum.
617/// This allows the real type to be used as usual while `Reflect` handles everything internally.
618/// To do this, add the `#[reflect(remote = path::to::MyType)]` attribute to your field:
619///
620/// ```ignore
621/// #[derive(Reflect)]
622/// struct SomeStruct {
623/// #[reflect(remote = RemoteTypeWrapper)]
624/// data: RemoteType
625/// }
626/// ```
627///
628/// ## Safety
629///
630/// When using the `#[reflect(remote = path::to::MyType)]` field attribute, be sure you are defining the correct wrapper type.
631/// Internally, this field will be unsafely [transmuted], and is only sound if using a wrapper generated for the remote type.
632/// This also means keeping your wrapper definitions up-to-date with the remote types.
633///
634/// [transmuted]: std::mem::transmute
635#[proc_macro_attribute]
636pub fn reflect_remote(args: TokenStream, input: TokenStream) -> TokenStream {
637 remote::reflect_remote(args, input)
638}
639
640/// A macro used to generate reflection trait implementations for the given type.
641///
642/// This is functionally the same as [deriving `Reflect`] using the `#[reflect(opaque)]` container attribute.
643///
644/// The only reason for this macro's existence is so that `bevy_reflect` can easily implement the reflection traits
645/// on primitives and other opaque types internally.
646///
647/// Since this macro also implements `TypePath`, the type path must be explicit.
648/// See [`impl_type_path!`] for the exact syntax.
649///
650/// # Examples
651///
652/// Types can be passed with or without registering type data:
653///
654/// ```ignore (bevy_reflect is not accessible from this crate)
655/// impl_reflect_opaque!(my_crate::Foo);
656/// impl_reflect_opaque!(my_crate::Bar(Debug, Default, Serialize, Deserialize));
657/// ```
658///
659/// Generic types can also specify their parameters and bounds:
660///
661/// ```ignore (bevy_reflect is not accessible from this crate)
662/// impl_reflect_opaque!(my_crate::Foo<T1, T2: Baz> where T1: Bar (Default, Serialize, Deserialize));
663/// ```
664///
665/// Custom type paths can be specified:
666///
667/// ```ignore (bevy_reflect is not accessible from this crate)
668/// impl_reflect_opaque!((in not_my_crate as NotFoo) Foo(Debug, Default));
669/// ```
670///
671/// [deriving `Reflect`]: Reflect
672#[proc_macro]
673pub fn impl_reflect_opaque(input: TokenStream) -> TokenStream {
674 let def = parse_macro_input!(input with ReflectOpaqueDef::parse_reflect);
675
676 let default_name = &def.type_path.segments.last().unwrap().ident;
677 let type_path = if def.type_path.leading_colon.is_none() && def.custom_path.is_none() {
678 ReflectTypePath::Primitive(default_name)
679 } else {
680 ReflectTypePath::External {
681 path: &def.type_path,
682 custom_path: def.custom_path.map(|path| path.into_path(default_name)),
683 generics: &def.generics,
684 }
685 };
686
687 let meta = ReflectMeta::new(type_path, def.traits.unwrap_or_default());
688
689 #[cfg(feature = "reflect_documentation")]
690 let meta = meta.with_docs(documentation::Documentation::from_attributes(&def.attrs));
691
692 let reflect_impls = impls::impl_opaque(&meta);
693 let from_reflect_impl = from_reflect::impl_opaque(&meta);
694
695 TokenStream::from(quote! {
696 const _: () = {
697 #reflect_impls
698 #from_reflect_impl
699 };
700 })
701}
702
703/// A replacement for `#[derive(Reflect)]` to be used with foreign types which
704/// the definitions of cannot be altered.
705///
706/// This macro is an alternative to [`impl_reflect_opaque!`] and [`impl_from_reflect_opaque!`]
707/// which implement foreign types as Opaque types. Note that there is no `impl_from_reflect`,
708/// as this macro will do the job of both. This macro implements them using one of the reflect
709/// variant traits (`bevy_reflect::{Struct, TupleStruct, Enum}`, etc.),
710/// which have greater functionality. The type being reflected must be in scope, as you cannot
711/// qualify it in the macro as e.g. `bevy::prelude::Vec3`.
712///
713/// It is necessary to add a `#[type_path = "my_crate::foo"]` attribute to all types.
714///
715/// It may be necessary to add `#[reflect(Default)]` for some types, specifically non-constructible
716/// foreign types. Without `Default` reflected for such types, you will usually get an arcane
717/// error message and fail to compile. If the type does not implement `Default`, it may not
718/// be possible to reflect without extending the macro.
719///
720///
721/// # Example
722/// Implementing `Reflect` for `bevy::prelude::Vec3` as a struct type:
723/// ```ignore (bevy_reflect is not accessible from this crate)
724/// use bevy::prelude::Vec3;
725///
726/// impl_reflect!(
727/// #[reflect(PartialEq, Serialize, Deserialize, Default)]
728/// #[type_path = "bevy::prelude"]
729/// struct Vec3 {
730/// x: f32,
731/// y: f32,
732/// z: f32
733/// }
734/// );
735/// ```
736#[proc_macro]
737pub fn impl_reflect(input: TokenStream) -> TokenStream {
738 let ast = parse_macro_input!(input as DeriveInput);
739 match_reflect_impls(ast, ReflectImplSource::ImplRemoteType)
740}
741
742/// A macro used to generate a `FromReflect` trait implementation for the given type.
743///
744/// This is functionally the same as [deriving `FromReflect`] on a type that [derives `Reflect`] using
745/// the `#[reflect(opaque)]` container attribute.
746///
747/// The only reason this macro exists is so that `bevy_reflect` can easily implement `FromReflect` on
748/// primitives and other opaque types internally.
749///
750/// Please note that this macro will not work with any type that [derives `Reflect`] normally
751/// or makes use of the [`impl_reflect_opaque!`] macro, as those macros also implement `FromReflect`
752/// by default.
753///
754/// # Examples
755///
756/// ```ignore (bevy_reflect is not accessible from this crate)
757/// impl_from_reflect_opaque!(foo<T1, T2: Baz> where T1: Bar);
758/// ```
759///
760/// [deriving `FromReflect`]: FromReflect
761/// [derives `Reflect`]: Reflect
762#[proc_macro]
763pub fn impl_from_reflect_opaque(input: TokenStream) -> TokenStream {
764 let def = parse_macro_input!(input with ReflectOpaqueDef::parse_from_reflect);
765
766 let default_name = &def.type_path.segments.last().unwrap().ident;
767 let type_path = if def.type_path.leading_colon.is_none()
768 && def.custom_path.is_none()
769 && def.generics.params.is_empty()
770 {
771 ReflectTypePath::Primitive(default_name)
772 } else {
773 ReflectTypePath::External {
774 path: &def.type_path,
775 custom_path: def.custom_path.map(|alias| alias.into_path(default_name)),
776 generics: &def.generics,
777 }
778 };
779
780 let from_reflect_impl =
781 from_reflect::impl_opaque(&ReflectMeta::new(type_path, def.traits.unwrap_or_default()));
782
783 TokenStream::from(quote! {
784 const _: () = {
785 #from_reflect_impl
786 };
787 })
788}
789
790/// A replacement for [deriving `TypePath`] for use on foreign types.
791///
792/// Since (unlike the derive) this macro may be invoked in a different module to where the type is defined,
793/// it requires an 'absolute' path definition.
794///
795/// Specifically, a leading `::` denoting a global path must be specified
796/// or a preceding `(in my_crate::foo)` to specify the custom path must be used.
797///
798/// # Examples
799///
800/// Implementing `TypePath` on a foreign type:
801/// ```ignore (bevy_reflect is not accessible from this crate)
802/// impl_type_path!(::foreign_crate::foo::bar::Baz);
803/// ```
804///
805/// On a generic type (this can also accept trait bounds):
806/// ```ignore (bevy_reflect is not accessible from this crate)
807/// impl_type_path!(::foreign_crate::Foo<T>);
808/// impl_type_path!(::foreign_crate::Goo<T: ?Sized>);
809/// ```
810///
811/// On a primitive (note this will not compile for a non-primitive type):
812/// ```ignore (bevy_reflect is not accessible from this crate)
813/// impl_type_path!(bool);
814/// ```
815///
816/// With a custom type path:
817/// ```ignore (bevy_reflect is not accessible from this crate)
818/// impl_type_path!((in other_crate::foo::bar) Baz);
819/// ```
820///
821/// With a custom type path and a custom type name:
822/// ```ignore (bevy_reflect is not accessible from this crate)
823/// impl_type_path!((in other_crate::foo as Baz) Bar);
824/// ```
825///
826/// [deriving `TypePath`]: TypePath
827#[proc_macro]
828pub fn impl_type_path(input: TokenStream) -> TokenStream {
829 let def = parse_macro_input!(input as NamedTypePathDef);
830
831 let type_path = match def {
832 NamedTypePathDef::External {
833 ref path,
834 custom_path,
835 ref generics,
836 } => {
837 let default_name = &path.segments.last().unwrap().ident;
838
839 ReflectTypePath::External {
840 path,
841 custom_path: custom_path.map(|path| path.into_path(default_name)),
842 generics,
843 }
844 }
845 NamedTypePathDef::Primitive(ref ident) => ReflectTypePath::Primitive(ident),
846 };
847
848 let meta = ReflectMeta::new(type_path, ContainerAttributes::default());
849
850 let type_path_impl = impls::impl_type_path(&meta);
851
852 TokenStream::from(quote! {
853 const _: () = {
854 #type_path_impl
855 };
856 })
857}
858
859/// Collects and loads type registrations when using `auto_register_static` feature.
860///
861/// Correctly using this macro requires following:
862/// 1. This macro must be called **last** during compilation. This can be achieved by putting your main function
863/// in a separate crate or restructuring your project to be separated into `bin` and `lib`, and putting this macro in `bin`.
864/// Any automatic type registrations using `#[derive(Reflect)]` within the same crate as this macro are not guaranteed to run.
865/// 2. Your project must be compiled with `auto_register_static` feature **and** `BEVY_REFLECT_AUTO_REGISTER_STATIC=1` env variable.
866/// Enabling the feature generates registration functions while setting the variable enables export and
867/// caching of registration function names.
868/// 3. Must be called before creating `App` or using `TypeRegistry::register_derived_types`.
869///
870/// If you're experiencing linking issues try running `cargo clean` before rebuilding.
871#[proc_macro]
872pub fn load_type_registrations(_input: TokenStream) -> TokenStream {
873 if !cfg!(feature = "auto_register_static") {
874 return TokenStream::new();
875 }
876
877 let Ok(dir) = fs::read_dir(PathBuf::from("target").join("bevy_reflect_type_registrations"))
878 else {
879 return TokenStream::new();
880 };
881 let mut str_buf = String::new();
882 let mut registration_fns = Vec::new();
883 for file_path in dir {
884 let mut file = fs::OpenOptions::new()
885 .read(true)
886 .open(file_path.unwrap().path())
887 .unwrap();
888 file.read_to_string(&mut str_buf).unwrap();
889 registration_fns.extend(str_buf.lines().filter(|s| !s.is_empty()).map(|s| {
890 s.parse::<proc_macro2::TokenStream>()
891 .expect("Unexpected function name")
892 }));
893 str_buf.clear();
894 }
895 let bevy_reflect_path = meta::get_bevy_reflect_path();
896 TokenStream::from(quote! {
897 {
898 fn _register_types(){
899 unsafe extern "Rust" {
900 #( safe fn #registration_fns(registry_ptr: &mut #bevy_reflect_path::TypeRegistry); )*
901 };
902 #( #bevy_reflect_path::__macro_exports::auto_register::push_registration_fn(#registration_fns); )*
903 }
904 _register_types();
905 }
906 })
907}