diff --git a/crates/luaffi_impl/src/cdef.rs b/crates/luaffi_impl/src/cdef.rs index a7be0ec..4d36022 100644 --- a/crates/luaffi_impl/src/cdef.rs +++ b/crates/luaffi_impl/src/cdef.rs @@ -24,7 +24,7 @@ pub fn transform(_args: Args, mut item: Item) -> Result { let mod_name = format_ident!("__{name}_cdef"); - Ok(quote!( + Ok(quote_spanned!(name.span() => #[repr(C)] #[allow(non_camel_case_types)] #item diff --git a/crates/luaffi_impl/src/metatype.rs b/crates/luaffi_impl/src/metatype.rs index 760ac06..104c9f8 100644 --- a/crates/luaffi_impl/src/metatype.rs +++ b/crates/luaffi_impl/src/metatype.rs @@ -16,7 +16,7 @@ pub fn transform(mut imp: ItemImpl) -> Result { let impls = generate_impls(&mut imp)?; let mod_name = format_ident!("__{}_metatype", ty_name(&imp.self_ty)?); - Ok(quote!( + Ok(quote_spanned!(imp.self_ty.span() => #imp #[doc(hidden)] @@ -77,7 +77,7 @@ fn generate_impls(imp: &mut ItemImpl) -> Result { let lua_build = &lua_funcs.build; let ffi_exports = generate_ffi_exports(&ffi_funcs)?; - Ok(quote! { + Ok(quote_spanned!(ty.span() => impl #ty { #(#ffi_shims)* } unsafe impl #ffi::Metatype for #ty { @@ -90,7 +90,7 @@ fn generate_impls(imp: &mut ItemImpl) -> Result { } #ffi_exports - }) + )) } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -224,6 +224,8 @@ fn get_ffi_functions(imp: &mut ItemImpl) -> Result> { let attrs = parse_ffi_function_attrs(&mut func.attrs)?; attrs.metamethod.map(|mm| document_metamethod(func, mm)); + document_ffi_function(func); + funcs.push(FfiFunction { name: func.sig.ident.clone(), is_async: func.sig.asyncness.is_some(), @@ -392,8 +394,12 @@ fn add_ffi_function(registry: &mut FfiRegistry, func: &FfiFunction) -> Result<() <#func_ret as #ffi::IntoFfi>::convention() == #ffi::FfiReturnConvention::ByOutParam )); - shim_params.insert(0, quote!(out: *mut #shim_ret)); - (shim_body, shim_ret) = (quote!(::std::ptr::write(out, #shim_body)), quote!(())); + shim_params.insert(0, quote_spanned!(func_ret.span() => out: *mut #shim_ret)); + + (shim_body, shim_ret) = ( + quote_spanned!(func_ret.span() => ::std::ptr::write(out, #shim_body)), + quote_spanned!(func_ret.span() => ()), + ); } }; } @@ -417,13 +423,17 @@ fn add_ffi_function(registry: &mut FfiRegistry, func: &FfiFunction) -> Result<() )); registry.build.push(match func.attrs.metamethod { - Some(ref mm) => quote!(b.metatable(#mm, |b| { #(#build)* });), - None => quote!(b.index(#lua_name, |b| { #(#build)* });), + Some(ref mm) => quote_spanned!(func_name.span() => + b.metatable(#mm, |b| { #(#build)* }); + ), + None => quote_spanned!(func_name.span() => + b.index(#lua_name, |b| { #(#build)* }); + ), }); registry.shims.push(parse_quote_spanned!(func_name.span() => #[unsafe(export_name = #c_name)] - unsafe extern "C" fn #shim_name(#(#shim_params),*) -> #shim_ret { #shim_body } + unsafe extern "C" fn #shim_name(#(#shim_params),*) -> #shim_ret { unsafe { #shim_body } } )); Ok(()) @@ -485,6 +495,8 @@ fn get_lua_functions(imp: &mut ItemImpl) -> Result> { let attrs = parse_lua_function_attrs(&mut func.attrs)?; attrs.metamethod.map(|mm| document_metamethod(func, mm)); + document_lua_function(func); + funcs.push(LuaFunction { name: func.sig.ident.clone(), params, @@ -506,9 +518,10 @@ fn stub_lua_function(func: &mut ImplItemFn) -> Result<()> { // documentation generation func.sig.abi = None; func.attrs.push(parse_quote!(#[allow(unused)])); - func.block = parse_quote!({ + func.block.stmts.clear(); + func.block.stmts.push(parse_quote!( ::std::unreachable!("cannot call lua function from rust"); - }); + )); let inputs = &mut func.sig.inputs; let output = &mut func.sig.output; @@ -598,48 +611,23 @@ impl LuaRegistry { fn add_lua_function(registry: &mut LuaRegistry, func: &LuaFunction) -> Result<()> { let ffi = ffi_crate(); let luaify = quote!(#ffi::__internal::luaify!); - let name = func.name.unraw().to_string(); + let func_name = &func.name; let params = &func.params; let body = &func.body; + let name = func_name.unraw().to_string(); registry.build.push(match func.attrs.metamethod { - Some(ref mm) => quote!(b.metatable_raw(#mm, #luaify(|#(#params),*| #body));), - None => quote!(b.index_raw(#name, #luaify(|#(#params),*| #body));), + Some(ref mm) => quote_spanned!(func_name.span() => + b.metatable_raw(#mm, #luaify(|#(#params),*| #body)); + ), + None => quote_spanned!(func_name.span() => + b.index_raw(#name, #luaify(|#(#params),*| #body)); + ), }); Ok(()) } -fn document_metamethod(func: &mut ImplItemFn, method: Metamethod) { - let s = match method { - Metamethod::Eq => "This is a metamethod which is called by the `==` operator.".into(), - Metamethod::Len => "This is a metamethod which is called by the `#` operator.".into(), - Metamethod::Lt => "This is a metamethod which is called by the `<` operator.".into(), - Metamethod::Le => "This is a metamethod which is called by the `<=` operator.".into(), - Metamethod::Concat => "This is a metamethod which is called by the `..` operator.".into(), - Metamethod::Add => "This is a metamethod which is called by the `+` operator.".into(), - Metamethod::Sub => "This is a metamethod which is called by the `-` operator.".into(), - Metamethod::Mul => "This is a metamethod which is called by the `*` operator.".into(), - Metamethod::Div => "This is a metamethod which is called by the `/` operator.".into(), - Metamethod::Mod => "This is a metamethod which is called by the `%` operator.".into(), - Metamethod::Pow => "This is a metamethod which is called by the `^` operator.".into(), - Metamethod::Unm => "This is a metamethod which is called by the `-` operator.".into(), - Metamethod::ToString => { - "This is a metamethod which can be called by the `tostring` built-in function.".into() - } - Metamethod::Pairs => { - "This is a metamethod which can be called by the `pairs` built-in function.".into() - } - Metamethod::Ipairs => { - "This is a metamethod which can be called by the `ipairs` built-in function.".into() - } - _ => format!("This is a metamethod and cannot be called directly."), - }; - - func.attrs.push(parse_quote!(#[doc = ""])); - func.attrs.push(parse_quote!(#[doc = #s])); -} - fn inject_fallback_new(registry: &mut LuaRegistry) -> Result<()> { let ty = ®istry.ty; let lua = format!( @@ -711,3 +699,45 @@ fn inject_merged_drop(registry: &mut FfiRegistry, lua: Option<&LuaFunction>) -> Ok(()) } + +fn document_ffi_function(func: &mut ImplItemFn) { + func.attrs.insert(0, parse_quote!(#[doc = + r#"FFI"# + ])); +} + +fn document_lua_function(func: &mut ImplItemFn) { + func.attrs.insert(0, parse_quote!(#[doc = + r#"Lua"# + ])); +} + +fn document_metamethod(func: &mut ImplItemFn, method: Metamethod) { + let s = match method { + Metamethod::Eq => "This is a metamethod which is called by the `==` operator.".into(), + Metamethod::Len => "This is a metamethod which is called by the `#` operator.".into(), + Metamethod::Lt => "This is a metamethod which is called by the `<` operator.".into(), + Metamethod::Le => "This is a metamethod which is called by the `<=` operator.".into(), + Metamethod::Concat => "This is a metamethod which is called by the `..` operator.".into(), + Metamethod::Add => "This is a metamethod which is called by the `+` operator.".into(), + Metamethod::Sub => "This is a metamethod which is called by the `-` operator.".into(), + Metamethod::Mul => "This is a metamethod which is called by the `*` operator.".into(), + Metamethod::Div => "This is a metamethod which is called by the `/` operator.".into(), + Metamethod::Mod => "This is a metamethod which is called by the `%` operator.".into(), + Metamethod::Pow => "This is a metamethod which is called by the `^` operator.".into(), + Metamethod::Unm => "This is a metamethod which is called by the `-` operator.".into(), + Metamethod::ToString => { + "This is a metamethod which can be called by the `tostring` built-in function.".into() + } + Metamethod::Pairs => { + "This is a metamethod which can be called by the `pairs` built-in function.".into() + } + Metamethod::Ipairs => { + "This is a metamethod which can be called by the `ipairs` built-in function.".into() + } + _ => format!("This is a metamethod and cannot be called directly."), + }; + + func.attrs.push(parse_quote!(#[doc = ""])); + func.attrs.push(parse_quote!(#[doc = #s])); +}