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