Fix macros breaking auto completion in IDEs
This commit is contained in:
parent
92072ef93f
commit
3e708a0c0d
|
@ -135,7 +135,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gmod"
|
name = "gmod"
|
||||||
version = "12.0.0"
|
version = "12.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg_table 1.0.0",
|
"cfg_table 1.0.0",
|
||||||
"cstr",
|
"cstr",
|
||||||
|
@ -144,7 +144,7 @@ dependencies = [
|
||||||
"fn_abi",
|
"fn_abi",
|
||||||
"fn_has_this",
|
"fn_has_this",
|
||||||
"fn_type_alias",
|
"fn_type_alias",
|
||||||
"gmod-macros 2.0.0",
|
"gmod-macros 2.0.1",
|
||||||
"gmserverplugin",
|
"gmserverplugin",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libloading",
|
"libloading",
|
||||||
|
@ -165,7 +165,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gmod-macros"
|
name = "gmod-macros"
|
||||||
version = "2.0.0"
|
version = "2.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "gmod-macros"
|
name = "gmod-macros"
|
||||||
version = "2.0.0"
|
version = "2.0.1"
|
||||||
authors = ["William Venner <william@venner.io>"]
|
authors = ["William Venner <william@venner.io>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
@ -8,6 +8,16 @@ use proc_macro::TokenStream;
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use syn::ItemFn;
|
use syn::ItemFn;
|
||||||
|
|
||||||
|
macro_rules! wrap_compile_error {
|
||||||
|
($input:ident, $code:expr) => {{
|
||||||
|
let orig_tokens = $input.clone();
|
||||||
|
match (|| -> Result<TokenStream, syn::Error> { $code })() {
|
||||||
|
Ok(tokens) => tokens,
|
||||||
|
Err(_) => return orig_tokens
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
fn check_lua_function(input: &mut ItemFn) {
|
fn check_lua_function(input: &mut ItemFn) {
|
||||||
assert!(input.sig.asyncness.is_none(), "Cannot be async");
|
assert!(input.sig.asyncness.is_none(), "Cannot be async");
|
||||||
assert!(input.sig.constness.is_none(), "Cannot be const");
|
assert!(input.sig.constness.is_none(), "Cannot be const");
|
||||||
|
@ -24,66 +34,72 @@ fn genericify_return(item_fn: &mut ItemFn) {
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn gmod13_open(_attr: TokenStream, tokens: TokenStream) -> TokenStream {
|
pub fn gmod13_open(_attr: TokenStream, tokens: TokenStream) -> TokenStream {
|
||||||
let mut input = parse_macro_input!(tokens as ItemFn);
|
wrap_compile_error!(tokens, {
|
||||||
|
let mut input = syn::parse::<ItemFn>(tokens)?;
|
||||||
|
|
||||||
let lua_ident = format_ident!("{}", match &input.sig.inputs[0] {
|
let lua_ident = format_ident!("{}", match &input.sig.inputs[0] {
|
||||||
syn::FnArg::Typed(arg) => arg.pat.to_token_stream().to_string(),
|
syn::FnArg::Typed(arg) => arg.pat.to_token_stream().to_string(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Capture the Lua state
|
// Capture the Lua state
|
||||||
input.block.stmts.insert(0, syn::parse2(quote!(::gmod::lua::__set_state__internal(#lua_ident);)).unwrap());
|
input.block.stmts.insert(0, syn::parse2(quote!(::gmod::lua::__set_state__internal(#lua_ident);)).unwrap());
|
||||||
|
|
||||||
// Load lua_shared
|
// Load lua_shared
|
||||||
input.block.stmts.insert(0, syn::parse2(quote!(#[allow(unused_unsafe)] unsafe { ::gmod::lua::load() })).unwrap());
|
input.block.stmts.insert(0, syn::parse2(quote!(#[allow(unused_unsafe)] unsafe { ::gmod::lua::load() })).unwrap());
|
||||||
|
|
||||||
// Make sure it's valid
|
// Make sure it's valid
|
||||||
check_lua_function(&mut input);
|
check_lua_function(&mut input);
|
||||||
|
|
||||||
// No mangling
|
// No mangling
|
||||||
input.attrs.push(parse_quote!(#[no_mangle]));
|
input.attrs.push(parse_quote!(#[no_mangle]));
|
||||||
|
|
||||||
// Make the return type nice and dynamic
|
// Make the return type nice and dynamic
|
||||||
genericify_return(&mut input);
|
genericify_return(&mut input);
|
||||||
|
|
||||||
input.into_token_stream().into()
|
Ok(input.into_token_stream().into())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn gmod13_close(_attr: TokenStream, tokens: TokenStream) -> TokenStream {
|
pub fn gmod13_close(_attr: TokenStream, tokens: TokenStream) -> TokenStream {
|
||||||
let mut input = parse_macro_input!(tokens as ItemFn);
|
wrap_compile_error!(tokens, {
|
||||||
|
let mut input = syn::parse::<ItemFn>(tokens)?;
|
||||||
|
|
||||||
// Make sure it's valid
|
// Make sure it's valid
|
||||||
check_lua_function(&mut input);
|
check_lua_function(&mut input);
|
||||||
|
|
||||||
// No mangling
|
// No mangling
|
||||||
input.attrs.push(parse_quote!(#[no_mangle]));
|
input.attrs.push(parse_quote!(#[no_mangle]));
|
||||||
|
|
||||||
// Shutdown gmcl thread if it's running
|
// Shutdown gmcl thread if it's running
|
||||||
#[cfg(feature = "gmcl")] {
|
#[cfg(feature = "gmcl")] {
|
||||||
let stmts = std::mem::take(&mut input.block.stmts);
|
let stmts = std::mem::take(&mut input.block.stmts);
|
||||||
input.block.stmts = vec![syn::parse2(quote!({
|
input.block.stmts = vec![syn::parse2(quote!({
|
||||||
let ret = (|| {#(#stmts);*})();
|
let ret = (|| {#(#stmts);*})();
|
||||||
::gmod::gmcl::restore_stdout();
|
::gmod::gmcl::restore_stdout();
|
||||||
ret
|
ret
|
||||||
})).unwrap()];
|
})).unwrap()];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the return type nice and dynamic
|
// Make the return type nice and dynamic
|
||||||
genericify_return(&mut input);
|
genericify_return(&mut input);
|
||||||
|
|
||||||
input.into_token_stream().into()
|
Ok(input.into_token_stream().into())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn lua_function(_attr: TokenStream, tokens: TokenStream) -> TokenStream {
|
pub fn lua_function(_attr: TokenStream, tokens: TokenStream) -> TokenStream {
|
||||||
let mut input = parse_macro_input!(tokens as ItemFn);
|
wrap_compile_error!(tokens, {
|
||||||
|
let mut input = syn::parse::<ItemFn>(tokens)?;
|
||||||
|
|
||||||
// Make sure it's valid
|
// Make sure it's valid
|
||||||
check_lua_function(&mut input);
|
check_lua_function(&mut input);
|
||||||
|
|
||||||
// Make the return type nice and dynamic
|
// Make the return type nice and dynamic
|
||||||
genericify_return(&mut input);
|
genericify_return(&mut input);
|
||||||
|
|
||||||
input.into_token_stream().into()
|
Ok(input.into_token_stream().into())
|
||||||
|
})
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "gmod"
|
name = "gmod"
|
||||||
version = "12.0.0"
|
version = "12.0.1"
|
||||||
authors = ["William Venner <william@venner.io>"]
|
authors = ["William Venner <william@venner.io>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
@ -16,7 +16,7 @@ server-plugin = ["gmserverplugin"]
|
||||||
gmcl = ["gmod-macros/gmcl"]
|
gmcl = ["gmod-macros/gmcl"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gmod-macros = { version = "2.0.0", path = "../gmod-macros" }
|
gmod-macros = { version = "2.0.1", path = "../gmod-macros" }
|
||||||
gmserverplugin = { version = "1", optional = true }
|
gmserverplugin = { version = "1", optional = true }
|
||||||
|
|
||||||
libloading = "0"
|
libloading = "0"
|
||||||
|
|
Loading…
Reference in New Issue