summaryrefslogtreecommitdiff
path: root/engine-macros
diff options
context:
space:
mode:
Diffstat (limited to 'engine-macros')
-rw-r--r--engine-macros/src/reflection/enum_impl.rs129
-rw-r--r--engine-macros/src/reflection/struct_impl.rs21
-rw-r--r--engine-macros/src/util.rs24
3 files changed, 114 insertions, 60 deletions
diff --git a/engine-macros/src/reflection/enum_impl.rs b/engine-macros/src/reflection/enum_impl.rs
index 1760f40..a01ed8b 100644
--- a/engine-macros/src/reflection/enum_impl.rs
+++ b/engine-macros/src/reflection/enum_impl.rs
@@ -1,7 +1,7 @@
use quote::{format_ident, quote, ToTokens};
use crate::reflection::field::{generate as generate_field, ReflectionFieldGenOptions};
-use crate::util::find_engine_crate_path;
+use crate::util::{find_engine_crate_path, syn_path, SynPathExt};
const PRIMITIVE_REPRS: &[&'static str] = &[
"u8", "u16", "u32", "u64", "u128", "usize", "i8", "i16", "i32", "i64", "i128",
@@ -14,7 +14,20 @@ pub fn generate(input: syn::ItemEnum) -> proc_macro2::TokenStream
let input_ident = &input.ident;
- let (impl_generics, type_generics, where_clause) = input.generics.split_for_impl();
+ let mut generics = input.generics;
+
+ for type_param in generics.type_params_mut() {
+ type_param
+ .bounds
+ .push(syn::TypeParamBound::Trait(syn::TraitBound {
+ paren_token: None,
+ modifier: syn::TraitBoundModifier::None,
+ lifetimes: None,
+ path: engine_crate_path.join(syn_path!(reflection::Reflection)),
+ }));
+ }
+
+ let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
let variant_lookup_match_arms =
input.variants.iter().enumerate().map(|(index, variant)| {
@@ -80,22 +93,22 @@ pub fn generate(input: syn::ItemEnum) -> proc_macro2::TokenStream
let mod_content = if is_unit_only {
quote! {}
} else {
- let variant_fields_structs = input.variants.iter().map(|variant| {
- let fields = variant.fields.iter().map(|field| {
- let field_type = &field.ty;
-
- if let Some(field_ident) = &field.ident {
- quote! { pub #field_ident: #field_type }
- } else {
- quote! { pub #field_type }
- }
- });
+ let variant_fields_structs =
+ input.variants.iter().map(|variant| {
+ let fields = variant.fields.iter().map(|field| {
+ let field_type = &field.ty;
+
+ if let Some(field_ident) = &field.ident {
+ quote! { pub #field_ident: #field_type }
+ } else {
+ quote! { pub #field_type }
+ }
+ });
- let ident = format_ident!("VariantFields{}", variant.ident);
+ let ident = format_ident!("VariantFields{}", variant.ident);
- let generics_phantom_data_elems =
- input.generics.params.iter().filter_map(|generic_param| {
- match generic_param {
+ let generics_phantom_data_elems = generics.params.iter().filter_map(
+ |generic_param| match generic_param {
syn::GenericParam::Type(type_param) => {
Some(type_param.ident.clone().into_token_stream())
}
@@ -103,38 +116,38 @@ pub fn generate(input: syn::ItemEnum) -> proc_macro2::TokenStream
unimplemented!();
}
syn::GenericParam::Const(_const_param) => None,
- }
- });
+ },
+ );
- let generics_phantom_data = quote! {
- std::marker::PhantomData<(#(#generics_phantom_data_elems),*)>
- };
+ let generics_phantom_data = quote! {
+ std::marker::PhantomData<(#(#generics_phantom_data_elems),*)>
+ };
- match variant.fields {
- syn::Fields::Named(_) => quote! {
- #[repr(C)]
- pub struct #ident #impl_generics
- #where_clause
- {
- #(#fields,)*
- _pd: #generics_phantom_data
- }
- },
- syn::Fields::Unnamed(_) => quote! {
- #[repr(C)]
- pub struct #ident #impl_generics (
- #(#fields,)*
- #generics_phantom_data
- )
- #where_clause;
- },
- syn::Fields::Unit => quote! {
- #[repr(C)]
- pub struct #ident #impl_generics (#generics_phantom_data)
- #where_clause;
- },
- }
- });
+ match variant.fields {
+ syn::Fields::Named(_) => quote! {
+ #[repr(C)]
+ pub struct #ident #impl_generics
+ #where_clause
+ {
+ #(#fields,)*
+ _pd: #generics_phantom_data
+ }
+ },
+ syn::Fields::Unnamed(_) => quote! {
+ #[repr(C)]
+ pub struct #ident #impl_generics (
+ #(#fields,)*
+ #generics_phantom_data
+ )
+ #where_clause;
+ },
+ syn::Fields::Unit => quote! {
+ #[repr(C)]
+ pub struct #ident #impl_generics (#generics_phantom_data)
+ #where_clause;
+ },
+ }
+ });
let fields_union_fields = input.variants.iter().map(|variant| {
let variant_ident = &variant.ident;
@@ -197,7 +210,13 @@ pub fn generate(input: syn::ItemEnum) -> proc_macro2::TokenStream
}
};
- let variants = generate_variants(&input, is_unit_only, &engine_crate_path);
+ let variants = generate_variants(
+ input_ident,
+ &input.variants,
+ &generics,
+ is_unit_only,
+ &engine_crate_path,
+ );
quote! {
#[doc(hidden)]
@@ -240,16 +259,18 @@ pub fn generate(input: syn::ItemEnum) -> proc_macro2::TokenStream
}
fn generate_variants<'a>(
- input: &'a syn::ItemEnum,
+ input_ident: &proc_macro2::Ident,
+ input_variants: &'a syn::punctuated::Punctuated<syn::Variant, syn::Token![,]>,
+ input_generics: &'a syn::Generics,
is_unit_only: bool,
engine_crate_path: &'a syn::Path,
) -> impl Iterator<Item = proc_macro2::TokenStream> + use<'a>
{
- let mod_name = format_ident!("__engine_private_{}", input.ident);
+ let mod_name = format_ident!("__engine_private_{input_ident}");
- let (_, type_generics, _) = input.generics.split_for_impl();
+ let (_, type_generics, _) = input_generics.split_for_impl();
- input.variants.iter().map(move |variant| {
+ input_variants.iter().map(move |variant| {
let variant_name =
syn::LitStr::new(&variant.ident.to_string(), variant.ident.span());
@@ -288,8 +309,7 @@ fn generate_variants<'a>(
unreachable!();
}
},
- type_reflection_optional: input
- .generics
+ type_reflection_optional: input_generics
.params
.is_empty(),
},
@@ -337,8 +357,7 @@ fn generate_variants<'a>(
}
}
},
- type_reflection_optional: input
- .generics
+ type_reflection_optional: input_generics
.params
.is_empty(),
},
diff --git a/engine-macros/src/reflection/struct_impl.rs b/engine-macros/src/reflection/struct_impl.rs
index 2a271e0..b1adea5 100644
--- a/engine-macros/src/reflection/struct_impl.rs
+++ b/engine-macros/src/reflection/struct_impl.rs
@@ -1,7 +1,7 @@
use quote::quote;
use crate::reflection::field::{generate as generate_field, ReflectionFieldGenOptions};
-use crate::util::find_engine_crate_path;
+use crate::util::{find_engine_crate_path, syn_path, SynPathExt};
pub fn generate(input: syn::ItemStruct) -> proc_macro2::TokenStream
{
@@ -9,7 +9,22 @@ pub fn generate(input: syn::ItemStruct) -> proc_macro2::TokenStream
let input_ident = input.ident;
- let (impl_generics, type_generics, where_clause) = input.generics.split_for_impl();
+ let type_reflection_optional = input.generics.params.is_empty();
+
+ let mut generics = input.generics;
+
+ for type_param in generics.type_params_mut() {
+ type_param
+ .bounds
+ .push(syn::TypeParamBound::Trait(syn::TraitBound {
+ paren_token: None,
+ modifier: syn::TraitBoundModifier::None,
+ lifetimes: None,
+ path: engine_crate_path.join(syn_path!(reflection::Reflection)),
+ }));
+ }
+
+ let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
let fields = input
.fields
@@ -29,7 +44,7 @@ pub fn generate(input: syn::ItemStruct) -> proc_macro2::TokenStream
quote! { std::mem::offset_of!(Self, #field_index) }
}
},
- type_reflection_optional: input.generics.params.is_empty(),
+ type_reflection_optional,
},
)
});
diff --git a/engine-macros/src/util.rs b/engine-macros/src/util.rs
index 515b066..327c517 100644
--- a/engine-macros/src/util.rs
+++ b/engine-macros/src/util.rs
@@ -7,8 +7,8 @@ macro_rules! syn_path {
::syn::Path {
leading_colon: None,
segments: ::syn::punctuated::Punctuated::from_iter([
- syn_path_segment!($first_segment),
- $(syn_path_segment!($segment),)*
+ $crate::util::syn_path_segment!($first_segment),
+ $($crate::util::syn_path_segment!($segment),)*
])
}
};
@@ -26,6 +26,9 @@ macro_rules! syn_path_segment {
};
}
+pub(crate) use syn_path;
+pub(crate) use syn_path_segment;
+
pub fn find_engine_crate_path() -> Option<syn::Path>
{
let cargo_crate_name = std::env::var("CARGO_CRATE_NAME").ok()?;
@@ -63,3 +66,20 @@ pub fn syn_path_to_string(path: &syn::Path) -> String
output
}
+
+pub trait SynPathExt
+{
+ fn join(&self, tail: Self) -> Self;
+}
+
+impl SynPathExt for syn::Path
+{
+ fn join(&self, tail: Self) -> Self
+ {
+ let mut new = self.clone();
+
+ new.segments.extend(tail.segments);
+
+ new
+ }
+}