Use static array for codegen parameters info.
This commit is contained in:
parent
1d661f2c8e
commit
adbb5f8eb8
@ -16,6 +16,8 @@ an object map is small.
|
|||||||
`HashMap` and `BTreeMap` have almost identical public API's so this change is unlikely to break
|
`HashMap` and `BTreeMap` have almost identical public API's so this change is unlikely to break
|
||||||
existing code.
|
existing code.
|
||||||
|
|
||||||
|
All function signature/metadata methods are now grouped under the umbrella `metadata` feature.
|
||||||
|
|
||||||
|
|
||||||
Breaking changes
|
Breaking changes
|
||||||
----------------
|
----------------
|
||||||
|
@ -587,20 +587,14 @@ impl ExportedFn {
|
|||||||
let name: syn::Ident =
|
let name: syn::Ident =
|
||||||
syn::Ident::new(&format!("rhai_fn_{}", self.name()), self.name().span());
|
syn::Ident::new(&format!("rhai_fn_{}", self.name()), 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 param_names_block = self.generate_param_names("Token");
|
|
||||||
let input_types_block = self.generate_input_types("Token");
|
|
||||||
let dyn_result_fn_block = self.generate_dynamic_fn();
|
let dyn_result_fn_block = self.generate_dynamic_fn();
|
||||||
let vis = self.visibility;
|
let vis = self.visibility;
|
||||||
quote! {
|
quote! {
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
#vis mod #name {
|
#vis mod #name {
|
||||||
use super::*;
|
use super::*;
|
||||||
struct Token();
|
pub struct Token();
|
||||||
#impl_block
|
#impl_block
|
||||||
#callable_block
|
|
||||||
#param_names_block
|
|
||||||
#input_types_block
|
|
||||||
#dyn_result_fn_block
|
#dyn_result_fn_block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -613,7 +607,7 @@ impl ExportedFn {
|
|||||||
dynamic_signature.ident =
|
dynamic_signature.ident =
|
||||||
syn::Ident::new("dynamic_result_fn", proc_macro2::Span::call_site());
|
syn::Ident::new("dynamic_result_fn", proc_macro2::Span::call_site());
|
||||||
dynamic_signature.output = syn::parse2::<syn::ReturnType>(quote! {
|
dynamic_signature.output = syn::parse2::<syn::ReturnType>(quote! {
|
||||||
-> Result<Dynamic, Box<EvalAltResult>>
|
-> RhaiResult
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let arguments: Vec<syn::Ident> = dynamic_signature
|
let arguments: Vec<syn::Ident> = dynamic_signature
|
||||||
@ -649,48 +643,6 @@ impl ExportedFn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.to_lowercase()),
|
|
||||||
self.name().span(),
|
|
||||||
);
|
|
||||||
quote! {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn #callable_fn_name() -> CallableFunction {
|
|
||||||
#token_name().into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_param_names(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
|
||||||
let token_name: syn::Ident = syn::Ident::new(on_type_name, self.name().span());
|
|
||||||
let param_names_fn_name: syn::Ident = syn::Ident::new(
|
|
||||||
&format!("{}_param_names", on_type_name.to_lowercase()),
|
|
||||||
self.name().span(),
|
|
||||||
);
|
|
||||||
quote! {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn #param_names_fn_name() -> Box<[&'static str]> {
|
|
||||||
#token_name().param_names()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.to_lowercase()),
|
|
||||||
self.name().span(),
|
|
||||||
);
|
|
||||||
quote! {
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn #input_types_fn_name() -> Box<[TypeId]> {
|
|
||||||
#token_name().input_types()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_impl(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
pub fn generate_impl(&self, on_type_name: &str) -> proc_macro2::TokenStream {
|
||||||
let sig_name = self.name().clone();
|
let sig_name = self.name().clone();
|
||||||
let arg_count = self.arg_count();
|
let arg_count = self.arg_count();
|
||||||
@ -866,23 +818,19 @@ 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 #type_name {
|
||||||
|
pub const PARAM_NAMES: &'static [&'static str] = &[#(#input_type_names,)* #return_type];
|
||||||
|
#[inline(always)] pub fn param_types() -> [TypeId; #arg_count] { [#(#input_type_exprs),*] }
|
||||||
|
}
|
||||||
impl PluginFunction for #type_name {
|
impl PluginFunction for #type_name {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
debug_assert_eq!(args.len(), #arg_count, "wrong arg count: {} != {}", args.len(), #arg_count);
|
|
||||||
#(#unpack_statements)*
|
#(#unpack_statements)*
|
||||||
#return_expr
|
#return_expr
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)] fn is_method_call(&self) -> bool { #is_method_call }
|
#[inline(always)] fn is_method_call(&self) -> bool { #is_method_call }
|
||||||
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
||||||
#[inline(always)] fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(#type_name()) }
|
|
||||||
#[inline(always)] fn param_names(&self) -> Box<[&'static str]> {
|
|
||||||
new_vec![#(#input_type_names,)* #return_type].into_boxed_slice()
|
|
||||||
}
|
|
||||||
#[inline(always)] fn input_types(&self) -> Box<[TypeId]> {
|
|
||||||
new_vec![#(#input_type_exprs),*].into_boxed_slice()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,9 +332,9 @@ pub fn set_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream
|
|||||||
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
||||||
proc_macro::TokenStream::from(quote! {
|
proc_macro::TokenStream::from(quote! {
|
||||||
#module_expr.set_fn(#export_name, FnNamespace::Internal, FnAccess::Public,
|
#module_expr.set_fn(#export_name, FnNamespace::Internal, FnAccess::Public,
|
||||||
Some(#gen_mod_path::token_param_names().as_ref()),
|
Some(#gen_mod_path::Token::PARAM_NAMES),
|
||||||
#gen_mod_path::token_input_types().as_ref(),
|
&#gen_mod_path::Token::param_types(),
|
||||||
#gen_mod_path::token_callable());
|
#gen_mod_path::Token().into());
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
@ -373,9 +373,9 @@ pub fn set_exported_global_fn(args: proc_macro::TokenStream) -> proc_macro::Toke
|
|||||||
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
let gen_mod_path = crate::register::generated_module_path(&rust_mod_path);
|
||||||
proc_macro::TokenStream::from(quote! {
|
proc_macro::TokenStream::from(quote! {
|
||||||
#module_expr.set_fn(#export_name, FnNamespace::Global, FnAccess::Public,
|
#module_expr.set_fn(#export_name, FnNamespace::Global, FnAccess::Public,
|
||||||
Some(#gen_mod_path::token_param_names().as_ref()),
|
Some(#gen_mod_path::Token::PARAM_NAMES),
|
||||||
#gen_mod_path::token_input_types().as_ref(),
|
&#gen_mod_path::Token::param_types(),
|
||||||
#gen_mod_path::token_callable());
|
#gen_mod_path::Token().into());
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(e) => e.to_compile_error().into(),
|
Err(e) => e.to_compile_error().into(),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use quote::{quote, ToTokens};
|
use quote::quote;
|
||||||
|
|
||||||
use crate::attrs::ExportScope;
|
use crate::attrs::ExportScope;
|
||||||
use crate::function::{
|
use crate::function::{
|
||||||
@ -81,16 +81,6 @@ pub fn generate_body(
|
|||||||
);
|
);
|
||||||
let reg_names = function.exported_names();
|
let reg_names = function.exported_names();
|
||||||
|
|
||||||
let fn_input_names: Vec<String> = function
|
|
||||||
.arg_list()
|
|
||||||
.map(|fn_arg| match fn_arg {
|
|
||||||
syn::FnArg::Receiver(_) => panic!("internal error: receiver fn outside impl!?"),
|
|
||||||
syn::FnArg::Typed(syn::PatType { pat, ty, .. }) => {
|
|
||||||
format!("{}: {}", pat.to_token_stream(), print_type(ty))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let fn_input_types: Vec<syn::Expr> = function
|
let fn_input_types: Vec<syn::Expr> = function
|
||||||
.arg_list()
|
.arg_list()
|
||||||
.map(|fn_arg| match fn_arg {
|
.map(|fn_arg| match fn_arg {
|
||||||
@ -128,17 +118,12 @@ pub fn generate_body(
|
|||||||
};
|
};
|
||||||
|
|
||||||
syn::parse2::<syn::Expr>(quote! {
|
syn::parse2::<syn::Expr>(quote! {
|
||||||
core::any::TypeId::of::<#arg_type>()})
|
TypeId::of::<#arg_type>()})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let return_type = function
|
|
||||||
.return_type()
|
|
||||||
.map(print_type)
|
|
||||||
.unwrap_or_else(|| "()".to_string());
|
|
||||||
|
|
||||||
for fn_literal in reg_names {
|
for fn_literal in reg_names {
|
||||||
let mut namespace = FnNamespaceAccess::Internal;
|
let mut namespace = FnNamespaceAccess::Internal;
|
||||||
|
|
||||||
@ -172,7 +157,7 @@ pub fn generate_body(
|
|||||||
set_fn_statements.push(
|
set_fn_statements.push(
|
||||||
syn::parse2::<syn::Stmt>(quote! {
|
syn::parse2::<syn::Stmt>(quote! {
|
||||||
m.set_fn(#fn_literal, FnNamespace::#ns_str, FnAccess::Public,
|
m.set_fn(#fn_literal, FnNamespace::#ns_str, FnAccess::Public,
|
||||||
Some(&[#(#fn_input_names,)* #return_type]), &[#(#fn_input_types),*],
|
Some(#fn_token_name::PARAM_NAMES), &[#(#fn_input_types),*],
|
||||||
#fn_token_name().into());
|
#fn_token_name().into());
|
||||||
})
|
})
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -181,12 +166,9 @@ pub fn generate_body(
|
|||||||
|
|
||||||
gen_fn_tokens.push(quote! {
|
gen_fn_tokens.push(quote! {
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
struct #fn_token_name();
|
pub 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_param_names(&fn_token_name.to_string()));
|
|
||||||
gen_fn_tokens.push(function.generate_input_types(&fn_token_name.to_string()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut generate_fn_call = syn::parse2::<syn::ItemMod>(quote! {
|
let mut generate_fn_call = syn::parse2::<syn::ItemMod>(quote! {
|
||||||
|
@ -275,35 +275,21 @@ mod generate_tests {
|
|||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
pub mod rhai_fn_do_nothing {
|
pub mod rhai_fn_do_nothing {
|
||||||
use super::*;
|
use super::*;
|
||||||
struct Token();
|
pub struct Token();
|
||||||
|
impl Token {
|
||||||
|
pub const PARAM_NAMES: &'static [&'static str] = &["()"];
|
||||||
|
#[inline(always)] pub fn param_types() -> [TypeId; 0usize] { [] }
|
||||||
|
}
|
||||||
impl PluginFunction for Token {
|
impl PluginFunction for Token {
|
||||||
#[inline(always)] fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
#[inline(always)] fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
debug_assert_eq!(args.len(), 0usize,
|
|
||||||
"wrong arg count: {} != {}", args.len(), 0usize);
|
|
||||||
Ok(Dynamic::from(do_nothing()))
|
Ok(Dynamic::from(do_nothing()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
||||||
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
||||||
#[inline(always)] fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
|
||||||
#[inline(always)] fn param_names(&self) -> Box<[&'static str]> {
|
|
||||||
new_vec!["()"].into_boxed_slice()
|
|
||||||
}
|
|
||||||
#[inline(always)] fn input_types(&self) -> Box<[TypeId]> {
|
|
||||||
new_vec![].into_boxed_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_callable() -> CallableFunction {
|
|
||||||
Token().into()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_param_names() -> Box<[&'static str]> {
|
|
||||||
Token().param_names()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_input_types() -> Box<[TypeId]> {
|
|
||||||
Token().input_types()
|
|
||||||
}
|
}
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[inline(always)] pub fn dynamic_result_fn() -> Result<Dynamic, Box<EvalAltResult> > {
|
#[inline(always)] pub fn dynamic_result_fn() -> RhaiResult {
|
||||||
Ok(Dynamic::from(do_nothing()))
|
Ok(Dynamic::from(do_nothing()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,37 +309,23 @@ mod generate_tests {
|
|||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
pub mod rhai_fn_do_something {
|
pub mod rhai_fn_do_something {
|
||||||
use super::*;
|
use super::*;
|
||||||
struct Token();
|
pub struct Token();
|
||||||
|
impl Token {
|
||||||
|
pub const PARAM_NAMES: &'static [&'static str] = &["x: usize", "()"];
|
||||||
|
#[inline(always)] pub fn param_types() -> [TypeId; 1usize] { [TypeId::of::<usize>()] }
|
||||||
|
}
|
||||||
impl PluginFunction for Token {
|
impl PluginFunction for Token {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
debug_assert_eq!(args.len(), 1usize,
|
|
||||||
"wrong arg count: {} != {}", args.len(), 1usize);
|
|
||||||
let arg0 = mem::take(args[0usize]).cast::<usize>();
|
let arg0 = mem::take(args[0usize]).cast::<usize>();
|
||||||
Ok(Dynamic::from(do_something(arg0)))
|
Ok(Dynamic::from(do_something(arg0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
||||||
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
||||||
#[inline(always)] fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
|
||||||
#[inline(always)] fn param_names(&self) -> Box<[&'static str]> {
|
|
||||||
new_vec!["x: usize", "()"].into_boxed_slice()
|
|
||||||
}
|
|
||||||
#[inline(always)] fn input_types(&self) -> Box<[TypeId]> {
|
|
||||||
new_vec![TypeId::of::<usize>()].into_boxed_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_callable() -> CallableFunction {
|
|
||||||
Token().into()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_param_names() -> Box<[&'static str]> {
|
|
||||||
Token().param_names()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_input_types() -> Box<[TypeId]> {
|
|
||||||
Token().input_types()
|
|
||||||
}
|
}
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[inline(always)] pub fn dynamic_result_fn(x: usize) -> Result<Dynamic, Box<EvalAltResult> > {
|
#[inline(always)] pub fn dynamic_result_fn(x: usize) -> RhaiResult {
|
||||||
Ok(Dynamic::from(do_something(x)))
|
Ok(Dynamic::from(do_something(x)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -373,37 +345,23 @@ mod generate_tests {
|
|||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
pub mod rhai_fn_do_something {
|
pub mod rhai_fn_do_something {
|
||||||
use super::*;
|
use super::*;
|
||||||
struct Token();
|
pub struct Token();
|
||||||
|
impl Token {
|
||||||
|
pub const PARAM_NAMES: &'static [&'static str] = &["x: usize", "()"];
|
||||||
|
#[inline(always)] pub fn param_types() -> [TypeId; 1usize] { [TypeId::of::<usize>()] }
|
||||||
|
}
|
||||||
impl PluginFunction for Token {
|
impl PluginFunction for Token {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
debug_assert_eq!(args.len(), 1usize,
|
|
||||||
"wrong arg count: {} != {}", args.len(), 1usize);
|
|
||||||
let arg0 = mem::take(args[0usize]).cast::<usize>();
|
let arg0 = mem::take(args[0usize]).cast::<usize>();
|
||||||
Ok(Dynamic::from(do_something(context, arg0)))
|
Ok(Dynamic::from(do_something(context, arg0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
||||||
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
||||||
#[inline(always)] fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
|
||||||
#[inline(always)] fn param_names(&self) -> Box<[&'static str]> {
|
|
||||||
new_vec!["x: usize", "()"].into_boxed_slice()
|
|
||||||
}
|
|
||||||
#[inline(always)] fn input_types(&self) -> Box<[TypeId]> {
|
|
||||||
new_vec![TypeId::of::<usize>()].into_boxed_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_callable() -> CallableFunction {
|
|
||||||
Token().into()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_param_names() -> Box<[&'static str]> {
|
|
||||||
Token().param_names()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_input_types() -> Box<[TypeId]> {
|
|
||||||
Token().input_types()
|
|
||||||
}
|
}
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[inline(always)] pub fn dynamic_result_fn(context: NativeCallContext, x: usize) -> Result<Dynamic, Box<EvalAltResult> > {
|
#[inline(always)] pub fn dynamic_result_fn(context: NativeCallContext, x: usize) -> RhaiResult {
|
||||||
Ok(Dynamic::from(do_something(context, x)))
|
Ok(Dynamic::from(do_something(context, x)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -426,36 +384,22 @@ mod generate_tests {
|
|||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
pub mod rhai_fn_return_dynamic {
|
pub mod rhai_fn_return_dynamic {
|
||||||
use super::*;
|
use super::*;
|
||||||
struct Token();
|
pub struct Token();
|
||||||
|
impl Token {
|
||||||
|
pub const PARAM_NAMES: &'static [&'static str] = &["rhai::Dynamic"];
|
||||||
|
#[inline(always)] pub fn param_types() -> [TypeId; 0usize] { [] }
|
||||||
|
}
|
||||||
impl PluginFunction for Token {
|
impl PluginFunction for Token {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
debug_assert_eq!(args.len(), 0usize,
|
|
||||||
"wrong arg count: {} != {}", args.len(), 0usize);
|
|
||||||
Ok(Dynamic::from(return_dynamic()))
|
Ok(Dynamic::from(return_dynamic()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
||||||
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
||||||
#[inline(always)] fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
|
||||||
#[inline(always)] fn param_names(&self) -> Box<[&'static str]> {
|
|
||||||
new_vec!["rhai::Dynamic"].into_boxed_slice()
|
|
||||||
}
|
|
||||||
#[inline(always)] fn input_types(&self) -> Box<[TypeId]> {
|
|
||||||
new_vec![].into_boxed_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_callable() -> CallableFunction {
|
|
||||||
Token().into()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_param_names() -> Box<[&'static str]> {
|
|
||||||
Token().param_names()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_input_types() -> Box<[TypeId]> {
|
|
||||||
Token().input_types()
|
|
||||||
}
|
}
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[inline(always)] pub fn dynamic_result_fn() -> Result<Dynamic, Box<EvalAltResult> > {
|
#[inline(always)] pub fn dynamic_result_fn() -> RhaiResult {
|
||||||
Ok(Dynamic::from(return_dynamic()))
|
Ok(Dynamic::from(return_dynamic()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -472,24 +416,19 @@ mod generate_tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let expected_tokens = quote! {
|
let expected_tokens = quote! {
|
||||||
|
impl TestStruct {
|
||||||
|
pub const PARAM_NAMES: &'static [&'static str] = &["x: usize", "()"];
|
||||||
|
#[inline(always)] pub fn param_types() -> [TypeId; 1usize] { [TypeId::of::<usize>()] }
|
||||||
|
}
|
||||||
impl PluginFunction for TestStruct {
|
impl PluginFunction for TestStruct {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
debug_assert_eq!(args.len(), 1usize,
|
|
||||||
"wrong arg count: {} != {}", args.len(), 1usize);
|
|
||||||
let arg0 = mem::take(args[0usize]).cast::<usize>();
|
let arg0 = mem::take(args[0usize]).cast::<usize>();
|
||||||
Ok(Dynamic::from(do_something(arg0)))
|
Ok(Dynamic::from(do_something(arg0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
||||||
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
||||||
#[inline(always)] fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(TestStruct()) }
|
|
||||||
#[inline(always)] fn param_names(&self) -> Box<[&'static str]> {
|
|
||||||
new_vec!["x: usize", "()"].into_boxed_slice()
|
|
||||||
}
|
|
||||||
#[inline(always)] fn input_types(&self) -> Box<[TypeId]> {
|
|
||||||
new_vec![TypeId::of::<usize>()].into_boxed_slice()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -507,12 +446,14 @@ mod generate_tests {
|
|||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
pub mod rhai_fn_add_together {
|
pub mod rhai_fn_add_together {
|
||||||
use super::*;
|
use super::*;
|
||||||
struct Token();
|
pub struct Token();
|
||||||
|
impl Token {
|
||||||
|
pub const PARAM_NAMES: &'static [&'static str] = &["x: usize", "y: usize", "usize"];
|
||||||
|
#[inline(always)] pub fn param_types() -> [TypeId; 2usize] { [TypeId::of::<usize>(), TypeId::of::<usize>()] }
|
||||||
|
}
|
||||||
impl PluginFunction for Token {
|
impl PluginFunction for Token {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
debug_assert_eq!(args.len(), 2usize,
|
|
||||||
"wrong arg count: {} != {}", args.len(), 2usize);
|
|
||||||
let arg0 = mem::take(args[0usize]).cast::<usize>();
|
let arg0 = mem::take(args[0usize]).cast::<usize>();
|
||||||
let arg1 = mem::take(args[1usize]).cast::<usize>();
|
let arg1 = mem::take(args[1usize]).cast::<usize>();
|
||||||
Ok(Dynamic::from(add_together(arg0, arg1)))
|
Ok(Dynamic::from(add_together(arg0, arg1)))
|
||||||
@ -520,26 +461,9 @@ mod generate_tests {
|
|||||||
|
|
||||||
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
||||||
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
||||||
#[inline(always)] fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
|
||||||
#[inline(always)] fn param_names(&self) -> Box<[&'static str]> {
|
|
||||||
new_vec!["x: usize", "y: usize", "usize"].into_boxed_slice()
|
|
||||||
}
|
|
||||||
#[inline(always)] fn input_types(&self) -> Box<[TypeId]> {
|
|
||||||
new_vec![TypeId::of::<usize>(),
|
|
||||||
TypeId::of::<usize>()].into_boxed_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_callable() -> CallableFunction {
|
|
||||||
Token().into()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_param_names() -> Box<[&'static str]> {
|
|
||||||
Token().param_names()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_input_types() -> Box<[TypeId]> {
|
|
||||||
Token().input_types()
|
|
||||||
}
|
}
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[inline(always)] pub fn dynamic_result_fn(x: usize, y: usize) -> Result<Dynamic, Box<EvalAltResult> > {
|
#[inline(always)] pub fn dynamic_result_fn(x: usize, y: usize) -> RhaiResult {
|
||||||
Ok(Dynamic::from(add_together(x, y)))
|
Ok(Dynamic::from(add_together(x, y)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -559,12 +483,14 @@ mod generate_tests {
|
|||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
pub mod rhai_fn_increment {
|
pub mod rhai_fn_increment {
|
||||||
use super::*;
|
use super::*;
|
||||||
struct Token();
|
pub struct Token();
|
||||||
|
impl Token {
|
||||||
|
pub const PARAM_NAMES: &'static [&'static str] = &["x: &mut usize", "y: usize", "()"];
|
||||||
|
#[inline(always)] pub fn param_types() -> [TypeId; 2usize] { [TypeId::of::<usize>(), TypeId::of::<usize>()] }
|
||||||
|
}
|
||||||
impl PluginFunction for Token {
|
impl PluginFunction for Token {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
debug_assert_eq!(args.len(), 2usize,
|
|
||||||
"wrong arg count: {} != {}", args.len(), 2usize);
|
|
||||||
if args[0usize].is_read_only() {
|
if args[0usize].is_read_only() {
|
||||||
return Err(Box::new(
|
return Err(Box::new(
|
||||||
EvalAltResult::ErrorAssignmentToConstant("x".to_string(), Position::NONE)
|
EvalAltResult::ErrorAssignmentToConstant("x".to_string(), Position::NONE)
|
||||||
@ -577,26 +503,9 @@ mod generate_tests {
|
|||||||
|
|
||||||
#[inline(always)] fn is_method_call(&self) -> bool { true }
|
#[inline(always)] fn is_method_call(&self) -> bool { true }
|
||||||
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
||||||
#[inline(always)] fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
|
||||||
#[inline(always)] fn param_names(&self) -> Box<[&'static str]> {
|
|
||||||
new_vec!["x: &mut usize", "y: usize", "()"].into_boxed_slice()
|
|
||||||
}
|
|
||||||
#[inline(always)] fn input_types(&self) -> Box<[TypeId]> {
|
|
||||||
new_vec![TypeId::of::<usize>(),
|
|
||||||
TypeId::of::<usize>()].into_boxed_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_callable() -> CallableFunction {
|
|
||||||
Token().into()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_param_names() -> Box<[&'static str]> {
|
|
||||||
Token().param_names()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_input_types() -> Box<[TypeId]> {
|
|
||||||
Token().input_types()
|
|
||||||
}
|
}
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[inline(always)] pub fn dynamic_result_fn(x: &mut usize, y: usize) -> Result<Dynamic, Box<EvalAltResult> > {
|
#[inline(always)] pub fn dynamic_result_fn(x: &mut usize, y: usize) -> RhaiResult {
|
||||||
Ok(Dynamic::from(increment(x, y)))
|
Ok(Dynamic::from(increment(x, y)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -617,37 +526,23 @@ mod generate_tests {
|
|||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
pub mod rhai_fn_special_print {
|
pub mod rhai_fn_special_print {
|
||||||
use super::*;
|
use super::*;
|
||||||
struct Token();
|
pub struct Token();
|
||||||
|
impl Token {
|
||||||
|
pub const PARAM_NAMES: &'static [&'static str] = &["message: &str", "()"];
|
||||||
|
#[inline(always)] pub fn param_types() -> [TypeId; 1usize] { [TypeId::of::<ImmutableString>()] }
|
||||||
|
}
|
||||||
impl PluginFunction for Token {
|
impl PluginFunction for Token {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> RhaiResult {
|
||||||
debug_assert_eq!(args.len(), 1usize,
|
|
||||||
"wrong arg count: {} != {}", args.len(), 1usize);
|
|
||||||
let arg0 = mem::take(args[0usize]).take_immutable_string().unwrap();
|
let arg0 = mem::take(args[0usize]).take_immutable_string().unwrap();
|
||||||
Ok(Dynamic::from(special_print(&arg0)))
|
Ok(Dynamic::from(special_print(&arg0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
#[inline(always)] fn is_method_call(&self) -> bool { false }
|
||||||
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
#[inline(always)] fn is_variadic(&self) -> bool { false }
|
||||||
#[inline(always)] fn clone_boxed(&self) -> Box<dyn PluginFunction> { Box::new(Token()) }
|
|
||||||
#[inline(always)] fn param_names(&self) -> Box<[&'static str]> {
|
|
||||||
new_vec!["message: &str", "()"].into_boxed_slice()
|
|
||||||
}
|
|
||||||
#[inline(always)] fn input_types(&self) -> Box<[TypeId]> {
|
|
||||||
new_vec![TypeId::of::<ImmutableString>()].into_boxed_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_callable() -> CallableFunction {
|
|
||||||
Token().into()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_param_names() -> Box<[&'static str]> {
|
|
||||||
Token().param_names()
|
|
||||||
}
|
|
||||||
#[inline(always)] pub fn token_input_types() -> Box<[TypeId]> {
|
|
||||||
Token().input_types()
|
|
||||||
}
|
}
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
#[inline(always)] pub fn dynamic_result_fn(message: &str) -> Result<Dynamic, Box<EvalAltResult> > {
|
#[inline(always)] pub fn dynamic_result_fn(message: &str) -> RhaiResult {
|
||||||
Ok(Dynamic::from(special_print(message)))
|
Ok(Dynamic::from(special_print(message)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@ help: consider importing one of these items
|
|||||||
|
|
|
|
||||||
11 | use core::fmt::Pointer;
|
11 | use core::fmt::Pointer;
|
||||||
|
|
|
|
||||||
11 | use crate::new_vec::fmt::Pointer;
|
11 | use crate::mem::fmt::Pointer;
|
||||||
|
|
|
|
||||||
11 | use std::fmt::Pointer;
|
11 | use std::fmt::Pointer;
|
||||||
|
|
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Module defining macros for developing _plugins_.
|
//! Module defining macros for developing _plugins_.
|
||||||
|
|
||||||
pub use crate::fn_native::{CallableFunction, FnCallArgs};
|
pub use crate::fn_native::{CallableFunction, FnCallArgs};
|
||||||
pub use crate::stdlib::{any::TypeId, boxed::Box, format, mem, string::ToString, vec as new_vec};
|
pub use crate::stdlib::{any::TypeId, boxed::Box, format, mem, string::ToString};
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module,
|
Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, ImmutableString, Module,
|
||||||
NativeCallContext, Position,
|
NativeCallContext, Position,
|
||||||
@ -26,13 +26,4 @@ pub trait PluginFunction {
|
|||||||
|
|
||||||
/// Is this plugin function variadic?
|
/// Is this plugin function variadic?
|
||||||
fn is_variadic(&self) -> bool;
|
fn is_variadic(&self) -> bool;
|
||||||
|
|
||||||
/// Convert a plugin function into a boxed trait object.
|
|
||||||
fn clone_boxed(&self) -> Box<dyn PluginFunction>;
|
|
||||||
|
|
||||||
/// Return a boxed slice of the names of the function's parameters and return type.
|
|
||||||
fn param_names(&self) -> Box<[&'static str]>;
|
|
||||||
|
|
||||||
/// Return a boxed slice of type ID's of the function's parameters.
|
|
||||||
fn input_types(&self) -> Box<[TypeId]>;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user