Fine tune codegen for global exports.

This commit is contained in:
Stephen Chung 2020-11-17 14:29:28 +08:00
parent bd094d95b4
commit 863c6b45a5
5 changed files with 23 additions and 18 deletions

View File

@ -15,7 +15,7 @@ New features
* `Engine::register_module` to register a module as a sub-module in the global namespace.
* `Module::get_fn_namespace` and `Module::set_fn_namespace` can expose a module function to the global namespace. This is convenient when registering an API for a custom type.
* `set_exported_global_fn!` macro to register a plugin function and expose it to the global namespace.
* `#[rhai_fn(gobal)]` and `#[rhai_fn(internal)]` attributes to determine whether a function defined in a plugin module should be exposed to the global namespace. This is convenient when defining an API for a custom type.
* `#[rhai_fn(global)]` and `#[rhai_fn(internal)]` attributes to determine whether a function defined in a plugin module should be exposed to the global namespace. This is convenient when defining an API for a custom type.
Enhancements
------------

View File

@ -215,14 +215,18 @@ impl ExportedParams for ExportedFnParams {
return Err(syn::Error::new(s.span(), "extraneous value"))
}
("global", None) => {
if namespace.is_some() {
return Err(syn::Error::new(key.span(), "conflicting namespace"));
if let Some(ns) = namespace {
if ns != FnNamespaceAccess::Global {
return Err(syn::Error::new(key.span(), "conflicting namespace"));
}
}
namespace = Some(FnNamespaceAccess::Global);
}
("internal", None) => {
if namespace.is_some() {
return Err(syn::Error::new(key.span(), "conflicting namespace"));
if let Some(ns) = namespace {
if ns != FnNamespaceAccess::Internal {
return Err(syn::Error::new(key.span(), "conflicting namespace"));
}
}
namespace = Some(FnNamespaceAccess::Internal);
}

View File

@ -129,17 +129,18 @@ pub(crate) fn generate_body(
}
for fn_literal in reg_names {
set_fn_stmts.push(
let ns_str = syn::Ident::new(
match namespace {
FnNamespaceAccess::Global => syn::parse2::<syn::Stmt>(quote! {
m.set_fn(#fn_literal, FnNamespace::Global, FnAccess::Public, &[#(#fn_input_types),*],
#fn_token_name().into());
}),
FnNamespaceAccess::Internal => syn::parse2::<syn::Stmt>(quote! {
m.set_fn(#fn_literal, FnNamespace::Internal, FnAccess::Public, &[#(#fn_input_types),*],
#fn_token_name().into());
}),
}
FnNamespaceAccess::Global => "Global",
FnNamespaceAccess::Internal => "Internal",
},
fn_literal.span(),
);
set_fn_stmts.push(
syn::parse2::<syn::Stmt>(quote! {
m.set_fn(#fn_literal, FnNamespace::#ns_str, FnAccess::Public, &[#(#fn_input_types),*],
#fn_token_name().into());
})
.unwrap(),
);
}

View File

@ -9,7 +9,7 @@ pub struct Point {
#[export_module]
pub mod test_module {
pub use super::Point;
#[rhai_fn(global, global)]
#[rhai_fn(global, internal)]
pub fn test_fn(input: Point) -> bool {
input.x > input.y
}

View File

@ -1,8 +1,8 @@
error: conflicting namespace
--> $DIR/rhai_fn_global_multiple.rs:12:23
|
12 | #[rhai_fn(global, global)]
| ^^^^^^
12 | #[rhai_fn(global, internal)]
| ^^^^^^^^
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
--> $DIR/rhai_fn_global_multiple.rs:23:8