Unraw idents

This commit is contained in:
lumi 2025-06-23 07:18:16 +10:00
parent 884acd71e1
commit c3fb3407c4
Signed by: luaneko
GPG Key ID: 406809B8763FF07A
2 changed files with 39 additions and 27 deletions

View File

@ -2,7 +2,7 @@ use crate::utils::{ffi_crate, syn_assert, syn_error};
use darling::FromMeta;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use syn::*;
use syn::{ext::IdentExt, *};
#[derive(Debug, FromMeta)]
pub struct Args {}
@ -42,8 +42,8 @@ pub fn transform(_args: Args, mut item: Item) -> Result<TokenStream> {
fn generate_type(ty: &Ident) -> Result<TokenStream> {
let ffi = ffi_crate();
let fmt = quote!(::std::format!);
let name = LitStr::new(&format!("{ty}"), ty.span());
let cdecl_fmt = LitStr::new(&format!("struct {ty} {{}}"), ty.span());
let name = LitStr::new(&format!("{}", ty.unraw()), ty.span());
let cdecl_fmt = LitStr::new(&format!("struct {} {{}}", ty.unraw()), ty.span());
Ok(quote! {
unsafe impl #ffi::Type for #ty {
@ -79,8 +79,8 @@ fn generate_cdef_structure(str: &mut ItemStruct) -> Result<TokenStream> {
let build = generate_build_cdef(&to_cfields(&mut str.fields)?)?;
Ok(quote! {
unsafe impl #ffi::CDef for #ty {
fn build(b: &mut #ffi::CDefBuilder) { #build }
unsafe impl #ffi::Cdef for #ty {
fn build(b: &mut #ffi::CdefBuilder) { #build }
}
})
}
@ -104,8 +104,8 @@ fn generate_cdef_enum(enu: &mut ItemEnum) -> Result<TokenStream> {
.collect::<Result<Vec<_>>>()?;
Ok(quote! {
unsafe impl #ffi::CDef for #ty {
fn build(b: &mut #ffi::CDefBuilder) {
unsafe impl #ffi::Cdef for #ty {
fn build(b: &mut #ffi::CdefBuilder) {
b.field::<::std::ffi::c_int>("__tag").inner_union(|b| { #(#build)* });
}
}
@ -133,7 +133,7 @@ fn to_cfields(fields: &mut Fields) -> Result<Vec<CField>> {
.map(|(i, field)| {
Ok(CField {
name: match field.ident {
Some(ref name) => format!("{name}"),
Some(ref name) => format!("{}", name.unraw()),
None => format!("__{i}"),
},
ty: field.ty.clone(),

View File

@ -1,7 +1,7 @@
use crate::utils::{ffi_crate, is_primitive, is_unit, pat_ident, syn_assert, ty_name};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use syn::*;
use syn::{ext::IdentExt, *};
pub fn transform(mut imp: ItemImpl) -> Result<TokenStream> {
syn_assert!(
@ -44,12 +44,13 @@ fn generate_impls(imp: &mut ItemImpl) -> Result<TokenStream> {
.map(generate_ffi_register)
.collect::<Result<_>>()?;
let ffi_new_fallback = match ffi_funcs
let ffi_register_new = match ffi_funcs
.iter()
.find(|f| f.attrs.metatable.as_deref() == Some("new"))
{
Some(_) => None,
None => Some({
// fallback error constructor to prevent creating uninitialised ctypes
let err = format!(r#"function() error("type '{ty_name}' has no constructor"); end"#);
quote! { b.metatable_raw("new", #err); }
}),
@ -57,6 +58,19 @@ fn generate_impls(imp: &mut ItemImpl) -> Result<TokenStream> {
let ffi_drop_rname = format_ident!("__ffi_drop");
let ffi_drop_cname = format!("{ty_name}_drop");
let ffi_wrapper_drop = quote! {
#[unsafe(export_name = #ffi_drop_cname)]
unsafe extern "C" fn #ffi_drop_rname(ptr: *mut Self) {
unsafe { ::std::ptr::drop_in_place(ptr) }
}
};
let ffi_register_drop = quote! {
if ::std::mem::needs_drop::<Self>() {
b.declare::<unsafe extern "C" fn(*mut Self)>(#ffi_drop_cname);
b.metatable_raw("gc", ::std::format_args!("__C.{}", #ffi_drop_cname));
}
};
// ffi function symbol export code
let ffi_exports = {
@ -75,11 +89,7 @@ fn generate_impls(imp: &mut ItemImpl) -> Result<TokenStream> {
Ok(quote! {
impl #ty {
#(#ffi_wrappers)*
#[unsafe(export_name = #ffi_drop_cname)]
unsafe extern "C" fn #ffi_drop_rname(ptr: *mut Self) {
unsafe { ::std::ptr::drop_in_place(ptr) }
}
#ffi_wrapper_drop
}
unsafe impl #ffi::Metatype for #ty {
@ -89,10 +99,8 @@ fn generate_impls(imp: &mut ItemImpl) -> Result<TokenStream> {
#(#ffi_register)*
#(#lua_register)*
#ffi_new_fallback
b.declare::<unsafe extern "C" fn(*mut Self)>(#ffi_drop_cname);
b.metatable_raw("gc", ::std::format_args!("__C.{}", #ffi_drop_cname));
#ffi_register_new
#ffi_register_drop
}
}
@ -154,9 +162,9 @@ fn get_ffi_functions(imp: &mut ItemImpl) -> Result<Vec<FfiFunction>> {
funcs.push(FfiFunction {
name: func.sig.ident.clone(),
rust_name: format_ident!("__ffi_{}", func.sig.ident),
lua_name: format!("{}", func.sig.ident),
c_name: format!("{}_{}", ty_name(&imp.self_ty)?, func.sig.ident),
rust_name: format_ident!("__ffi_{}", func.sig.ident.unraw()),
lua_name: format!("{}", func.sig.ident.unraw()),
c_name: format!("{}_{}", ty_name(&imp.self_ty)?, func.sig.ident.unraw()),
params,
ret,
ret_by_out,
@ -311,7 +319,7 @@ fn generate_ffi_exports<'a>(
struct LuaFunction {
name: String,
params: Vec<PatType>,
params: Vec<Pat>,
body: Block,
}
@ -325,8 +333,8 @@ fn get_lua_functions(imp: &mut ItemImpl) -> Result<Vec<LuaFunction>> {
&& let Some(ref abi) = abi.name
&& abi.value() == "Lua"
{
// normalise inputs to PatType
let params = func
// normalise inputs to Pat
let mut params: Vec<_> = func
.sig
.inputs
.iter()
@ -337,11 +345,15 @@ fn get_lua_functions(imp: &mut ItemImpl) -> Result<Vec<LuaFunction>> {
syn_assert!(recv.mutability.is_none(), recv, "cannot be mut");
parse_quote! { self: cdata }
}
FnArg::Typed(ty) => ty.clone(),
FnArg::Typed(ty) => Pat::Type(ty.clone()),
})
})
.collect::<Result<_>>()?;
if let Some(_) = func.sig.variadic {
params.push(parse_quote!(variadic!()));
}
// shouldn't specify an output type
syn_assert!(
matches!(func.sig.output, ReturnType::Default),
@ -350,7 +362,7 @@ fn get_lua_functions(imp: &mut ItemImpl) -> Result<Vec<LuaFunction>> {
);
funcs.push(LuaFunction {
name: format!("{}", func.sig.ident),
name: format!("{}", func.sig.ident.unraw()),
body: func.block.clone(),
params,
});