use quote::format_ident;
use syn::{parse_quote, Fields, ImplItem, ItemImpl};
use crate::utils::add_field;
use super::parsers::{BaseFnProps, BaseImplProps};
pub fn add_main_fields(main_fields: &mut Fields, impl_bases_inner: &[BaseImplProps], vtable: bool) {
if !impl_bases_inner.is_empty() {
for BaseImplProps {
base_name,
base_field_name,
..
} in impl_bases_inner.iter().rev()
{
add_field(main_fields, base_field_name, base_name);
}
} else if vtable {
add_field(main_fields, &format_ident!("vtbl"), &format_ident!("usize"));
}
}
pub fn add_layout_fields(layout_fields: &mut Fields, impl_bases_inner: &[BaseImplProps]) {
if let Some(BaseImplProps { fns, .. }) = impl_bases_inner.first() {
let Fields::Named(fields) = layout_fields else {
panic!("expected named fields");
};
for BaseFnProps {
fn_name,
inputs_inner,
output,
virt,
..
} in fns.iter().rev()
{
if !virt {
continue;
}
fields.named.insert(
0,
parse_quote! {
#fn_name: fn(#inputs_inner) #output
},
);
}
}
}
pub fn move_impls_to_main(impl_inner: &mut ItemImpl, impl_bases_inner: &[BaseImplProps]) {
for BaseFnProps { fun, .. } in impl_bases_inner
.iter()
.flat_map(|BaseImplProps { fns, .. }| fns)
.rev()
{
impl_inner.items.insert(0, ImplItem::Fn(fun.clone()));
}
}