reflect: Fix weird panics for rust-analyzer

Not sure why they were happening. These panics didn't happen on CI and my machine when building and running the tests.
This commit is contained in:
SeanOMik 2024-01-08 20:25:20 -05:00
parent 29467faf55
commit eb44aba3dc
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
3 changed files with 33 additions and 31 deletions

View File

@ -113,7 +113,7 @@ fn gen_variant_if(enum_id: &proc_macro2::Ident, variant: &Variant, if_body: proc
fn gen_if_field_names(variant: &Variant) -> proc_macro2::TokenStream { fn gen_if_field_names(variant: &Variant) -> proc_macro2::TokenStream {
let field_ifs = variant.fields.iter().map(|field| { let field_ifs = variant.fields.iter().map(|field| {
let id = field.ident.as_ref().unwrap(); let id = field.ident.as_ref().unwrap();
let id_str = id.span().source_text().unwrap(); let id_str = id.to_string();
quote! { quote! {
if name == #id_str { if name == #id_str {
@ -140,7 +140,7 @@ fn gen_match_names(variant: &Variant) -> proc_macro2::TokenStream {
let field_name_strs = variant.fields.iter().map(|field| { let field_name_strs = variant.fields.iter().map(|field| {
let id = field.ident.as_ref() let id = field.ident.as_ref()
.expect("Could not find identifier for enum field!"); .expect("Could not find identifier for enum field!");
id.span().source_text().unwrap() id.to_string()
}); });
quote! { quote! {
@ -292,7 +292,6 @@ fn gen_enum_if_stmts(enum_id: &proc_macro2::Ident, data: &DataEnum, by_index: bo
_ => quote! { }, _ => quote! { },
} }
}); });
println!("====");
quote! { quote! {
#( #struct_vars )* #( #struct_vars )*
@ -458,41 +457,35 @@ fn gen_enum_variant_type(enum_id: &proc_macro2::Ident, data: &DataEnum) -> proc_
/// Create a reflect implementation for an enum /// Create a reflect implementation for an enum
pub fn derive_reflect_enum(input: &DeriveInput, data_enum: &DataEnum) -> proc_macro2::TokenStream { pub fn derive_reflect_enum(input: &DeriveInput, data_enum: &DataEnum) -> proc_macro2::TokenStream {
let type_path = &input.ident; let input_ident = &input.ident;
let name = type_path.span().source_text().unwrap(); let ident_str = input.ident.to_string();
//println!("Got type path: {}", type_path);
let variant_count = data_enum.variants.len(); let variant_count = data_enum.variants.len();
/* let mut variants_iter = data_enum.variants.iter(); let field_ifs = gen_enum_if_stmts(input_ident, data_enum, false);
let field_mut_ifs = gen_enum_if_stmts(input_ident, data_enum, false);
let variant = variants_iter.next().unwrap(); let field_at_ifs = gen_enum_if_stmts(input_ident, data_enum, true);
let variant_name = &variant.ident; */ let field_at_mut_ifs = gen_enum_if_stmts(input_ident, data_enum, true);
let field_ifs = gen_enum_if_stmts(type_path, data_enum, false); let has_field = gen_enum_has_field(input_ident, data_enum);
let field_mut_ifs = gen_enum_if_stmts(type_path, data_enum, false); let field_len = gen_enum_fields_len(input_ident, data_enum);
let field_name_at = gen_enum_field_name_at(input_ident, data_enum);
let field_at_ifs = gen_enum_if_stmts(type_path, data_enum, true); let variant_name_match = gen_enum_variant_name(input_ident, data_enum, false);
let field_at_mut_ifs = gen_enum_if_stmts(type_path, data_enum, true); let variant_idx_match = gen_enum_variant_name(input_ident, data_enum, true);
let variant_type = gen_enum_variant_type(input_ident, data_enum);
let has_field = gen_enum_has_field(type_path, data_enum);
let field_len = gen_enum_fields_len(type_path, data_enum);
let field_name_at = gen_enum_field_name_at(type_path, data_enum);
let variant_name_match = gen_enum_variant_name(type_path, data_enum, false);
let variant_idx_match = gen_enum_variant_name(type_path, data_enum, true);
let variant_type = gen_enum_variant_type(type_path, data_enum);
let generics = add_trait_bounds(input.generics.clone(), vec![parse_quote!(Reflect), parse_quote!(Clone)]); let generics = add_trait_bounds(input.generics.clone(), vec![parse_quote!(Reflect), parse_quote!(Clone)]);
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
return proc_macro2::TokenStream::from(quote! { return proc_macro2::TokenStream::from(quote! {
impl #impl_generics lyra_engine::reflect::Reflect for #type_path #ty_generics #where_clause { impl #impl_generics lyra_engine::reflect::Reflect for #input_ident #ty_generics #where_clause {
fn name(&self) -> ::std::string::String { fn name(&self) -> ::std::string::String {
#name.to_string() #ident_str.to_string()
} }
fn type_id(&self) -> std::any::TypeId { fn type_id(&self) -> std::any::TypeId {
std::any::TypeId::of::<#type_path #ty_generics>() std::any::TypeId::of::<#input_ident #ty_generics>()
} }
fn as_any(&self) -> &dyn std::any::Any { fn as_any(&self) -> &dyn std::any::Any {
@ -530,7 +523,7 @@ pub fn derive_reflect_enum(input: &DeriveInput, data_enum: &DataEnum) -> proc_ma
} }
} }
impl #impl_generics lyra_engine::reflect::Enum for #type_path #ty_generics #where_clause { impl #impl_generics lyra_engine::reflect::Enum for #input_ident #ty_generics #where_clause {
fn field(&self, name: &str) -> Option<&dyn lyra_engine::reflect::Reflect> { fn field(&self, name: &str) -> Option<&dyn lyra_engine::reflect::Reflect> {
let name = name.to_lowercase(); let name = name.to_lowercase();
let name = name.as_str(); let name = name.as_str();

View File

@ -1,4 +1,5 @@
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::Ident;
use quote::{quote, ToTokens}; use quote::{quote, ToTokens};
use syn::{Generics, Path, Attribute, GenericParam, parse_macro_input, DeriveInput, TypeParamBound}; use syn::{Generics, Path, Attribute, GenericParam, parse_macro_input, DeriveInput, TypeParamBound};
@ -12,6 +13,7 @@ use struct_derive::*;
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) struct ReflectDef { pub(crate) struct ReflectDef {
//pub ident: Ident,
pub type_path: Path, pub type_path: Path,
pub generics: Generics, pub generics: Generics,
pub attributes: Vec<Attribute> pub attributes: Vec<Attribute>
@ -21,10 +23,12 @@ impl syn::parse::Parse for ReflectDef {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> { fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let attributes = input.call(Attribute::parse_outer)?; let attributes = input.call(Attribute::parse_outer)?;
let type_path = Path::parse_mod_style(input)?; let type_path = Path::parse_mod_style(input)?;
//let ident = type_path. //type_path.require_ident()?;
let mut generics = input.parse::<Generics>()?; let mut generics = input.parse::<Generics>()?;
generics.where_clause = input.parse()?; generics.where_clause = input.parse()?;
Ok(Self { Ok(Self {
//ident: ident.clone(),
type_path, type_path,
generics, generics,
attributes, attributes,
@ -56,17 +60,21 @@ pub fn derive_reflect(input: proc_macro::TokenStream) -> proc_macro::TokenStream
pub fn impl_reflect_trait_value(input: TokenStream) -> TokenStream { pub fn impl_reflect_trait_value(input: TokenStream) -> TokenStream {
let reflect = syn::parse_macro_input!(input as ReflectDef); let reflect = syn::parse_macro_input!(input as ReflectDef);
let type_path = reflect.type_path.clone().into_token_stream(); let type_path = reflect.type_path;
// convert the type path to a string. This would not create a leading separator
let name_id = &reflect.type_path.segments.last().unwrap().ident; let type_path_str = {
let name = name_id.span().source_text().unwrap(); let idents: Vec<String> = type_path.segments.iter()
.map(|segment| segment.ident.to_string())
.collect();
idents.join("::")
};
let (impl_generics, ty_generics, where_clause) = reflect.generics.split_for_impl(); let (impl_generics, ty_generics, where_clause) = reflect.generics.split_for_impl();
TokenStream::from(quote! { TokenStream::from(quote! {
impl #impl_generics lyra_engine::reflect::Reflect for #type_path #ty_generics #where_clause { impl #impl_generics lyra_engine::reflect::Reflect for #type_path #ty_generics #where_clause {
fn name(&self) -> ::std::string::String { fn name(&self) -> ::std::string::String {
#name.to_string() #type_path_str.to_string()
} }
fn type_id(&self) -> std::any::TypeId { fn type_id(&self) -> std::any::TypeId {

View File

@ -266,7 +266,8 @@ fn gen_struct_field_name_idx(data: &DataStruct) -> proc_macro2::TokenStream {
/// Generates a token stream that implements Reflect and Struct for the provided struct /// Generates a token stream that implements Reflect and Struct for the provided struct
pub fn derive_reflect_struct(input: &DeriveInput, data_struct: &DataStruct) -> proc_macro2::TokenStream { pub fn derive_reflect_struct(input: &DeriveInput, data_struct: &DataStruct) -> proc_macro2::TokenStream {
let type_path = &input.ident; let type_path = &input.ident;
let name = type_path.span().source_text().unwrap(); let name = type_path.to_string();
//let name = type_path.span().source_text().unwrap();
let field_len = data_struct.fields.len(); let field_len = data_struct.fields.len();
let get_field_match = gen_struct_field_match(data_struct, false); let get_field_match = gen_struct_field_match(data_struct, false);