Improve proc macro hygiene

This commit is contained in:
J Henry Waugh 2020-08-02 19:27:19 -05:00
parent 5eed5fe6a3
commit 3136188801
19 changed files with 258 additions and 163 deletions

View File

@ -154,12 +154,40 @@ impl ExportedFn {
self.name().span(), self.name().span(),
); );
let impl_block = self.generate_impl("Token"); let impl_block = self.generate_impl("Token");
let callable_block = self.generate_callable("Token");
let input_types_block = self.generate_input_types("Token");
quote! { quote! {
#[allow(unused)] #[allow(unused)]
pub mod #name { pub mod #name {
use super::*; use super::*;
pub struct Token(); struct Token();
#impl_block #impl_block
#callable_block
#input_types_block
}
}
}
pub fn generate_callable(&self, on_type_name: &str) -> proc_macro2::TokenStream {
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
let callable_fn_name: syn::Ident = syn::Ident::new(
format!("{}__callable", on_type_name).as_str(),
self.name().span());
quote! {
pub fn #callable_fn_name() -> CallableFunction {
CallableFunction::from_plugin(#token_name())
}
}
}
pub fn generate_input_types(&self, on_type_name: &str) -> proc_macro2::TokenStream {
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
let input_types_fn_name: syn::Ident = syn::Ident::new(
format!("{}__input_types", on_type_name).as_str(),
self.name().span());
quote! {
pub fn #input_types_fn_name() -> Box<[std::any::TypeId]> {
#token_name().input_types()
} }
} }
} }
@ -232,7 +260,7 @@ impl ExportedFn {
is_str_ref = true; is_str_ref = true;
quote_spanned!(arg_type.span()=> quote_spanned!(arg_type.span()=>
args[#i] args[#i]
.downcast_clone::<rhai::ImmutableString>() .downcast_clone::<ImmutableString>()
.unwrap()) .unwrap())
} }
_ => panic!("internal error: why wasn't this found earlier!?"), _ => panic!("internal error: why wasn't this found earlier!?"),
@ -260,7 +288,7 @@ impl ExportedFn {
} else { } else {
input_type_exprs.push( input_type_exprs.push(
syn::parse2::<syn::Expr>(quote_spanned!( syn::parse2::<syn::Expr>(quote_spanned!(
arg_type.span()=> std::any::TypeId::of::<rhai::ImmutableString>() arg_type.span()=> std::any::TypeId::of::<ImmutableString>()
)) ))
.unwrap(), .unwrap(),
); );
@ -285,22 +313,22 @@ impl ExportedFn {
let type_name = syn::Ident::new(on_type_name, proc_macro2::Span::call_site()); let type_name = syn::Ident::new(on_type_name, proc_macro2::Span::call_site());
quote! { quote! {
impl rhai::plugin::PluginFunction for #type_name { impl PluginFunction for #type_name {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != #arg_count { if args.len() != #arg_count {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), #arg_count), rhai::Position::none()))); args.len(), #arg_count), Position::none())));
} }
#(#unpack_stmts)* #(#unpack_stmts)*
Ok(rhai::Dynamic::from(#name(#(#unpack_exprs),*))) Ok(Dynamic::from(#name(#(#unpack_exprs),*)))
} }
fn is_method_call(&self) -> bool { #is_method_call } fn is_method_call(&self) -> bool { #is_method_call }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { Box::new(#type_name()) } fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(#type_name()) }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![#(#input_type_exprs),*].into_boxed_slice() vec![#(#input_type_exprs),*].into_boxed_slice()
} }
@ -577,26 +605,32 @@ mod generate_tests {
#[allow(unused)] #[allow(unused)]
pub mod rhai_fn__do_nothing { pub mod rhai_fn__do_nothing {
use super::*; use super::*;
pub struct Token(); struct Token();
impl rhai::plugin::PluginFunction for Token { impl PluginFunction for Token {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 0usize { if args.len() != 0usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 0usize), rhai::Position::none()))); args.len(), 0usize), Position::none())));
} }
Ok(rhai::Dynamic::from(do_nothing())) Ok(Dynamic::from(do_nothing()))
} }
fn is_method_call(&self) -> bool { false } fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { Box::new(Token()) } fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![].into_boxed_slice() vec![].into_boxed_slice()
} }
} }
pub fn Token__callable() -> CallableFunction {
CallableFunction::from_plugin(Token())
}
pub fn Token__input_types() -> Box<[std::any::TypeId]> {
Token().input_types()
}
} }
}; };
@ -614,27 +648,33 @@ mod generate_tests {
#[allow(unused)] #[allow(unused)]
pub mod rhai_fn__do_something { pub mod rhai_fn__do_something {
use super::*; use super::*;
pub struct Token(); struct Token();
impl rhai::plugin::PluginFunction for Token { impl PluginFunction for Token {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 1usize { if args.len() != 1usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 1usize), rhai::Position::none()))); args.len(), 1usize), Position::none())));
} }
let arg0 = args[0usize].downcast_clone::<usize>().unwrap(); let arg0 = args[0usize].downcast_clone::<usize>().unwrap();
Ok(rhai::Dynamic::from(do_something(arg0))) Ok(Dynamic::from(do_something(arg0)))
} }
fn is_method_call(&self) -> bool { false } fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { Box::new(Token()) } fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![std::any::TypeId::of::<usize>()].into_boxed_slice() vec![std::any::TypeId::of::<usize>()].into_boxed_slice()
} }
} }
pub fn Token__callable() -> CallableFunction {
CallableFunction::from_plugin(Token())
}
pub fn Token__input_types() -> Box<[std::any::TypeId]> {
Token().input_types()
}
} }
}; };
@ -649,22 +689,22 @@ mod generate_tests {
}; };
let expected_tokens = quote! { let expected_tokens = quote! {
impl rhai::plugin::PluginFunction for MyType { impl PluginFunction for MyType {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 1usize { if args.len() != 1usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 1usize), rhai::Position::none()))); args.len(), 1usize), Position::none())));
} }
let arg0 = args[0usize].downcast_clone::<usize>().unwrap(); let arg0 = args[0usize].downcast_clone::<usize>().unwrap();
Ok(rhai::Dynamic::from(do_something(arg0))) Ok(Dynamic::from(do_something(arg0)))
} }
fn is_method_call(&self) -> bool { false } fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { Box::new(MyType()) } fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(MyType()) }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![std::any::TypeId::of::<usize>()].into_boxed_slice() vec![std::any::TypeId::of::<usize>()].into_boxed_slice()
} }
@ -685,29 +725,35 @@ mod generate_tests {
#[allow(unused)] #[allow(unused)]
pub mod rhai_fn__add_together { pub mod rhai_fn__add_together {
use super::*; use super::*;
pub struct Token(); struct Token();
impl rhai::plugin::PluginFunction for Token { impl PluginFunction for Token {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 2usize { if args.len() != 2usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 2usize), rhai::Position::none()))); args.len(), 2usize), Position::none())));
} }
let arg0 = args[0usize].downcast_clone::<usize>().unwrap(); let arg0 = args[0usize].downcast_clone::<usize>().unwrap();
let arg1 = args[1usize].downcast_clone::<usize>().unwrap(); let arg1 = args[1usize].downcast_clone::<usize>().unwrap();
Ok(rhai::Dynamic::from(add_together(arg0, arg1))) Ok(Dynamic::from(add_together(arg0, arg1)))
} }
fn is_method_call(&self) -> bool { false } fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { Box::new(Token()) } fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![std::any::TypeId::of::<usize>(), vec![std::any::TypeId::of::<usize>(),
std::any::TypeId::of::<usize>()].into_boxed_slice() std::any::TypeId::of::<usize>()].into_boxed_slice()
} }
} }
pub fn Token__callable() -> CallableFunction {
CallableFunction::from_plugin(Token())
}
pub fn Token__input_types() -> Box<[std::any::TypeId]> {
Token().input_types()
}
} }
}; };
@ -725,29 +771,35 @@ mod generate_tests {
#[allow(unused)] #[allow(unused)]
pub mod rhai_fn__increment { pub mod rhai_fn__increment {
use super::*; use super::*;
pub struct Token(); struct Token();
impl rhai::plugin::PluginFunction for Token { impl PluginFunction for Token {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 2usize { if args.len() != 2usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 2usize), rhai::Position::none()))); args.len(), 2usize), Position::none())));
} }
let arg1 = args[1usize].downcast_clone::<usize>().unwrap(); let arg1 = args[1usize].downcast_clone::<usize>().unwrap();
let arg0: &mut _ = args[0usize].downcast_mut::<usize>().unwrap(); let arg0: &mut _ = args[0usize].downcast_mut::<usize>().unwrap();
Ok(rhai::Dynamic::from(increment(arg0, arg1))) Ok(Dynamic::from(increment(arg0, arg1)))
} }
fn is_method_call(&self) -> bool { true } fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { Box::new(Token()) } fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![std::any::TypeId::of::<usize>(), vec![std::any::TypeId::of::<usize>(),
std::any::TypeId::of::<usize>()].into_boxed_slice() std::any::TypeId::of::<usize>()].into_boxed_slice()
} }
} }
pub fn Token__callable() -> CallableFunction {
CallableFunction::from_plugin(Token())
}
pub fn Token__input_types() -> Box<[std::any::TypeId]> {
Token().input_types()
}
} }
}; };
@ -766,27 +818,33 @@ mod generate_tests {
#[allow(unused)] #[allow(unused)]
pub mod rhai_fn__special_print { pub mod rhai_fn__special_print {
use super::*; use super::*;
pub struct Token(); struct Token();
impl rhai::plugin::PluginFunction for Token { impl PluginFunction for Token {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 1usize { if args.len() != 1usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 1usize), rhai::Position::none()))); args.len(), 1usize), Position::none())));
} }
let arg0 = args[0usize].downcast_clone::<rhai::ImmutableString>().unwrap(); let arg0 = args[0usize].downcast_clone::<ImmutableString>().unwrap();
Ok(rhai::Dynamic::from(special_print(&arg0))) Ok(Dynamic::from(special_print(&arg0)))
} }
fn is_method_call(&self) -> bool { false } fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { Box::new(Token()) } fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![std::any::TypeId::of::<rhai::ImmutableString>()].into_boxed_slice() vec![std::any::TypeId::of::<ImmutableString>()].into_boxed_slice()
} }
} }
pub fn Token__callable() -> CallableFunction {
CallableFunction::from_plugin(Token())
}
pub fn Token__input_types() -> Box<[std::any::TypeId]> {
Token().input_types()
}
} }
}; };

View File

@ -4,7 +4,7 @@
//! # Exporting a Macro to Rhai //! # Exporting a Macro to Rhai
//! //!
//! ``` //! ```
//! use rhai::{EvalAltResult, FLOAT, RegisterFn}; //! use rhai::{EvalAltResult, FLOAT};
//! use rhai::plugin::*; //! use rhai::plugin::*;
//! use rhai::module_resolvers::*; //! use rhai::module_resolvers::*;
//! //!
@ -144,8 +144,8 @@ pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenS
}; };
let tokens = quote! { let tokens = quote! {
#rhai_module.set_fn(#export_name, rhai::FnAccess::Public, #rhai_module.set_fn(#export_name, rhai::FnAccess::Public,
#gen_mod_path::Token().input_types().as_ref(), #gen_mod_path::Token__input_types().as_ref(),
CallableFunction::from_plugin(#gen_mod_path::Token())); #gen_mod_path::Token__callable());
}; };
proc_macro::TokenStream::from(tokens) proc_macro::TokenStream::from(tokens)

View File

@ -263,7 +263,7 @@ mod generate_tests {
let expected_tokens = quote! { let expected_tokens = quote! {
pub mod empty { pub mod empty {
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();
@ -292,37 +292,43 @@ mod generate_tests {
42 42
} }
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();
m.set_fn("get_mystic_number", FnAccess::Public, &[], m.set_fn("get_mystic_number", FnAccess::Public, &[],
rhai::plugin::CallableFunction::from_plugin(get_mystic_number__Token())); CallableFunction::from_plugin(get_mystic_number__Token()));
m m
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct get_mystic_number__Token(); struct get_mystic_number__Token();
impl rhai::plugin::PluginFunction for get_mystic_number__Token { impl PluginFunction for get_mystic_number__Token {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 0usize { if args.len() != 0usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 0usize), rhai::Position::none()))); args.len(), 0usize), Position::none())));
} }
Ok(rhai::Dynamic::from(get_mystic_number())) Ok(Dynamic::from(get_mystic_number()))
} }
fn is_method_call(&self) -> bool { false } fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(get_mystic_number__Token()) Box::new(get_mystic_number__Token())
} }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![].into_boxed_slice() vec![].into_boxed_slice()
} }
} }
pub fn get_mystic_number__Token__callable() -> CallableFunction {
CallableFunction::from_plugin(get_mystic_number__Token())
}
pub fn get_mystic_number__Token__input_types() -> Box<[std::any::TypeId]> {
get_mystic_number__Token().input_types()
}
} }
}; };
@ -346,38 +352,44 @@ mod generate_tests {
x + 1 x + 1
} }
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();
m.set_fn("add_one_to", FnAccess::Public, &[core::any::TypeId::of::<INT>()], m.set_fn("add_one_to", FnAccess::Public, &[core::any::TypeId::of::<INT>()],
rhai::plugin::CallableFunction::from_plugin(add_one_to__Token())); CallableFunction::from_plugin(add_one_to__Token()));
m m
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct add_one_to__Token(); struct add_one_to__Token();
impl rhai::plugin::PluginFunction for add_one_to__Token { impl PluginFunction for add_one_to__Token {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 1usize { if args.len() != 1usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 1usize), rhai::Position::none()))); args.len(), 1usize), Position::none())));
} }
let arg0 = args[0usize].downcast_clone::<INT>().unwrap(); let arg0 = args[0usize].downcast_clone::<INT>().unwrap();
Ok(rhai::Dynamic::from(add_one_to(arg0))) Ok(Dynamic::from(add_one_to(arg0)))
} }
fn is_method_call(&self) -> bool { false } fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(add_one_to__Token()) Box::new(add_one_to__Token())
} }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![std::any::TypeId::of::<INT>()].into_boxed_slice() vec![std::any::TypeId::of::<INT>()].into_boxed_slice()
} }
} }
pub fn add_one_to__Token__callable() -> CallableFunction {
CallableFunction::from_plugin(add_one_to__Token())
}
pub fn add_one_to__Token__input_types() -> Box<[std::any::TypeId]> {
add_one_to__Token().input_types()
}
} }
}; };
@ -401,34 +413,34 @@ mod generate_tests {
x + y x + y
} }
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();
m.set_fn("add_together", FnAccess::Public, &[core::any::TypeId::of::<INT>(), m.set_fn("add_together", FnAccess::Public, &[core::any::TypeId::of::<INT>(),
core::any::TypeId::of::<INT>()], core::any::TypeId::of::<INT>()],
rhai::plugin::CallableFunction::from_plugin(add_together__Token())); CallableFunction::from_plugin(add_together__Token()));
m m
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct add_together__Token(); struct add_together__Token();
impl rhai::plugin::PluginFunction for add_together__Token { impl PluginFunction for add_together__Token {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 2usize { if args.len() != 2usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 2usize), rhai::Position::none()))); args.len(), 2usize), Position::none())));
} }
let arg0 = args[0usize].downcast_clone::<INT>().unwrap(); let arg0 = args[0usize].downcast_clone::<INT>().unwrap();
let arg1 = args[1usize].downcast_clone::<INT>().unwrap(); let arg1 = args[1usize].downcast_clone::<INT>().unwrap();
Ok(rhai::Dynamic::from(add_together(arg0, arg1))) Ok(Dynamic::from(add_together(arg0, arg1)))
} }
fn is_method_call(&self) -> bool { false } fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(add_together__Token()) Box::new(add_together__Token())
} }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
@ -436,6 +448,12 @@ mod generate_tests {
std::any::TypeId::of::<INT>()].into_boxed_slice() std::any::TypeId::of::<INT>()].into_boxed_slice()
} }
} }
pub fn add_together__Token__callable() -> CallableFunction {
CallableFunction::from_plugin(add_together__Token())
}
pub fn add_together__Token__input_types() -> Box<[std::any::TypeId]> {
add_together__Token().input_types()
}
} }
}; };
@ -455,7 +473,7 @@ mod generate_tests {
pub mod one_constant { pub mod one_constant {
pub const MYSTIC_NUMBER: INT = 42; pub const MYSTIC_NUMBER: INT = 42;
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();
@ -483,7 +501,7 @@ mod generate_tests {
pub use rhai::INT; pub use rhai::INT;
pub const MYSTIC_NUMBER: INT = 42; pub const MYSTIC_NUMBER: INT = 42;
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();
@ -513,7 +531,7 @@ mod generate_tests {
42 42
} }
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();
@ -538,7 +556,7 @@ mod generate_tests {
pub mod one_constant { pub mod one_constant {
const MYSTIC_NUMBER: INT = 42; const MYSTIC_NUMBER: INT = 42;
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();
@ -567,39 +585,45 @@ mod generate_tests {
x + 1 x + 1
} }
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();
m.set_fn("print_out_to", FnAccess::Public, m.set_fn("print_out_to", FnAccess::Public,
&[core::any::TypeId::of::<rhai::ImmutableString>()], &[core::any::TypeId::of::<ImmutableString>()],
rhai::plugin::CallableFunction::from_plugin(print_out_to__Token())); CallableFunction::from_plugin(print_out_to__Token()));
m m
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct print_out_to__Token(); struct print_out_to__Token();
impl rhai::plugin::PluginFunction for print_out_to__Token { impl PluginFunction for print_out_to__Token {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 1usize { if args.len() != 1usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 1usize), rhai::Position::none()))); args.len(), 1usize), Position::none())));
} }
let arg0 = args[0usize].downcast_clone::<rhai::ImmutableString>().unwrap(); let arg0 = args[0usize].downcast_clone::<ImmutableString>().unwrap();
Ok(rhai::Dynamic::from(print_out_to(&arg0))) Ok(Dynamic::from(print_out_to(&arg0)))
} }
fn is_method_call(&self) -> bool { false } fn is_method_call(&self) -> bool { false }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(print_out_to__Token()) Box::new(print_out_to__Token())
} }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![std::any::TypeId::of::<rhai::ImmutableString>()].into_boxed_slice() vec![std::any::TypeId::of::<ImmutableString>()].into_boxed_slice()
} }
} }
pub fn print_out_to__Token__callable() -> CallableFunction {
CallableFunction::from_plugin(print_out_to__Token())
}
pub fn print_out_to__Token__input_types() -> Box<[std::any::TypeId]> {
print_out_to__Token().input_types()
}
} }
}; };
@ -623,40 +647,46 @@ mod generate_tests {
*x += 1.0 as FLOAT; *x += 1.0 as FLOAT;
} }
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();
m.set_fn("increment", FnAccess::Public, m.set_fn("increment", FnAccess::Public,
&[core::any::TypeId::of::<FLOAT>()], &[core::any::TypeId::of::<FLOAT>()],
rhai::plugin::CallableFunction::from_plugin(increment__Token())); CallableFunction::from_plugin(increment__Token()));
m m
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct increment__Token(); struct increment__Token();
impl rhai::plugin::PluginFunction for increment__Token { impl PluginFunction for increment__Token {
fn call(&self, fn call(&self,
args: &mut [&mut rhai::Dynamic], pos: rhai::Position args: &mut [&mut Dynamic], pos: Position
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> { ) -> Result<Dynamic, Box<EvalAltResult>> {
if args.len() != 1usize { if args.len() != 1usize {
return Err(Box::new(rhai::EvalAltResult::ErrorRuntime( return Err(Box::new(EvalAltResult::ErrorRuntime(
format!("wrong arg count: {} != {}", format!("wrong arg count: {} != {}",
args.len(), 1usize), rhai::Position::none()))); args.len(), 1usize), Position::none())));
} }
let arg0: &mut _ = args[0usize].downcast_mut::<FLOAT>().unwrap(); let arg0: &mut _ = args[0usize].downcast_mut::<FLOAT>().unwrap();
Ok(rhai::Dynamic::from(increment(arg0))) Ok(Dynamic::from(increment(arg0)))
} }
fn is_method_call(&self) -> bool { true } fn is_method_call(&self) -> bool { true }
fn is_varadic(&self) -> bool { false } fn is_varadic(&self) -> bool { false }
fn clone_boxed(&self) -> Box<dyn rhai::plugin::PluginFunction> { fn clone_boxed(&self) -> Box<dyn PluginFunction> {
Box::new(increment__Token()) Box::new(increment__Token())
} }
fn input_types(&self) -> Box<[std::any::TypeId]> { fn input_types(&self) -> Box<[std::any::TypeId]> {
vec![std::any::TypeId::of::<FLOAT>()].into_boxed_slice() vec![std::any::TypeId::of::<FLOAT>()].into_boxed_slice()
} }
} }
} pub fn increment__Token__callable() -> CallableFunction {
CallableFunction::from_plugin(increment__Token())
}
pub fn increment__Token__input_types() -> Box<[std::any::TypeId]> {
increment__Token().input_types()
}
}
}; };
let item_mod = syn::parse2::<Module>(input_tokens).unwrap(); let item_mod = syn::parse2::<Module>(input_tokens).unwrap();

View File

@ -44,7 +44,7 @@ pub(crate) fn generate_body(
}) => match elem.as_ref() { }) => match elem.as_ref() {
&syn::Type::Path(ref p) if p.path == str_type_path => { &syn::Type::Path(ref p) if p.path == str_type_path => {
syn::parse2::<syn::Type>(quote! { syn::parse2::<syn::Type>(quote! {
rhai::ImmutableString }) ImmutableString })
.unwrap() .unwrap()
} }
_ => panic!("internal error: non-string shared reference!?"), _ => panic!("internal error: non-string shared reference!?"),
@ -71,22 +71,24 @@ pub(crate) fn generate_body(
set_fn_stmts.push( set_fn_stmts.push(
syn::parse2::<syn::Stmt>(quote! { syn::parse2::<syn::Stmt>(quote! {
m.set_fn(#fn_literal, FnAccess::Public, &[#(#fn_input_types),*], m.set_fn(#fn_literal, FnAccess::Public, &[#(#fn_input_types),*],
rhai::plugin::CallableFunction::from_plugin(#fn_token_name())); CallableFunction::from_plugin(#fn_token_name()));
}) })
.unwrap(), .unwrap(),
); );
gen_fn_tokens.push(quote! { gen_fn_tokens.push(quote! {
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub struct #fn_token_name(); struct #fn_token_name();
}); });
gen_fn_tokens.push(function.generate_impl(&fn_token_name.to_string())); gen_fn_tokens.push(function.generate_impl(&fn_token_name.to_string()));
gen_fn_tokens.push(function.generate_callable(&fn_token_name.to_string()));
gen_fn_tokens.push(function.generate_input_types(&fn_token_name.to_string()));
} }
let mut generate_fncall = syn::parse2::<syn::ItemMod>(quote! { let mut generate_fncall = syn::parse2::<syn::ItemMod>(quote! {
pub mod generate_info { pub mod generate_info {
#[allow(unused_imports)] #[allow(unused_imports)]
use rhai::{Module, FnAccess}; use super::*;
#[allow(unused_mut)] #[allow(unused_mut)]
pub fn rhai_module__generate() -> Module { pub fn rhai_module__generate() -> Module {
let mut m = Module::new(); let mut m = Module::new();

View File

@ -1,9 +1,8 @@
use rhai::module_resolvers::*; use rhai::module_resolvers::*;
use rhai::plugin::*; use rhai::{Engine, EvalAltResult, Module, RegisterFn, FLOAT, INT};
use rhai::{EvalAltResult, Module, RegisterFn, FLOAT, INT};
pub mod raw_fn { pub mod raw_fn {
use rhai::export_fn; use rhai::plugin::*;
use rhai::FLOAT; use rhai::FLOAT;
#[export_fn] #[export_fn]
@ -37,7 +36,7 @@ fn raw_fn_test() -> Result<(), Box<EvalAltResult>> {
} }
mod raw_fn_mut { mod raw_fn_mut {
use rhai::export_fn; use rhai::plugin::*;
use rhai::FLOAT; use rhai::FLOAT;
#[export_fn] #[export_fn]
@ -69,7 +68,7 @@ fn raw_fn_mut_test() -> Result<(), Box<EvalAltResult>> {
} }
mod raw_fn_str { mod raw_fn_str {
use rhai::export_fn; use rhai::plugin::*;
#[export_fn] #[export_fn]
pub fn write_out_str(message: &str) -> bool { pub fn write_out_str(message: &str) -> bool {
@ -100,7 +99,7 @@ fn raw_fn_str_test() -> Result<(), Box<EvalAltResult>> {
} }
mod mut_opaque_ref { mod mut_opaque_ref {
use rhai::export_fn; use rhai::plugin::*;
use rhai::INT; use rhai::INT;
#[derive(Clone)] #[derive(Clone)]

View File

@ -1,9 +1,8 @@
use rhai::module_resolvers::*; use rhai::module_resolvers::*;
use rhai::plugin::*; use rhai::{Engine, EvalAltResult, RegisterFn, FLOAT, INT};
use rhai::{EvalAltResult, RegisterFn, FLOAT, INT};
pub mod empty_module { pub mod empty_module {
use rhai::export_module; use rhai::plugin::*;
#[export_module] #[export_module]
pub mod EmptyModule {} pub mod EmptyModule {}
@ -25,7 +24,7 @@ fn empty_module_test() -> Result<(), Box<EvalAltResult>> {
} }
pub mod one_fn_module { pub mod one_fn_module {
use rhai::export_module; use rhai::plugin::*;
#[export_module] #[export_module]
pub mod advanced_math { pub mod advanced_math {
@ -56,7 +55,7 @@ fn one_fn_module_test() -> Result<(), Box<EvalAltResult>> {
} }
pub mod one_fn_and_const_module { pub mod one_fn_and_const_module {
use rhai::export_module; use rhai::plugin::*;
#[export_module] #[export_module]
pub mod advanced_math { pub mod advanced_math {
@ -91,7 +90,7 @@ fn one_fn_and_const_module_test() -> Result<(), Box<EvalAltResult>> {
} }
pub mod raw_fn_str_module { pub mod raw_fn_str_module {
use rhai::export_module; use rhai::plugin::*;
#[export_module] #[export_module]
pub mod host_io { pub mod host_io {
@ -122,7 +121,7 @@ fn raw_fn_str_module_test() -> Result<(), Box<EvalAltResult>> {
} }
pub mod mut_opaque_ref_module { pub mod mut_opaque_ref_module {
use rhai::export_module; use rhai::plugin::*;
use rhai::INT; use rhai::INT;
#[derive(Clone)] #[derive(Clone)]

View File

@ -1,4 +1,4 @@
use rhai::export_fn; use rhai::plugin::*;
struct NonClonable { struct NonClonable {
a: f32, a: f32,

View File

@ -5,7 +5,7 @@ error: references from Rhai in this position must be mutable
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error[E0425]: cannot find function `test_fn` in this scope error[E0425]: cannot find function `test_fn` in this scope
--> $DIR/first_shared_ref.rs:17:8 --> $DIR/first_shared_ref.rs:22:8
| |
17 | if test_fn(n) { 22 | if test_fn(n) {
| ^^^^^^^ not found in this scope | ^^^^^^^ not found in this scope

View File

@ -1,4 +1,4 @@
use rhai::export_fn; use rhai::plugin::*;
struct NonClonable { struct NonClonable {
a: f32, a: f32,

View File

@ -1,4 +1,4 @@
use rhai::export_fn; use rhai::plugin::*;
struct NonClonable { struct NonClonable {
a: f32, a: f32,

View File

@ -1,4 +1,4 @@
use rhai::export_fn; use rhai::plugin::*;
#[derive(Clone)] #[derive(Clone)]
struct Clonable { struct Clonable {

View File

@ -5,7 +5,7 @@ error: cannot return a reference to Rhai
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error[E0425]: cannot find function `test_fn` in this scope error[E0425]: cannot find function `test_fn` in this scope
--> $DIR/return_mut_ref.rs:18:8 --> $DIR/return_mut_ref.rs:23:8
| |
18 | if test_fn(n) { 23 | if test_fn(n) {
| ^^^^^^^ not found in this scope | ^^^^^^^ not found in this scope

View File

@ -1,4 +1,4 @@
use rhai::export_fn; use rhai::plugin::*;
#[derive(Clone)] #[derive(Clone)]
struct Clonable { struct Clonable {

View File

@ -5,7 +5,7 @@ error: cannot return a pointer to Rhai
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error[E0425]: cannot find function `test_fn` in this scope error[E0425]: cannot find function `test_fn` in this scope
--> $DIR/return_pointer.rs:18:39 --> $DIR/return_pointer.rs:24:19
| |
18 | println!("{}", unsafe { let ptr = test_fn(n); *ptr }); 24 | let ptr = test_fn(n);
| ^^^^^^^ not found in this scope | ^^^^^^^ not found in this scope

View File

@ -1,4 +1,4 @@
use rhai::export_fn; use rhai::plugin::*;
#[derive(Clone)] #[derive(Clone)]
struct Clonable { struct Clonable {

View File

@ -1,11 +1,11 @@
error: cannot return a reference to Rhai error: cannot return a reference to Rhai
--> $DIR/return_shared_ref.rs:12:33 --> $DIR/return_shared_ref.rs:12:33
| |
12 | pub fn test_fn(input: Clonable) -> & 'static str { 12 | pub fn test_fn(input: Clonable) -> &'static str {
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error[E0425]: cannot find function `test_fn` in this scope error[E0425]: cannot find function `test_fn` in this scope
--> $DIR/return_shared_ref.rs:18:20 --> $DIR/return_shared_ref.rs:23:20
| |
18 | println!("{}", test_fn(n)); 23 | println!("{}", test_fn(n));
| ^^^^^^^ not found in this scope | ^^^^^^^ not found in this scope

View File

@ -1,4 +1,4 @@
use rhai::export_fn; use rhai::plugin::*;
#[derive(Clone)] #[derive(Clone)]
pub struct Clonable { pub struct Clonable {

View File

@ -5,7 +5,7 @@ error: this type in this position passes from Rhai by value
| ^^^^^ | ^^^^^
error[E0425]: cannot find function `test_fn` in this scope error[E0425]: cannot find function `test_fn` in this scope
--> $DIR/second_shared_ref.rs:18:8 --> $DIR/second_shared_ref.rs:23:8
| |
18 | if test_fn(n, &true) { 23 | if test_fn(n, &true) {
| ^^^^^^^ not found in this scope | ^^^^^^^ not found in this scope

View File

@ -2,11 +2,18 @@
use crate::stdlib::{any::TypeId, boxed::Box}; use crate::stdlib::{any::TypeId, boxed::Box};
use crate::any::Dynamic; pub use crate::{
use crate::engine::Engine; fn_native::CallableFunction,
pub use crate::fn_native::CallableFunction; Dynamic,
use crate::result::EvalAltResult; Engine,
use crate::token::Position; EvalAltResult,
FnAccess,
ImmutableString,
Module,
Position,
};
pub use rhai_codegen::*;
#[cfg(features = "sync")] #[cfg(features = "sync")]
/// Represents an externally-written plugin for the Rhai interpreter. /// Represents an externally-written plugin for the Rhai interpreter.