commit
2221d523f0
@ -8,6 +8,7 @@ New features
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
* Plugins support via procedural macros.
|
* Plugins support via procedural macros.
|
||||||
|
* Scripted functions are allowed in packages.
|
||||||
|
|
||||||
|
|
||||||
Version 0.18.3
|
Version 0.18.3
|
||||||
|
@ -22,6 +22,7 @@ pub trait ExportedParams: Sized {
|
|||||||
pub struct AttrItem {
|
pub struct AttrItem {
|
||||||
pub key: proc_macro2::Ident,
|
pub key: proc_macro2::Ident,
|
||||||
pub value: Option<syn::LitStr>,
|
pub value: Option<syn::LitStr>,
|
||||||
|
pub span: proc_macro2::Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExportInfo {
|
pub struct ExportInfo {
|
||||||
@ -46,6 +47,7 @@ pub fn parse_punctuated_items(
|
|||||||
|
|
||||||
let mut attrs: Vec<AttrItem> = Vec::new();
|
let mut attrs: Vec<AttrItem> = Vec::new();
|
||||||
for arg in arg_list {
|
for arg in arg_list {
|
||||||
|
let arg_span = arg.span();
|
||||||
let (key, value) = match arg {
|
let (key, value) = match arg {
|
||||||
syn::Expr::Assign(syn::ExprAssign {
|
syn::Expr::Assign(syn::ExprAssign {
|
||||||
ref left,
|
ref left,
|
||||||
@ -78,7 +80,7 @@ pub fn parse_punctuated_items(
|
|||||||
.ok_or_else(|| syn::Error::new(attr_path.span(), "expecting attribute name"))?,
|
.ok_or_else(|| syn::Error::new(attr_path.span(), "expecting attribute name"))?,
|
||||||
x => return Err(syn::Error::new(x.span(), "expecting identifier")),
|
x => return Err(syn::Error::new(x.span(), "expecting identifier")),
|
||||||
};
|
};
|
||||||
attrs.push(AttrItem { key, value });
|
attrs.push(AttrItem { key, value, span: arg_span });
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ExportInfo { item_span: list_span, items: attrs })
|
Ok(ExportInfo { item_span: list_span, items: attrs })
|
||||||
|
@ -17,24 +17,43 @@ use syn::{parse::Parse, parse::ParseStream, parse::Parser, spanned::Spanned};
|
|||||||
|
|
||||||
use crate::attrs::{ExportInfo, ExportScope, ExportedParams};
|
use crate::attrs::{ExportInfo, ExportScope, ExportedParams};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum Index {
|
||||||
|
Get,
|
||||||
|
Set,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum Property {
|
||||||
|
Get(syn::Ident),
|
||||||
|
Set(syn::Ident),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum FnSpecialAccess {
|
||||||
|
None,
|
||||||
|
Index(Index),
|
||||||
|
Property(Property),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FnSpecialAccess {
|
||||||
|
fn default() -> FnSpecialAccess {
|
||||||
|
FnSpecialAccess::None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(crate) struct ExportedFnParams {
|
pub(crate) struct ExportedFnParams {
|
||||||
pub name: Option<Vec<String>>,
|
pub name: Option<Vec<String>>,
|
||||||
pub return_raw: bool,
|
pub return_raw: bool,
|
||||||
pub skip: bool,
|
pub skip: bool,
|
||||||
pub span: Option<proc_macro2::Span>,
|
pub span: Option<proc_macro2::Span>,
|
||||||
|
pub special: FnSpecialAccess,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const FN_IDX_GET: &str = "index$get$";
|
pub const FN_IDX_GET: &str = "index$get$";
|
||||||
pub const FN_IDX_SET: &str = "index$set$";
|
pub const FN_IDX_SET: &str = "index$set$";
|
||||||
|
|
||||||
pub fn make_getter(id: &str) -> String {
|
|
||||||
format!("get${}", id)
|
|
||||||
}
|
|
||||||
pub fn make_setter(id: &str) -> String {
|
|
||||||
format!("set${}", id)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for ExportedFnParams {
|
impl Parse for ExportedFnParams {
|
||||||
fn parse(args: ParseStream) -> syn::Result<Self> {
|
fn parse(args: ParseStream) -> syn::Result<Self> {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
@ -63,26 +82,73 @@ impl ExportedParams for ExportedFnParams {
|
|||||||
let mut name = Vec::new();
|
let mut name = Vec::new();
|
||||||
let mut return_raw = false;
|
let mut return_raw = false;
|
||||||
let mut skip = false;
|
let mut skip = false;
|
||||||
|
let mut special = FnSpecialAccess::None;
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
let crate::attrs::AttrItem { key, value } = attr;
|
let crate::attrs::AttrItem { key, value, span: item_span } = attr;
|
||||||
match (key.to_string().as_ref(), value) {
|
match (key.to_string().as_ref(), value) {
|
||||||
("name", Some(s)) => {
|
|
||||||
// check validity of name
|
|
||||||
if s.value().contains('.') {
|
|
||||||
return Err(syn::Error::new(
|
|
||||||
s.span(),
|
|
||||||
"Rhai function names may not contain dot",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
name.push(s.value())
|
|
||||||
}
|
|
||||||
("get", Some(s)) => name.push(make_getter(&s.value())),
|
|
||||||
("set", Some(s)) => name.push(make_setter(&s.value())),
|
|
||||||
("get", None) | ("set", None) | ("name", None) => {
|
("get", None) | ("set", None) | ("name", None) => {
|
||||||
return Err(syn::Error::new(key.span(), "requires value"))
|
return Err(syn::Error::new(key.span(), "requires value"))
|
||||||
}
|
},
|
||||||
("index_get", None) => name.push(FN_IDX_GET.to_string()),
|
("name", Some(s)) if &s.value() == FN_IDX_GET => {
|
||||||
("index_set", None) => name.push(FN_IDX_SET.to_string()),
|
return Err(syn::Error::new(item_span,
|
||||||
|
"use attribute 'index_get' instead"))
|
||||||
|
},
|
||||||
|
("name", Some(s)) if &s.value() == FN_IDX_SET => {
|
||||||
|
return Err(syn::Error::new(item_span,
|
||||||
|
"use attribute 'index_set' instead"))
|
||||||
|
},
|
||||||
|
("name", Some(s)) if s.value().starts_with("get$") => {
|
||||||
|
return Err(syn::Error::new(item_span,
|
||||||
|
format!("use attribute 'getter = \"{}\"' instead",
|
||||||
|
&s.value()["get$".len()..])))
|
||||||
|
},
|
||||||
|
("name", Some(s)) if s.value().starts_with("set$") => {
|
||||||
|
return Err(syn::Error::new(item_span,
|
||||||
|
format!("use attribute 'setter = \"{}\"' instead",
|
||||||
|
&s.value()["set$".len()..])))
|
||||||
|
},
|
||||||
|
("name", Some(s)) if s.value().contains('$') => {
|
||||||
|
return Err(syn::Error::new(s.span(),
|
||||||
|
"Rhai function names may not contain dollar sign"))
|
||||||
|
},
|
||||||
|
("name", Some(s)) if s.value().contains('.') => {
|
||||||
|
return Err(syn::Error::new(s.span(),
|
||||||
|
"Rhai function names may not contain dot"))
|
||||||
|
},
|
||||||
|
("name", Some(s)) => {
|
||||||
|
name.push(s.value())
|
||||||
|
},
|
||||||
|
("set", Some(s)) => special = match special {
|
||||||
|
FnSpecialAccess::None =>
|
||||||
|
FnSpecialAccess::Property(Property::Set(syn::Ident::new(&s.value(),
|
||||||
|
s.span()))),
|
||||||
|
_ => {
|
||||||
|
return Err(syn::Error::new(item_span.span(), "conflicting setter"))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
("get", Some(s)) => special = match special {
|
||||||
|
FnSpecialAccess::None =>
|
||||||
|
FnSpecialAccess::Property(Property::Get(syn::Ident::new(&s.value(),
|
||||||
|
s.span()))),
|
||||||
|
_ => {
|
||||||
|
return Err(syn::Error::new(item_span.span(), "conflicting getter"))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
("index_get", None) => special = match special {
|
||||||
|
FnSpecialAccess::None =>
|
||||||
|
FnSpecialAccess::Index(Index::Get),
|
||||||
|
_ => {
|
||||||
|
return Err(syn::Error::new(item_span.span(), "conflicting index_get"))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
("index_set", None) => special = match special {
|
||||||
|
FnSpecialAccess::None =>
|
||||||
|
FnSpecialAccess::Index(Index::Set),
|
||||||
|
_ => {
|
||||||
|
return Err(syn::Error::new(item_span.span(), "conflicting index_set"))
|
||||||
|
}
|
||||||
|
},
|
||||||
("return_raw", None) => return_raw = true,
|
("return_raw", None) => return_raw = true,
|
||||||
("index_get", Some(s)) | ("index_set", Some(s)) | ("return_raw", Some(s)) => {
|
("index_get", Some(s)) | ("index_set", Some(s)) | ("return_raw", Some(s)) => {
|
||||||
return Err(syn::Error::new(s.span(), "extraneous value"))
|
return Err(syn::Error::new(s.span(), "extraneous value"))
|
||||||
@ -102,6 +168,7 @@ impl ExportedParams for ExportedFnParams {
|
|||||||
name: if name.is_empty() { None } else { Some(name) },
|
name: if name.is_empty() { None } else { Some(name) },
|
||||||
return_raw,
|
return_raw,
|
||||||
skip,
|
skip,
|
||||||
|
special,
|
||||||
span: Some(span),
|
span: Some(span),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
@ -259,6 +326,32 @@ impl ExportedFn {
|
|||||||
&self.signature.ident
|
&self.signature.ident
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn exported_names(&self) -> Vec<syn::LitStr> {
|
||||||
|
let mut literals = self.params.name.as_ref()
|
||||||
|
.map(|v| v.iter()
|
||||||
|
.map(|s| syn::LitStr::new(s, proc_macro2::Span::call_site())).collect())
|
||||||
|
.unwrap_or_else(|| Vec::new());
|
||||||
|
|
||||||
|
match self.params.special {
|
||||||
|
FnSpecialAccess::None => {},
|
||||||
|
FnSpecialAccess::Property(Property::Get(ref g)) =>
|
||||||
|
literals.push(syn::LitStr::new(&format!("get${}", g.to_string()), g.span())),
|
||||||
|
FnSpecialAccess::Property(Property::Set(ref s)) =>
|
||||||
|
literals.push(syn::LitStr::new(&format!("set${}", s.to_string()), s.span())),
|
||||||
|
FnSpecialAccess::Index(Index::Get) =>
|
||||||
|
literals.push(syn::LitStr::new(FN_IDX_GET, proc_macro2::Span::call_site())),
|
||||||
|
FnSpecialAccess::Index(Index::Set) =>
|
||||||
|
literals.push(syn::LitStr::new(FN_IDX_SET, proc_macro2::Span::call_site())),
|
||||||
|
}
|
||||||
|
|
||||||
|
if literals.is_empty() {
|
||||||
|
literals.push(syn::LitStr::new(&self.signature.ident.to_string(),
|
||||||
|
self.signature.ident.span()));
|
||||||
|
}
|
||||||
|
|
||||||
|
literals
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn exported_name<'n>(&'n self) -> Cow<'n, str> {
|
pub(crate) fn exported_name<'n>(&'n self) -> Cow<'n, str> {
|
||||||
if let Some(ref name) = self.params.name {
|
if let Some(ref name) = self.params.name {
|
||||||
Cow::Borrowed(name.last().unwrap().as_str())
|
Cow::Borrowed(name.last().unwrap().as_str())
|
||||||
@ -284,9 +377,11 @@ impl ExportedFn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_params(&mut self, mut params: ExportedFnParams) -> syn::Result<()> {
|
pub fn set_params(&mut self, mut params: ExportedFnParams) -> syn::Result<()> {
|
||||||
// Do not allow non-returning raw functions.
|
// Several issues are checked here to avoid issues with diagnostics caused by raising them
|
||||||
|
// later.
|
||||||
|
//
|
||||||
|
// 1. Do not allow non-returning raw functions.
|
||||||
//
|
//
|
||||||
// This is caught now to avoid issues with diagnostics later.
|
|
||||||
if params.return_raw
|
if params.return_raw
|
||||||
&& mem::discriminant(&self.signature.output)
|
&& mem::discriminant(&self.signature.output)
|
||||||
== mem::discriminant(&syn::ReturnType::Default)
|
== mem::discriminant(&syn::ReturnType::Default)
|
||||||
@ -297,6 +392,58 @@ impl ExportedFn {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match params.special {
|
||||||
|
// 2a. Property getters must take only the subject as an argument.
|
||||||
|
FnSpecialAccess::Property(Property::Get(_)) if self.arg_count() != 1 =>
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
self.signature.span(),
|
||||||
|
"property getter requires exactly 1 argument",
|
||||||
|
)),
|
||||||
|
// 2b. Property getters must return a value.
|
||||||
|
FnSpecialAccess::Property(Property::Get(_)) if self.return_type().is_none() =>
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
self.signature.span(),
|
||||||
|
"property getter must return a value"
|
||||||
|
)),
|
||||||
|
// 3a. Property setters must take the subject and a new value as arguments.
|
||||||
|
FnSpecialAccess::Property(Property::Set(_)) if self.arg_count() != 2 =>
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
self.signature.span(),
|
||||||
|
"property setter requires exactly 2 arguments",
|
||||||
|
)),
|
||||||
|
// 3b. Property setters must return nothing.
|
||||||
|
FnSpecialAccess::Property(Property::Set(_)) if self.return_type().is_some() =>
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
self.signature.span(),
|
||||||
|
"property setter must return no value"
|
||||||
|
)),
|
||||||
|
// 4a. Index getters must take the subject and the accessed "index" as arguments.
|
||||||
|
FnSpecialAccess::Index(Index::Get) if self.arg_count() != 2 =>
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
self.signature.span(),
|
||||||
|
"index getter requires exactly 2 arguments",
|
||||||
|
)),
|
||||||
|
// 4b. Index getters must return a value.
|
||||||
|
FnSpecialAccess::Index(Index::Get) if self.return_type().is_none() =>
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
self.signature.span(),
|
||||||
|
"index getter must return a value"
|
||||||
|
)),
|
||||||
|
// 5a. Index setters must take the subject, "index", and new value as arguments.
|
||||||
|
FnSpecialAccess::Index(Index::Set) if self.arg_count() != 3 =>
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
self.signature.span(),
|
||||||
|
"index setter requires exactly 3 arguments",
|
||||||
|
)),
|
||||||
|
// 5b. Index setters must return nothing.
|
||||||
|
FnSpecialAccess::Index(Index::Set) if self.return_type().is_some() =>
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
self.signature.span(),
|
||||||
|
"index setter must return no value"
|
||||||
|
)),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
self.params = params;
|
self.params = params;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ impl ExportedParams for ExportedModParams {
|
|||||||
let mut skip = false;
|
let mut skip = false;
|
||||||
let mut scope = ExportScope::default();
|
let mut scope = ExportScope::default();
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
let AttrItem { key, value } = attr;
|
let AttrItem { key, value, .. } = attr;
|
||||||
match (key.to_string().as_ref(), value) {
|
match (key.to_string().as_ref(), value) {
|
||||||
("name", Some(s)) => name = Some(s.value()),
|
("name", Some(s)) => name = Some(s.value()),
|
||||||
("name", None) => return Err(syn::Error::new(key.span(), "requires value")),
|
("name", None) => return Err(syn::Error::new(key.span(), "requires value")),
|
||||||
|
@ -67,11 +67,7 @@ pub(crate) fn generate_body(
|
|||||||
&format!("{}_token", function.name().to_string()),
|
&format!("{}_token", function.name().to_string()),
|
||||||
function.name().span(),
|
function.name().span(),
|
||||||
);
|
);
|
||||||
let reg_names = function
|
let reg_names = function.exported_names();
|
||||||
.params()
|
|
||||||
.name
|
|
||||||
.clone()
|
|
||||||
.unwrap_or_else(|| vec![function.name().to_string()]);
|
|
||||||
|
|
||||||
let fn_input_types: Vec<syn::Expr> = function
|
let fn_input_types: Vec<syn::Expr> = function
|
||||||
.arg_list()
|
.arg_list()
|
||||||
@ -110,9 +106,7 @@ pub(crate) fn generate_body(
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for reg_name in reg_names {
|
for fn_literal in reg_names {
|
||||||
let fn_literal = syn::LitStr::new(®_name, proc_macro2::Span::call_site());
|
|
||||||
|
|
||||||
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),*],
|
||||||
|
@ -538,6 +538,74 @@ mod generate_tests {
|
|||||||
assert_streams_eq(item_mod.generate(), expected_tokens);
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_double_rename_fn_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
#[rhai_fn(name = "add", name = "+", name = "add_together")]
|
||||||
|
pub fn add_together(x: INT, y: INT) -> INT {
|
||||||
|
x + y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
pub fn add_together(x: INT, y: INT) -> INT {
|
||||||
|
x + y
|
||||||
|
}
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
m.set_fn("add", FnAccess::Public, &[core::any::TypeId::of::<INT>(),
|
||||||
|
core::any::TypeId::of::<INT>()],
|
||||||
|
CallableFunction::from_plugin(add_together_token()));
|
||||||
|
m.set_fn("+", FnAccess::Public, &[core::any::TypeId::of::<INT>(),
|
||||||
|
core::any::TypeId::of::<INT>()],
|
||||||
|
CallableFunction::from_plugin(add_together_token()));
|
||||||
|
m.set_fn("add_together", FnAccess::Public, &[core::any::TypeId::of::<INT>(),
|
||||||
|
core::any::TypeId::of::<INT>()],
|
||||||
|
CallableFunction::from_plugin(add_together_token()));
|
||||||
|
m
|
||||||
|
}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct add_together_token();
|
||||||
|
impl PluginFunction for add_together_token {
|
||||||
|
fn call(&self,
|
||||||
|
args: &mut [&mut Dynamic], pos: Position
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
debug_assert_eq!(args.len(), 2usize,
|
||||||
|
"wrong arg count: {} != {}", args.len(), 2usize);
|
||||||
|
let arg0 = mem::take(args[0usize]).clone().cast::<INT>();
|
||||||
|
let arg1 = mem::take(args[1usize]).clone().cast::<INT>();
|
||||||
|
Ok(Dynamic::from(add_together(arg0, arg1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_method_call(&self) -> bool { false }
|
||||||
|
fn is_varadic(&self) -> bool { false }
|
||||||
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
|
Box::new(add_together_token())
|
||||||
|
}
|
||||||
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
|
new_vec![TypeId::of::<INT>(),
|
||||||
|
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<[TypeId]> {
|
||||||
|
add_together_token().input_types()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn one_constant_module() {
|
fn one_constant_module() {
|
||||||
let input_tokens: TokenStream = quote! {
|
let input_tokens: TokenStream = quote! {
|
||||||
@ -1004,6 +1072,521 @@ mod generate_tests {
|
|||||||
assert_streams_eq(item_mod.generate(), expected_tokens);
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_getter_fn_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
#[rhai_fn(get = "square")]
|
||||||
|
pub fn int_foo(x: &mut u64) -> u64 {
|
||||||
|
(*x) * (*x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
pub fn int_foo(x: &mut u64) -> u64 {
|
||||||
|
(*x) * (*x)
|
||||||
|
}
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
m.set_fn("get$square", FnAccess::Public, &[core::any::TypeId::of::<u64>()],
|
||||||
|
CallableFunction::from_plugin(int_foo_token()));
|
||||||
|
m
|
||||||
|
}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct int_foo_token();
|
||||||
|
impl PluginFunction for int_foo_token {
|
||||||
|
fn call(&self,
|
||||||
|
args: &mut [&mut Dynamic], pos: Position
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
debug_assert_eq!(args.len(), 1usize,
|
||||||
|
"wrong arg count: {} != {}", args.len(), 1usize);
|
||||||
|
let arg0: &mut _ = &mut args[0usize].write_lock::<u64>().unwrap();
|
||||||
|
Ok(Dynamic::from(int_foo(arg0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_method_call(&self) -> bool { true }
|
||||||
|
fn is_varadic(&self) -> bool { false }
|
||||||
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
|
Box::new(int_foo_token())
|
||||||
|
}
|
||||||
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
|
new_vec![TypeId::of::<u64>()].into_boxed_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn int_foo_token_callable() -> CallableFunction {
|
||||||
|
CallableFunction::from_plugin(int_foo_token())
|
||||||
|
}
|
||||||
|
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
||||||
|
int_foo_token().input_types()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_getter_and_rename_fn_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
#[rhai_fn(name = "square", get = "square")]
|
||||||
|
pub fn int_foo(x: &mut u64) -> u64 {
|
||||||
|
(*x) * (*x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
pub fn int_foo(x: &mut u64) -> u64 {
|
||||||
|
(*x) * (*x)
|
||||||
|
}
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
m.set_fn("square", FnAccess::Public, &[core::any::TypeId::of::<u64>()],
|
||||||
|
CallableFunction::from_plugin(int_foo_token()));
|
||||||
|
m.set_fn("get$square", FnAccess::Public, &[core::any::TypeId::of::<u64>()],
|
||||||
|
CallableFunction::from_plugin(int_foo_token()));
|
||||||
|
m
|
||||||
|
}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct int_foo_token();
|
||||||
|
impl PluginFunction for int_foo_token {
|
||||||
|
fn call(&self,
|
||||||
|
args: &mut [&mut Dynamic], pos: Position
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
debug_assert_eq!(args.len(), 1usize,
|
||||||
|
"wrong arg count: {} != {}", args.len(), 1usize);
|
||||||
|
let arg0: &mut _ = &mut args[0usize].write_lock::<u64>().unwrap();
|
||||||
|
Ok(Dynamic::from(int_foo(arg0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_method_call(&self) -> bool { true }
|
||||||
|
fn is_varadic(&self) -> bool { false }
|
||||||
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
|
Box::new(int_foo_token())
|
||||||
|
}
|
||||||
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
|
new_vec![TypeId::of::<u64>()].into_boxed_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn int_foo_token_callable() -> CallableFunction {
|
||||||
|
CallableFunction::from_plugin(int_foo_token())
|
||||||
|
}
|
||||||
|
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
||||||
|
int_foo_token().input_types()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_setter_fn_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
#[rhai_fn(set = "squared")]
|
||||||
|
pub fn int_foo(x: &mut u64, y: u64) {
|
||||||
|
*x = y * y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
pub fn int_foo(x: &mut u64, y: u64) {
|
||||||
|
*x = y * y
|
||||||
|
}
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
m.set_fn("set$squared", FnAccess::Public,
|
||||||
|
&[core::any::TypeId::of::<u64>(),
|
||||||
|
core::any::TypeId::of::<u64>()],
|
||||||
|
CallableFunction::from_plugin(int_foo_token()));
|
||||||
|
m
|
||||||
|
}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct int_foo_token();
|
||||||
|
impl PluginFunction for int_foo_token {
|
||||||
|
fn call(&self,
|
||||||
|
args: &mut [&mut Dynamic], pos: Position
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
debug_assert_eq!(args.len(), 2usize,
|
||||||
|
"wrong arg count: {} != {}", args.len(), 2usize);
|
||||||
|
let arg1 = mem::take(args[1usize]).clone().cast::<u64>();
|
||||||
|
let arg0: &mut _ = &mut args[0usize].write_lock::<u64>().unwrap();
|
||||||
|
Ok(Dynamic::from(int_foo(arg0, arg1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_method_call(&self) -> bool { true }
|
||||||
|
fn is_varadic(&self) -> bool { false }
|
||||||
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
|
Box::new(int_foo_token())
|
||||||
|
}
|
||||||
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
|
new_vec![TypeId::of::<u64>(), TypeId::of::<u64>()].into_boxed_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn int_foo_token_callable() -> CallableFunction {
|
||||||
|
CallableFunction::from_plugin(int_foo_token())
|
||||||
|
}
|
||||||
|
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
||||||
|
int_foo_token().input_types()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_setter_and_rename_fn_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
#[rhai_fn(name = "set_sq", set = "squared")]
|
||||||
|
pub fn int_foo(x: &mut u64, y: u64) {
|
||||||
|
*x = y * y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
pub mod one_fn {
|
||||||
|
pub fn int_foo(x: &mut u64, y: u64) {
|
||||||
|
*x = y * y
|
||||||
|
}
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
m.set_fn("set_sq", FnAccess::Public,
|
||||||
|
&[core::any::TypeId::of::<u64>(),
|
||||||
|
core::any::TypeId::of::<u64>()],
|
||||||
|
CallableFunction::from_plugin(int_foo_token()));
|
||||||
|
m.set_fn("set$squared", FnAccess::Public,
|
||||||
|
&[core::any::TypeId::of::<u64>(),
|
||||||
|
core::any::TypeId::of::<u64>()],
|
||||||
|
CallableFunction::from_plugin(int_foo_token()));
|
||||||
|
m
|
||||||
|
}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct int_foo_token();
|
||||||
|
impl PluginFunction for int_foo_token {
|
||||||
|
fn call(&self,
|
||||||
|
args: &mut [&mut Dynamic], pos: Position
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
debug_assert_eq!(args.len(), 2usize,
|
||||||
|
"wrong arg count: {} != {}", args.len(), 2usize);
|
||||||
|
let arg1 = mem::take(args[1usize]).clone().cast::<u64>();
|
||||||
|
let arg0: &mut _ = &mut args[0usize].write_lock::<u64>().unwrap();
|
||||||
|
Ok(Dynamic::from(int_foo(arg0, arg1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_method_call(&self) -> bool { true }
|
||||||
|
fn is_varadic(&self) -> bool { false }
|
||||||
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
|
Box::new(int_foo_token())
|
||||||
|
}
|
||||||
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
|
new_vec![TypeId::of::<u64>(), TypeId::of::<u64>()].into_boxed_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn int_foo_token_callable() -> CallableFunction {
|
||||||
|
CallableFunction::from_plugin(int_foo_token())
|
||||||
|
}
|
||||||
|
pub fn int_foo_token_input_types() -> Box<[TypeId]> {
|
||||||
|
int_foo_token().input_types()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_index_getter_fn_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_index_fn {
|
||||||
|
#[rhai_fn(index_get)]
|
||||||
|
pub fn get_by_index(x: &mut MyCollection, i: u64) -> FLOAT {
|
||||||
|
x.get(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
pub mod one_index_fn {
|
||||||
|
pub fn get_by_index(x: &mut MyCollection, i: u64) -> FLOAT {
|
||||||
|
x.get(i)
|
||||||
|
}
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
m.set_fn("index$get$", FnAccess::Public,
|
||||||
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
|
core::any::TypeId::of::<u64>()],
|
||||||
|
CallableFunction::from_plugin(get_by_index_token()));
|
||||||
|
m
|
||||||
|
}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct get_by_index_token();
|
||||||
|
impl PluginFunction for get_by_index_token {
|
||||||
|
fn call(&self,
|
||||||
|
args: &mut [&mut Dynamic], pos: Position
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
debug_assert_eq!(args.len(), 2usize,
|
||||||
|
"wrong arg count: {} != {}", args.len(), 2usize);
|
||||||
|
let arg1 = mem::take(args[1usize]).clone().cast::<u64>();
|
||||||
|
let arg0: &mut _ = &mut args[0usize].write_lock::<MyCollection>().unwrap();
|
||||||
|
Ok(Dynamic::from(get_by_index(arg0, arg1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_method_call(&self) -> bool { true }
|
||||||
|
fn is_varadic(&self) -> bool { false }
|
||||||
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
|
Box::new(get_by_index_token())
|
||||||
|
}
|
||||||
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
|
new_vec![TypeId::of::<MyCollection>(),
|
||||||
|
TypeId::of::<u64>()].into_boxed_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn get_by_index_token_callable() -> CallableFunction {
|
||||||
|
CallableFunction::from_plugin(get_by_index_token())
|
||||||
|
}
|
||||||
|
pub fn get_by_index_token_input_types() -> Box<[TypeId]> {
|
||||||
|
get_by_index_token().input_types()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_index_getter_and_rename_fn_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_index_fn {
|
||||||
|
#[rhai_fn(name = "get", index_get)]
|
||||||
|
pub fn get_by_index(x: &mut MyCollection, i: u64) -> FLOAT {
|
||||||
|
x.get(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
pub mod one_index_fn {
|
||||||
|
pub fn get_by_index(x: &mut MyCollection, i: u64) -> FLOAT {
|
||||||
|
x.get(i)
|
||||||
|
}
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
m.set_fn("get", FnAccess::Public,
|
||||||
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
|
core::any::TypeId::of::<u64>()],
|
||||||
|
CallableFunction::from_plugin(get_by_index_token()));
|
||||||
|
m.set_fn("index$get$", FnAccess::Public,
|
||||||
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
|
core::any::TypeId::of::<u64>()],
|
||||||
|
CallableFunction::from_plugin(get_by_index_token()));
|
||||||
|
m
|
||||||
|
}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct get_by_index_token();
|
||||||
|
impl PluginFunction for get_by_index_token {
|
||||||
|
fn call(&self,
|
||||||
|
args: &mut [&mut Dynamic], pos: Position
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
debug_assert_eq!(args.len(), 2usize,
|
||||||
|
"wrong arg count: {} != {}", args.len(), 2usize);
|
||||||
|
let arg1 = mem::take(args[1usize]).clone().cast::<u64>();
|
||||||
|
let arg0: &mut _ = &mut args[0usize].write_lock::<MyCollection>().unwrap();
|
||||||
|
Ok(Dynamic::from(get_by_index(arg0, arg1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_method_call(&self) -> bool { true }
|
||||||
|
fn is_varadic(&self) -> bool { false }
|
||||||
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
|
Box::new(get_by_index_token())
|
||||||
|
}
|
||||||
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
|
new_vec![TypeId::of::<MyCollection>(),
|
||||||
|
TypeId::of::<u64>()].into_boxed_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn get_by_index_token_callable() -> CallableFunction {
|
||||||
|
CallableFunction::from_plugin(get_by_index_token())
|
||||||
|
}
|
||||||
|
pub fn get_by_index_token_input_types() -> Box<[TypeId]> {
|
||||||
|
get_by_index_token().input_types()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_index_setter_fn_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_index_fn {
|
||||||
|
#[rhai_fn(index_set)]
|
||||||
|
pub fn set_by_index(x: &mut MyCollection, i: u64, item: FLOAT) {
|
||||||
|
x.entry(i).set(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
pub mod one_index_fn {
|
||||||
|
pub fn set_by_index(x: &mut MyCollection, i: u64, item: FLOAT) {
|
||||||
|
x.entry(i).set(item)
|
||||||
|
}
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
m.set_fn("index$set$", FnAccess::Public,
|
||||||
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
|
core::any::TypeId::of::<u64>(),
|
||||||
|
core::any::TypeId::of::<FLOAT>()],
|
||||||
|
CallableFunction::from_plugin(set_by_index_token()));
|
||||||
|
m
|
||||||
|
}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct set_by_index_token();
|
||||||
|
impl PluginFunction for set_by_index_token {
|
||||||
|
fn call(&self,
|
||||||
|
args: &mut [&mut Dynamic], pos: Position
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
debug_assert_eq!(args.len(), 3usize,
|
||||||
|
"wrong arg count: {} != {}", args.len(), 3usize);
|
||||||
|
let arg1 = mem::take(args[1usize]).clone().cast::<u64>();
|
||||||
|
let arg2 = mem::take(args[2usize]).clone().cast::<FLOAT>();
|
||||||
|
let arg0: &mut _ = &mut args[0usize].write_lock::<MyCollection>().unwrap();
|
||||||
|
Ok(Dynamic::from(set_by_index(arg0, arg1, arg2)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_method_call(&self) -> bool { true }
|
||||||
|
fn is_varadic(&self) -> bool { false }
|
||||||
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
|
Box::new(set_by_index_token())
|
||||||
|
}
|
||||||
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
|
new_vec![TypeId::of::<MyCollection>(),
|
||||||
|
TypeId::of::<u64>(),
|
||||||
|
TypeId::of::<FLOAT>()].into_boxed_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn set_by_index_token_callable() -> CallableFunction {
|
||||||
|
CallableFunction::from_plugin(set_by_index_token())
|
||||||
|
}
|
||||||
|
pub fn set_by_index_token_input_types() -> Box<[TypeId]> {
|
||||||
|
set_by_index_token().input_types()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_index_setter_and_rename_fn_module() {
|
||||||
|
let input_tokens: TokenStream = quote! {
|
||||||
|
pub mod one_index_fn {
|
||||||
|
#[rhai_fn(name = "set", index_set)]
|
||||||
|
pub fn set_by_index(x: &mut MyCollection, i: u64, item: FLOAT) {
|
||||||
|
x.entry(i).set(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let expected_tokens = quote! {
|
||||||
|
pub mod one_index_fn {
|
||||||
|
pub fn set_by_index(x: &mut MyCollection, i: u64, item: FLOAT) {
|
||||||
|
x.entry(i).set(item)
|
||||||
|
}
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
m.set_fn("set", FnAccess::Public,
|
||||||
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
|
core::any::TypeId::of::<u64>(),
|
||||||
|
core::any::TypeId::of::<FLOAT>()],
|
||||||
|
CallableFunction::from_plugin(set_by_index_token()));
|
||||||
|
m.set_fn("index$set$", FnAccess::Public,
|
||||||
|
&[core::any::TypeId::of::<MyCollection>(),
|
||||||
|
core::any::TypeId::of::<u64>(),
|
||||||
|
core::any::TypeId::of::<FLOAT>()],
|
||||||
|
CallableFunction::from_plugin(set_by_index_token()));
|
||||||
|
m
|
||||||
|
}
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct set_by_index_token();
|
||||||
|
impl PluginFunction for set_by_index_token {
|
||||||
|
fn call(&self,
|
||||||
|
args: &mut [&mut Dynamic], pos: Position
|
||||||
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
debug_assert_eq!(args.len(), 3usize,
|
||||||
|
"wrong arg count: {} != {}", args.len(), 3usize);
|
||||||
|
let arg1 = mem::take(args[1usize]).clone().cast::<u64>();
|
||||||
|
let arg2 = mem::take(args[2usize]).clone().cast::<FLOAT>();
|
||||||
|
let arg0: &mut _ = &mut args[0usize].write_lock::<MyCollection>().unwrap();
|
||||||
|
Ok(Dynamic::from(set_by_index(arg0, arg1, arg2)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_method_call(&self) -> bool { true }
|
||||||
|
fn is_varadic(&self) -> bool { false }
|
||||||
|
fn clone_boxed(&self) -> Box<dyn PluginFunction> {
|
||||||
|
Box::new(set_by_index_token())
|
||||||
|
}
|
||||||
|
fn input_types(&self) -> Box<[TypeId]> {
|
||||||
|
new_vec![TypeId::of::<MyCollection>(),
|
||||||
|
TypeId::of::<u64>(),
|
||||||
|
TypeId::of::<FLOAT>()].into_boxed_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn set_by_index_token_callable() -> CallableFunction {
|
||||||
|
CallableFunction::from_plugin(set_by_index_token())
|
||||||
|
}
|
||||||
|
pub fn set_by_index_token_input_types() -> Box<[TypeId]> {
|
||||||
|
set_by_index_token().input_types()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_mod = syn::parse2::<Module>(input_tokens).unwrap();
|
||||||
|
assert_streams_eq(item_mod.generate(), expected_tokens);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn one_constant_nested_module() {
|
fn one_constant_nested_module() {
|
||||||
let input_tokens: TokenStream = quote! {
|
let input_tokens: TokenStream = quote! {
|
||||||
|
@ -4,8 +4,8 @@ error: unknown attribute 'unknown'
|
|||||||
11 | #[rhai_fn(unknown = "thing")]
|
11 | #[rhai_fn(unknown = "thing")]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_mod`
|
||||||
--> $DIR/export_mod_bad_attr.rs:22:8
|
--> $DIR/export_mod_bad_attr.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_mod::test_fn(n) {
|
22 | if test_mod::test_fn(n) {
|
||||||
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
| ^^^^^^^^ use of undeclared crate or module `test_mod`
|
||||||
|
@ -4,8 +4,8 @@ error: expecting string literal
|
|||||||
11 | #[rhai_fn(name = true)]
|
11 | #[rhai_fn(name = true)]
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_mod`
|
||||||
--> $DIR/export_mod_bad_value.rs:22:8
|
--> $DIR/export_mod_bad_value.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_mod::test_fn(n) {
|
22 | if test_mod::test_fn(n) {
|
||||||
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
| ^^^^^^^^ use of undeclared crate or module `test_mod`
|
||||||
|
@ -4,8 +4,8 @@ error: cfg attributes not allowed on this item
|
|||||||
11 | #[cfg(not(feature = "foo"))]
|
11 | #[cfg(not(feature = "foo"))]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_mod`
|
||||||
--> $DIR/export_mod_cfg.rs:23:8
|
--> $DIR/export_mod_cfg.rs:23:8
|
||||||
|
|
|
|
||||||
23 | if test_mod::test_fn(n) {
|
23 | if test_mod::test_fn(n) {
|
||||||
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
| ^^^^^^^^ use of undeclared crate or module `test_mod`
|
||||||
|
@ -4,8 +4,8 @@ error: extraneous value
|
|||||||
11 | #[rhai_fn(return_raw = "yes")]
|
11 | #[rhai_fn(return_raw = "yes")]
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_mod`
|
||||||
--> $DIR/export_mod_extra_value.rs:22:8
|
--> $DIR/export_mod_extra_value.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_mod::test_fn(n) {
|
22 | if test_mod::test_fn(n) {
|
||||||
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
| ^^^^^^^^ use of undeclared crate or module `test_mod`
|
||||||
|
@ -4,8 +4,8 @@ error: expecting identifier
|
|||||||
11 | #[rhai_fn("wheeeee")]
|
11 | #[rhai_fn("wheeeee")]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_mod`
|
||||||
--> $DIR/export_mod_junk_arg.rs:22:8
|
--> $DIR/export_mod_junk_arg.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_mod::test_fn(n) {
|
22 | if test_mod::test_fn(n) {
|
||||||
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
| ^^^^^^^^ use of undeclared crate or module `test_mod`
|
||||||
|
@ -4,8 +4,8 @@ error: requires value
|
|||||||
11 | #[rhai_fn(name)]
|
11 | #[rhai_fn(name)]
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_mod`
|
||||||
--> $DIR/export_mod_missing_value.rs:22:8
|
--> $DIR/export_mod_missing_value.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_mod::test_fn(n) {
|
22 | if test_mod::test_fn(n) {
|
||||||
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
| ^^^^^^^^ use of undeclared crate or module `test_mod`
|
||||||
|
@ -4,8 +4,8 @@ error: expecting attribute name
|
|||||||
11 | #[rhai_fn(rhai::name = "thing")]
|
11 | #[rhai_fn(rhai::name = "thing")]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_mod`
|
||||||
--> $DIR/export_mod_path_attr.rs:22:8
|
--> $DIR/export_mod_path_attr.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_mod::test_fn(n) {
|
22 | if test_mod::test_fn(n) {
|
||||||
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
| ^^^^^^^^ use of undeclared crate or module `test_mod`
|
||||||
|
@ -4,8 +4,8 @@ error: return_raw functions must return Result<T>
|
|||||||
12 | pub fn test_fn(input: &mut Point) {
|
12 | pub fn test_fn(input: &mut Point) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_mod`
|
||||||
--> $DIR/export_mod_raw_noreturn.rs:22:5
|
--> $DIR/export_mod_raw_noreturn.rs:22:5
|
||||||
|
|
|
|
||||||
22 | test_mod::test_fn(&mut n);
|
22 | test_mod::test_fn(&mut n);
|
||||||
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
| ^^^^^^^^ use of undeclared crate or module `test_mod`
|
||||||
|
@ -4,8 +4,8 @@ error: cfg attributes not allowed on this item
|
|||||||
13 | #[cfg(feature = "foo")]
|
13 | #[cfg(feature = "foo")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/module_cfg_const.rs:26:8
|
--> $DIR/module_cfg_const.rs:26:8
|
||||||
|
|
|
|
||||||
26 | if test_module::test_fn(n) {
|
26 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: cfg attributes not allowed on this item
|
|||||||
11 | #[cfg(not(feature = "foo"))]
|
11 | #[cfg(not(feature = "foo"))]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/module_cfg_fn.rs:22:8
|
--> $DIR/module_cfg_fn.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_module::test_fn(n) {
|
22 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: unknown attribute 'unknown'
|
|||||||
11 | #[rhai_fn(unknown = "thing")]
|
11 | #[rhai_fn(unknown = "thing")]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_bad_attr.rs:22:8
|
--> $DIR/rhai_fn_bad_attr.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_module::test_fn(n) {
|
22 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: expecting string literal
|
|||||||
11 | #[rhai_fn(name = true)]
|
11 | #[rhai_fn(name = true)]
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_bad_value.rs:22:8
|
--> $DIR/rhai_fn_bad_value.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_module::test_fn(n) {
|
22 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: extraneous value
|
|||||||
11 | #[rhai_fn(return_raw = "yes")]
|
11 | #[rhai_fn(return_raw = "yes")]
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_extra_value.rs:22:8
|
--> $DIR/rhai_fn_extra_value.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_module::test_fn(n) {
|
22 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
28
codegen/ui_tests/rhai_fn_getter_conflict.rs
Normal file
28
codegen/ui_tests/rhai_fn_getter_conflict.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "foo", get = "foo", set = "bar")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_getter_conflict.stderr
Normal file
11
codegen/ui_tests/rhai_fn_getter_conflict.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: conflicting setter
|
||||||
|
--> $DIR/rhai_fn_getter_conflict.rs:12:42
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "foo", get = "foo", set = "bar")]
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_getter_conflict.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_getter_multiple.rs
Normal file
28
codegen/ui_tests/rhai_fn_getter_multiple.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "foo", get = "foo", get = "bar")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_getter_multiple.stderr
Normal file
11
codegen/ui_tests/rhai_fn_getter_multiple.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: conflicting getter
|
||||||
|
--> $DIR/rhai_fn_getter_multiple.rs:12:42
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "foo", get = "foo", get = "bar")]
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_getter_multiple.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
29
codegen/ui_tests/rhai_fn_getter_return.rs
Normal file
29
codegen/ui_tests/rhai_fn_getter_return.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(get = "foo")]
|
||||||
|
pub fn test_fn(input: &mut Point) {
|
||||||
|
input.x *= 2.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
test_module::test_fn(&mut n);
|
||||||
|
if n.x > 10.0 {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_getter_return.stderr
Normal file
11
codegen/ui_tests/rhai_fn_getter_return.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: property getter must return a value
|
||||||
|
--> $DIR/rhai_fn_getter_return.rs:13:9
|
||||||
|
|
|
||||||
|
13 | pub fn test_fn(input: &mut Point) {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_getter_return.rs:23:5
|
||||||
|
|
|
||||||
|
23 | test_module::test_fn(&mut n);
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_getter_signature.rs
Normal file
28
codegen/ui_tests/rhai_fn_getter_signature.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(get = "foo")]
|
||||||
|
pub fn test_fn(input: Point, value: bool) -> bool {
|
||||||
|
value && input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n, true) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_getter_signature.stderr
Normal file
11
codegen/ui_tests/rhai_fn_getter_signature.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: property getter requires exactly 1 argument
|
||||||
|
--> $DIR/rhai_fn_getter_signature.rs:13:9
|
||||||
|
|
|
||||||
|
13 | pub fn test_fn(input: Point, value: bool) -> bool {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_getter_signature.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n, true) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_index_getter_multiple.rs
Normal file
28
codegen/ui_tests/rhai_fn_index_getter_multiple.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "foo", index_get, index_get)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_index_getter_multiple.stderr
Normal file
11
codegen/ui_tests/rhai_fn_index_getter_multiple.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: conflicting index_get
|
||||||
|
--> $DIR/rhai_fn_index_getter_multiple.rs:12:40
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "foo", index_get, index_get)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_index_getter_multiple.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_index_getter_return.rs
Normal file
28
codegen/ui_tests/rhai_fn_index_getter_return.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(index_get)]
|
||||||
|
pub fn test_fn(input: &mut Point, i: f32) {
|
||||||
|
input.x *= 2.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(&mut n, 5.0) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_index_getter_return.stderr
Normal file
11
codegen/ui_tests/rhai_fn_index_getter_return.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: index getter must return a value
|
||||||
|
--> $DIR/rhai_fn_index_getter_return.rs:13:9
|
||||||
|
|
|
||||||
|
13 | pub fn test_fn(input: &mut Point, i: f32) {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_index_getter_return.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(&mut n, 5.0) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_index_getter_signature.rs
Normal file
28
codegen/ui_tests/rhai_fn_index_getter_signature.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(index_get)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_index_getter_signature.stderr
Normal file
11
codegen/ui_tests/rhai_fn_index_getter_signature.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: index getter requires exactly 2 arguments
|
||||||
|
--> $DIR/rhai_fn_index_getter_signature.rs:13:9
|
||||||
|
|
|
||||||
|
13 | pub fn test_fn(input: Point) -> bool {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_index_getter_signature.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_index_setter_multiple.rs
Normal file
28
codegen/ui_tests/rhai_fn_index_setter_multiple.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "foo", index_set, index_set)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_index_setter_multiple.stderr
Normal file
11
codegen/ui_tests/rhai_fn_index_setter_multiple.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: conflicting index_set
|
||||||
|
--> $DIR/rhai_fn_index_setter_multiple.rs:12:40
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "foo", index_set, index_set)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_index_setter_multiple.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
@ -4,8 +4,8 @@ error: expecting identifier
|
|||||||
11 | #[rhai_fn("wheeeee")]
|
11 | #[rhai_fn("wheeeee")]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_junk_arg.rs:22:8
|
--> $DIR/rhai_fn_junk_arg.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_module::test_fn(n) {
|
22 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: requires value
|
|||||||
11 | #[rhai_fn(name)]
|
11 | #[rhai_fn(name)]
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_missing_value.rs:22:8
|
--> $DIR/rhai_fn_missing_value.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_module::test_fn(n) {
|
22 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: expecting attribute name
|
|||||||
11 | #[rhai_fn(rhai::name = "thing")]
|
11 | #[rhai_fn(rhai::name = "thing")]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_path_attr.rs:22:8
|
--> $DIR/rhai_fn_path_attr.rs:22:8
|
||||||
|
|
|
|
||||||
22 | if test_module::test_fn(n) {
|
22 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -10,8 +10,8 @@ error: duplicated function renamed 'foo'
|
|||||||
12 | #[rhai_fn(name = "foo")]
|
12 | #[rhai_fn(name = "foo")]
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_rename_collision.rs:28:8
|
--> $DIR/rhai_fn_rename_collision.rs:28:8
|
||||||
|
|
|
|
||||||
28 | if test_module::test_fn(n) {
|
28 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -10,8 +10,8 @@ error: duplicated function 'foo'
|
|||||||
17 | pub fn foo(input: Point) -> bool {
|
17 | pub fn foo(input: Point) -> bool {
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_rename_collision_oneattr.rs:27:8
|
--> $DIR/rhai_fn_rename_collision_oneattr.rs:27:8
|
||||||
|
|
|
|
||||||
27 | if test_module::test_fn(n) {
|
27 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
error: duplicate Rhai signature for 'get$bar'
|
error: duplicate Rhai signature for 'foo'
|
||||||
--> $DIR/rhai_fn_rename_collision_oneattr_multiple.rs:17:15
|
|
||||||
|
|
|
||||||
17 | #[rhai_fn(get = "bar")]
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: duplicated function renamed 'get$bar'
|
|
||||||
--> $DIR/rhai_fn_rename_collision_oneattr_multiple.rs:12:15
|
--> $DIR/rhai_fn_rename_collision_oneattr_multiple.rs:12:15
|
||||||
|
|
|
|
||||||
12 | #[rhai_fn(name = "foo", get = "bar")]
|
12 | #[rhai_fn(name = "foo", get = "bar")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error: duplicated function 'foo'
|
||||||
|
--> $DIR/rhai_fn_rename_collision_oneattr_multiple.rs:18:12
|
||||||
|
|
|
||||||
|
18 | pub fn foo(input: Point) -> bool {
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_rename_collision_oneattr_multiple.rs:25:8
|
--> $DIR/rhai_fn_rename_collision_oneattr_multiple.rs:25:8
|
||||||
|
|
|
|
||||||
25 | if test_module::test_fn(n) {
|
25 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -10,8 +10,8 @@ error: duplicated function renamed 'foo'
|
|||||||
12 | #[rhai_fn(name = "foo", name = "bar", name = "foo")]
|
12 | #[rhai_fn(name = "foo", name = "bar", name = "foo")]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_rename_collision_with_itself.rs:20:8
|
--> $DIR/rhai_fn_rename_collision_with_itself.rs:20:8
|
||||||
|
|
|
|
||||||
20 | if test_module::test_fn(n) {
|
20 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
28
codegen/ui_tests/rhai_fn_rename_dollar_sign.rs
Normal file
28
codegen/ui_tests/rhai_fn_rename_dollar_sign.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "big$caching")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_rename_dollar_sign.stderr
Normal file
11
codegen/ui_tests/rhai_fn_rename_dollar_sign.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: Rhai function names may not contain dollar sign
|
||||||
|
--> $DIR/rhai_fn_rename_dollar_sign.rs:12:22
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "big$caching")]
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_rename_dollar_sign.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
@ -4,8 +4,8 @@ error: Rhai function names may not contain dot
|
|||||||
12 | #[rhai_fn(name = "foo.bar")]
|
12 | #[rhai_fn(name = "foo.bar")]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_fn_rename_dot.rs:23:8
|
--> $DIR/rhai_fn_rename_dot.rs:23:8
|
||||||
|
|
|
|
||||||
23 | if test_module::test_fn(n) {
|
23 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
28
codegen/ui_tests/rhai_fn_rename_to_index_getter.rs
Normal file
28
codegen/ui_tests/rhai_fn_rename_to_index_getter.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "index$get$")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_rename_to_index_getter.stderr
Normal file
11
codegen/ui_tests/rhai_fn_rename_to_index_getter.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: use attribute 'index_get' instead
|
||||||
|
--> $DIR/rhai_fn_rename_to_index_getter.rs:12:15
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "index$get$")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_rename_to_index_getter.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_rename_to_index_setter.rs
Normal file
28
codegen/ui_tests/rhai_fn_rename_to_index_setter.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "index$set$")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_rename_to_index_setter.stderr
Normal file
11
codegen/ui_tests/rhai_fn_rename_to_index_setter.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: use attribute 'index_set' instead
|
||||||
|
--> $DIR/rhai_fn_rename_to_index_setter.rs:12:15
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "index$set$")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_rename_to_index_setter.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_rename_to_prop_getter.rs
Normal file
28
codegen/ui_tests/rhai_fn_rename_to_prop_getter.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "get$foo")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_rename_to_prop_getter.stderr
Normal file
11
codegen/ui_tests/rhai_fn_rename_to_prop_getter.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: use attribute 'getter = "foo"' instead
|
||||||
|
--> $DIR/rhai_fn_rename_to_prop_getter.rs:12:15
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "get$foo")]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_rename_to_prop_getter.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_rename_to_prop_setter.rs
Normal file
28
codegen/ui_tests/rhai_fn_rename_to_prop_setter.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "get$foo")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_rename_to_prop_setter.stderr
Normal file
11
codegen/ui_tests/rhai_fn_rename_to_prop_setter.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: use attribute 'getter = "foo"' instead
|
||||||
|
--> $DIR/rhai_fn_rename_to_prop_setter.rs:12:15
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "get$foo")]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_rename_to_prop_setter.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_setter_index_signature.rs
Normal file
28
codegen/ui_tests/rhai_fn_setter_index_signature.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(index_set)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_setter_index_signature.stderr
Normal file
11
codegen/ui_tests/rhai_fn_setter_index_signature.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: index setter requires exactly 3 arguments
|
||||||
|
--> $DIR/rhai_fn_setter_index_signature.rs:13:9
|
||||||
|
|
|
||||||
|
13 | pub fn test_fn(input: Point) -> bool {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_setter_index_signature.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_setter_multiple.rs
Normal file
28
codegen/ui_tests/rhai_fn_setter_multiple.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "foo", set = "foo", set = "bar")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_setter_multiple.stderr
Normal file
11
codegen/ui_tests/rhai_fn_setter_multiple.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: conflicting setter
|
||||||
|
--> $DIR/rhai_fn_setter_multiple.rs:12:42
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "foo", set = "foo", set = "bar")]
|
||||||
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_setter_multiple.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
29
codegen/ui_tests/rhai_fn_setter_return.rs
Normal file
29
codegen/ui_tests/rhai_fn_setter_return.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(set = "foo")]
|
||||||
|
pub fn test_fn(input: &mut Point, value: f32) -> bool {
|
||||||
|
let z = if value % 2 { input.x } else { input.y };
|
||||||
|
*input.x = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(&mut n, 5.0) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_setter_return.stderr
Normal file
11
codegen/ui_tests/rhai_fn_setter_return.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: property setter must return no value
|
||||||
|
--> $DIR/rhai_fn_setter_return.rs:13:9
|
||||||
|
|
|
||||||
|
13 | pub fn test_fn(input: &mut Point, value: f32) -> bool {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_setter_return.rs:24:8
|
||||||
|
|
|
||||||
|
24 | if test_module::test_fn(&mut n, 5.0) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
28
codegen/ui_tests/rhai_fn_setter_signature.rs
Normal file
28
codegen/ui_tests/rhai_fn_setter_signature.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(set = "foo")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_setter_signature.stderr
Normal file
11
codegen/ui_tests/rhai_fn_setter_signature.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: property setter requires exactly 2 arguments
|
||||||
|
--> $DIR/rhai_fn_setter_signature.rs:13:9
|
||||||
|
|
|
||||||
|
13 | pub fn test_fn(input: Point) -> bool {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_setter_signature.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
@ -4,8 +4,8 @@ error: unknown attribute 'unknown'
|
|||||||
11 | #[rhai_mod(unknown = "thing")]
|
11 | #[rhai_mod(unknown = "thing")]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_mod_bad_attr.rs:24:8
|
--> $DIR/rhai_mod_bad_attr.rs:24:8
|
||||||
|
|
|
|
||||||
24 | if test_module::test_fn(n) {
|
24 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: expecting string literal
|
|||||||
11 | #[rhai_mod(name = true)]
|
11 | #[rhai_mod(name = true)]
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_mod_bad_value.rs:24:8
|
--> $DIR/rhai_mod_bad_value.rs:24:8
|
||||||
|
|
|
|
||||||
24 | if test_module::test_fn(n) {
|
24 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: expecting identifier
|
|||||||
11 | #[rhai_mod("wheeeee")]
|
11 | #[rhai_mod("wheeeee")]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_mod_junk_arg.rs:24:8
|
--> $DIR/rhai_mod_junk_arg.rs:24:8
|
||||||
|
|
|
|
||||||
24 | if test_module::test_fn(n) {
|
24 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: requires value
|
|||||||
11 | #[rhai_mod(name)]
|
11 | #[rhai_mod(name)]
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_mod_missing_value.rs:24:8
|
--> $DIR/rhai_mod_missing_value.rs:24:8
|
||||||
|
|
|
|
||||||
24 | if test_module::test_fn(n) {
|
24 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -10,8 +10,8 @@ error: duplicated function 'test_fn'
|
|||||||
12 | pub fn test_fn(input: Point) -> bool {
|
12 | pub fn test_fn(input: Point) -> bool {
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_mod_name_collisions.rs:26:8
|
--> $DIR/rhai_mod_name_collisions.rs:26:8
|
||||||
|
|
|
|
||||||
26 | if test_module::test_fn(n) {
|
26 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: expecting attribute name
|
|||||||
11 | #[rhai_mod(rhai::name = "thing")]
|
11 | #[rhai_mod(rhai::name = "thing")]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_mod_path_attr.rs:24:8
|
--> $DIR/rhai_mod_path_attr.rs:24:8
|
||||||
|
|
|
|
||||||
24 | if test_module::test_fn(n) {
|
24 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -4,8 +4,8 @@ error: unknown attribute 'return_raw'
|
|||||||
11 | #[rhai_mod(return_raw = "yes")]
|
11 | #[rhai_mod(return_raw = "yes")]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
error[E0433]: failed to resolve: use of undeclared crate or module `test_module`
|
||||||
--> $DIR/rhai_mod_return_raw.rs:24:8
|
--> $DIR/rhai_mod_return_raw.rs:24:8
|
||||||
|
|
|
|
||||||
24 | if test_module::test_fn(n) {
|
24 | if test_module::test_fn(n) {
|
||||||
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
| ^^^^^^^^^^^ use of undeclared crate or module `test_module`
|
||||||
|
@ -15,7 +15,7 @@ help: consider importing one of these items
|
|||||||
|
|
|
|
||||||
11 | use core::fmt::Pointer;
|
11 | use core::fmt::Pointer;
|
||||||
|
|
|
|
||||||
11 | use crate::mem::fmt::Pointer;
|
11 | use crate::new_vec::fmt::Pointer;
|
||||||
|
|
|
|
||||||
11 | use std::fmt::Pointer;
|
11 | use std::fmt::Pointer;
|
||||||
|
|
|
|
||||||
|
@ -43,6 +43,9 @@ export x as answer; // the variable 'x' is exported under the alias 'answer'
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[`private`] variables are used to initialize the module.
|
||||||
|
They cannot be used apart from this.
|
||||||
|
|
||||||
|
|
||||||
Functions
|
Functions
|
||||||
---------
|
---------
|
||||||
@ -59,6 +62,9 @@ fn inc(x) { x + 1 } // script-defined function - default public
|
|||||||
private fn foo() {} // private function - hidden
|
private fn foo() {} // private function - hidden
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[`private`] functions are commonly called to initialize the module.
|
||||||
|
They cannot be called apart from this.
|
||||||
|
|
||||||
|
|
||||||
Sub-Modules
|
Sub-Modules
|
||||||
-----------
|
-----------
|
||||||
|
@ -13,8 +13,8 @@ This Rust module can then either be loaded into an [`Engine`] as a normal [modul
|
|||||||
registered as a [custom package]. This is done by using the `exported_module!` macro.
|
registered as a [custom package]. This is done by using the `exported_module!` macro.
|
||||||
|
|
||||||
|
|
||||||
Using`#[export_module]` and `exported_module!`
|
`#[export_module]` and `exported_module!`
|
||||||
---------------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
Apply `#[export_module]` onto a Rust module to convert all `pub` functions into Rhai plugin
|
Apply `#[export_module]` onto a Rust module to convert all `pub` functions into Rhai plugin
|
||||||
functions.
|
functions.
|
||||||
@ -92,6 +92,8 @@ With `#[rhai_fn(name = "...")]`, multiple functions may be registered under the
|
|||||||
|
|
||||||
Operators (which require function names that are not valid for Rust) can also be registered this way.
|
Operators (which require function names that are not valid for Rust) can also be registered this way.
|
||||||
|
|
||||||
|
Registering the same function name with the same parameter types will cause a parsing error.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rhai::plugins::*; // a "prelude" import for macros
|
use rhai::plugins::*; // a "prelude" import for macros
|
||||||
|
|
||||||
@ -155,6 +157,38 @@ mod my_module {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Multiple Registrations
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Parameters to the `#[rhai_fn(...)]` attribute can be applied multiple times.
|
||||||
|
|
||||||
|
This is especially useful for the `name = "..."`, `get = "..."` and `set = "..."` parameters
|
||||||
|
to give multiple alternative names to the same function.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use rhai::plugins::*; // a "prelude" import for macros
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
mod my_module {
|
||||||
|
// This function can be called in five ways
|
||||||
|
#[rhai_fn(name = "get_prop_value", name = "prop", name = "+", set = "prop", index_get)]
|
||||||
|
pub fn prop_function(obj: &mut MyType, index: i64) -> i64 {
|
||||||
|
obj.prop[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The above function can be called in five ways:
|
||||||
|
|
||||||
|
| Parameter for `#[rhai_fn(...)]` | Type | Call style |
|
||||||
|
| ------------------------------- | :-------------: | --------------------------------------------- |
|
||||||
|
| `name = "get_prop_value"` | Method function | `get_prop_value(x, 0)`, `x.get_prop_value(0)` |
|
||||||
|
| `name = "prop"` | Method function | `prop(x, 0)`, `x.prop(0)` |
|
||||||
|
| `name = "+"` | Operator | `x + 42` |
|
||||||
|
| `set = "prop"` | Setter | `x.prop = 42` |
|
||||||
|
| `index_get` | Index getter | `x[0]` |
|
||||||
|
|
||||||
|
|
||||||
Fallible Functions
|
Fallible Functions
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@ -444,7 +444,7 @@ impl Engine {
|
|||||||
//|| self.global_module.contains_fn(hash_script, pub_only)
|
//|| self.global_module.contains_fn(hash_script, pub_only)
|
||||||
|| self.global_module.contains_fn(hash_fn, pub_only)
|
|| self.global_module.contains_fn(hash_fn, pub_only)
|
||||||
// Then check packages
|
// Then check packages
|
||||||
//|| self.packages.contains_fn(hash_script, pub_only)
|
|| self.packages.contains_fn(hash_script, pub_only)
|
||||||
|| self.packages.contains_fn(hash_fn, pub_only)
|
|| self.packages.contains_fn(hash_fn, pub_only)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,7 +477,17 @@ impl Engine {
|
|||||||
|
|
||||||
// Qualifiers (none) + function name + number of arguments + argument `TypeId`'s.
|
// Qualifiers (none) + function name + number of arguments + argument `TypeId`'s.
|
||||||
let arg_types = args.iter().map(|a| a.type_id());
|
let arg_types = args.iter().map(|a| a.type_id());
|
||||||
let hash_fn = calc_fn_hash(empty(), fn_name, args.len(), arg_types);
|
let hash_fn = calc_fn_hash(
|
||||||
|
empty(),
|
||||||
|
fn_name,
|
||||||
|
if args.is_empty() {
|
||||||
|
// Distinguish between a script function and a native function with no parameters
|
||||||
|
usize::MAX
|
||||||
|
} else {
|
||||||
|
args.len()
|
||||||
|
},
|
||||||
|
arg_types,
|
||||||
|
);
|
||||||
|
|
||||||
match fn_name {
|
match fn_name {
|
||||||
// type_of
|
// type_of
|
||||||
@ -514,9 +524,15 @@ impl Engine {
|
|||||||
|
|
||||||
// Normal script function call
|
// Normal script function call
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
_ if hash_script > 0 && lib.contains_fn(hash_script, pub_only) => {
|
_ if lib.contains_fn(hash_script, pub_only)
|
||||||
|
|| self.packages.contains_fn(hash_script, pub_only) =>
|
||||||
|
{
|
||||||
// Get scripted function
|
// Get scripted function
|
||||||
let func = lib.get_fn(hash_script, pub_only).unwrap().get_fn_def();
|
let func = lib
|
||||||
|
.get_fn(hash_script, pub_only)
|
||||||
|
.or_else(|| self.packages.get_fn(hash_script, pub_only))
|
||||||
|
.unwrap()
|
||||||
|
.get_fn_def();
|
||||||
|
|
||||||
let scope = &mut Scope::new();
|
let scope = &mut Scope::new();
|
||||||
let mods = &mut Imports::new();
|
let mods = &mut Imports::new();
|
||||||
@ -559,6 +575,7 @@ impl Engine {
|
|||||||
|
|
||||||
Ok((result, false))
|
Ok((result, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal native function call
|
// Normal native function call
|
||||||
_ => self.call_native_fn(
|
_ => self.call_native_fn(
|
||||||
state, lib, fn_name, hash_fn, args, is_ref, pub_only, def_val,
|
state, lib, fn_name, hash_fn, args, is_ref, pub_only, def_val,
|
||||||
|
@ -93,7 +93,7 @@ pub use result::EvalAltResult;
|
|||||||
pub use scope::Scope;
|
pub use scope::Scope;
|
||||||
pub use syntax::{EvalContext, Expression};
|
pub use syntax::{EvalContext, Expression};
|
||||||
pub use token::Position;
|
pub use token::Position;
|
||||||
pub use utils::calc_fn_spec as calc_fn_hash;
|
pub use utils::calc_fn_hash;
|
||||||
|
|
||||||
pub use rhai_codegen::*;
|
pub use rhai_codegen::*;
|
||||||
|
|
||||||
|
@ -247,9 +247,13 @@ impl Module {
|
|||||||
&mut self,
|
&mut self,
|
||||||
hash_var: u64,
|
hash_var: u64,
|
||||||
) -> Result<&mut Dynamic, Box<EvalAltResult>> {
|
) -> Result<&mut Dynamic, Box<EvalAltResult>> {
|
||||||
self.all_variables.get_mut(&hash_var).ok_or_else(|| {
|
if hash_var == 0 {
|
||||||
EvalAltResult::ErrorVariableNotFound(String::new(), Position::none()).into()
|
Err(EvalAltResult::ErrorVariableNotFound(String::new(), Position::none()).into())
|
||||||
})
|
} else {
|
||||||
|
self.all_variables.get_mut(&hash_var).ok_or_else(|| {
|
||||||
|
EvalAltResult::ErrorVariableNotFound(String::new(), Position::none()).into()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a script-defined function into the module.
|
/// Set a script-defined function into the module.
|
||||||
@ -354,7 +358,9 @@ impl Module {
|
|||||||
/// assert!(module.contains_fn(hash, true));
|
/// assert!(module.contains_fn(hash, true));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn contains_fn(&self, hash_fn: u64, public_only: bool) -> bool {
|
pub fn contains_fn(&self, hash_fn: u64, public_only: bool) -> bool {
|
||||||
if public_only {
|
if hash_fn == 0 {
|
||||||
|
false
|
||||||
|
} else if public_only {
|
||||||
self.functions
|
self.functions
|
||||||
.get(&hash_fn)
|
.get(&hash_fn)
|
||||||
.map(|(_, access, _, _)| match access {
|
.map(|(_, access, _, _)| match access {
|
||||||
@ -383,7 +389,14 @@ impl Module {
|
|||||||
) -> u64 {
|
) -> u64 {
|
||||||
let name = name.into();
|
let name = name.into();
|
||||||
|
|
||||||
let hash_fn = calc_fn_hash(empty(), &name, arg_types.len(), arg_types.iter().cloned());
|
let args_len = if arg_types.is_empty() {
|
||||||
|
// Distinguish between a script function and a function with no parameters
|
||||||
|
usize::MAX
|
||||||
|
} else {
|
||||||
|
arg_types.len()
|
||||||
|
};
|
||||||
|
|
||||||
|
let hash_fn = calc_fn_hash(empty(), &name, args_len, arg_types.iter().cloned());
|
||||||
|
|
||||||
let params = arg_types.into_iter().cloned().collect();
|
let params = arg_types.into_iter().cloned().collect();
|
||||||
|
|
||||||
@ -910,13 +923,17 @@ impl Module {
|
|||||||
/// The `u64` hash is calculated by the function `crate::calc_fn_hash`.
|
/// The `u64` hash is calculated by the function `crate::calc_fn_hash`.
|
||||||
/// It is also returned by the `set_fn_XXX` calls.
|
/// It is also returned by the `set_fn_XXX` calls.
|
||||||
pub(crate) fn get_fn(&self, hash_fn: u64, public_only: bool) -> Option<&Func> {
|
pub(crate) fn get_fn(&self, hash_fn: u64, public_only: bool) -> Option<&Func> {
|
||||||
self.functions
|
if hash_fn == 0 {
|
||||||
.get(&hash_fn)
|
None
|
||||||
.and_then(|(_, access, _, f)| match access {
|
} else {
|
||||||
_ if !public_only => Some(f),
|
self.functions
|
||||||
FnAccess::Public => Some(f),
|
.get(&hash_fn)
|
||||||
FnAccess::Private => None,
|
.and_then(|(_, access, _, f)| match access {
|
||||||
})
|
_ if !public_only => Some(f),
|
||||||
|
FnAccess::Public => Some(f),
|
||||||
|
FnAccess::Private => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a modules-qualified function.
|
/// Get a modules-qualified function.
|
||||||
|
@ -149,7 +149,7 @@ fn call_fn_with_constant_arguments(
|
|||||||
fn optimize_stmt(stmt: Stmt, state: &mut State, preserve_result: bool) -> Stmt {
|
fn optimize_stmt(stmt: Stmt, state: &mut State, preserve_result: bool) -> Stmt {
|
||||||
match stmt {
|
match stmt {
|
||||||
// if expr { Noop }
|
// if expr { Noop }
|
||||||
Stmt::IfThenElse(x) if matches!(x.1, Stmt::Noop(_)) => {
|
Stmt::IfThenElse(x) if matches!(x.1, Stmt::Noop(_)) && x.2.is_none() => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
|
|
||||||
let pos = x.0.position();
|
let pos = x.0.position();
|
||||||
|
@ -1838,7 +1838,7 @@ fn parse_unary(
|
|||||||
// Call negative function
|
// Call negative function
|
||||||
expr => {
|
expr => {
|
||||||
let op = "-";
|
let op = "-";
|
||||||
let hash = calc_fn_hash(empty(), op, 2, empty());
|
let hash = calc_fn_hash(empty(), op, 1, empty());
|
||||||
let mut args = StaticVec::new();
|
let mut args = StaticVec::new();
|
||||||
args.push(expr);
|
args.push(expr);
|
||||||
|
|
||||||
@ -1865,7 +1865,7 @@ fn parse_unary(
|
|||||||
args.push(expr);
|
args.push(expr);
|
||||||
|
|
||||||
let op = "!";
|
let op = "!";
|
||||||
let hash = calc_fn_hash(empty(), op, 2, empty());
|
let hash = calc_fn_hash(empty(), op, 1, empty());
|
||||||
|
|
||||||
Ok(Expr::FnCall(Box::new((
|
Ok(Expr::FnCall(Box::new((
|
||||||
(op.into(), true, false, pos),
|
(op.into(), true, false, pos),
|
||||||
|
@ -1,28 +1,15 @@
|
|||||||
//! Module defining plugins in Rhai. Is exported for use by plugin authors.
|
//! Module defining plugins in Rhai for use by plugin authors.
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
stdlib::any::TypeId,
|
fn_native::CallableFunction, stdlib::any::TypeId, stdlib::boxed::Box, stdlib::format,
|
||||||
stdlib::boxed::Box,
|
stdlib::mem, stdlib::string::ToString, stdlib::vec as new_vec, stdlib::vec::Vec, Dynamic,
|
||||||
stdlib::format,
|
Engine, EvalAltResult, FnAccess, ImmutableString, Module, Position, RegisterResultFn,
|
||||||
stdlib::string::ToString,
|
|
||||||
stdlib::vec::Vec,
|
|
||||||
stdlib::vec as new_vec,
|
|
||||||
stdlib::mem,
|
|
||||||
fn_native::CallableFunction,
|
|
||||||
Dynamic,
|
|
||||||
Engine,
|
|
||||||
EvalAltResult,
|
|
||||||
FnAccess,
|
|
||||||
ImmutableString,
|
|
||||||
Module,
|
|
||||||
Position,
|
|
||||||
RegisterResultFn,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(features = "no_module")]
|
|
||||||
pub use rhai_codegen::{export_fn, register_exported_fn};
|
|
||||||
#[cfg(not(features = "no_module"))]
|
#[cfg(not(features = "no_module"))]
|
||||||
pub use rhai_codegen::*;
|
pub use rhai_codegen::*;
|
||||||
|
#[cfg(features = "no_module")]
|
||||||
|
pub use rhai_codegen::{export_fn, register_exported_fn};
|
||||||
|
|
||||||
#[cfg(features = "sync")]
|
#[cfg(features = "sync")]
|
||||||
/// Represents an externally-written plugin for the Rhai interpreter.
|
/// Represents an externally-written plugin for the Rhai interpreter.
|
||||||
|
@ -69,7 +69,7 @@ impl BuildHasher for StraightHasherBuilder {
|
|||||||
/// # Note
|
/// # Note
|
||||||
///
|
///
|
||||||
/// The first module name is skipped. Hashing starts from the _second_ module in the chain.
|
/// The first module name is skipped. Hashing starts from the _second_ module in the chain.
|
||||||
pub fn calc_fn_spec<'a>(
|
pub fn calc_fn_hash<'a>(
|
||||||
modules: impl Iterator<Item = &'a str>,
|
modules: impl Iterator<Item = &'a str>,
|
||||||
fn_name: &str,
|
fn_name: &str,
|
||||||
num: usize,
|
num: usize,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use rhai::{Engine, EvalAltResult, INT, Scope};
|
|
||||||
use rhai::packages::{Package, StandardPackage};
|
use rhai::packages::{Package, StandardPackage};
|
||||||
|
use rhai::{Engine, EvalAltResult, Module, Scope, INT};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_packages() -> Result<(), Box<EvalAltResult>> {
|
fn test_packages() -> Result<(), Box<EvalAltResult>> {
|
||||||
let e = Engine::new();
|
let engine = Engine::new();
|
||||||
let ast = e.compile("x")?;
|
let ast = engine.compile("x")?;
|
||||||
let std_pkg = StandardPackage::new();
|
let std_pkg = StandardPackage::new();
|
||||||
|
|
||||||
let make_call = |x: INT| -> Result<INT, Box<EvalAltResult>> {
|
let make_call = |x: INT| -> Result<INT, Box<EvalAltResult>> {
|
||||||
@ -24,10 +24,22 @@ fn test_packages() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.eval_ast_with_scope::<INT>(&mut scope, &ast)
|
engine.eval_ast_with_scope::<INT>(&mut scope, &ast)
|
||||||
};
|
};
|
||||||
|
|
||||||
// The following loop creates 10,000 Engine instances!
|
assert_eq!(make_call(42)?, 42);
|
||||||
for x in 0..10_000 {
|
|
||||||
assert_eq!(make_call(x)?, x);
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
#[cfg(not(feature = "no_module"))]
|
||||||
|
#[test]
|
||||||
|
fn test_packages_with_script() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
let ast = engine.compile("fn foo(x) { x + 1 }")?;
|
||||||
|
let module = Module::eval_ast_as_new(Scope::new(), &ast, &engine)?;
|
||||||
|
|
||||||
|
engine.load_package(module);
|
||||||
|
|
||||||
|
assert_eq!(engine.eval::<INT>("foo(41)")?, 42);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user