Add Lua and FFI tags to documentation

This commit is contained in:
lumi 2025-06-25 15:46:17 +10:00
parent a07f62ecc5
commit af3dbe60cb
Signed by: luaneko
GPG Key ID: 406809B8763FF07A
2 changed files with 74 additions and 44 deletions

View File

@ -24,7 +24,7 @@ pub fn transform(_args: Args, mut item: Item) -> Result<TokenStream> {
let mod_name = format_ident!("__{name}_cdef");
Ok(quote!(
Ok(quote_spanned!(name.span() =>
#[repr(C)]
#[allow(non_camel_case_types)]
#item

View File

@ -16,7 +16,7 @@ pub fn transform(mut imp: ItemImpl) -> Result<TokenStream> {
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<TokenStream> {
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<TokenStream> {
}
#ffi_exports
})
))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -224,6 +224,8 @@ fn get_ffi_functions(imp: &mut ItemImpl) -> Result<Vec<FfiFunction>> {
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<Vec<LuaFunction>> {
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 = &registry.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#"<span class="stab" title="This is a C/FFI function." style="float: right; font-weight: 500; margin-left: 3px; padding-left: 5px; padding-right: 5px;">FFI</span>"#
]));
}
fn document_lua_function(func: &mut ImplItemFn) {
func.attrs.insert(0, parse_quote!(#[doc =
r#"<span class="stab" title="This is a Lua function." style="float: right; font-weight: 500; margin-left: 3px; padding-left: 5px; padding-right: 5px;">Lua</span>"#
]));
}
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]));
}