Simplify code.
This commit is contained in:
parent
a13fcc5cc2
commit
e8d5f78f88
@ -1,6 +1,15 @@
|
|||||||
Rhai Release Notes
|
Rhai Release Notes
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
Version 0.20.0
|
||||||
|
==============
|
||||||
|
|
||||||
|
Breaking changes
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* `AST::iter_functions` and `Module::iter_script_fn_info` now return an iterator instead of taking a closure.
|
||||||
|
|
||||||
|
|
||||||
Version 0.19.0
|
Version 0.19.0
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
@ -403,9 +403,9 @@ impl ExportedFn {
|
|||||||
|
|
||||||
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())
|
name.last().unwrap().as_str().into()
|
||||||
} else {
|
} else {
|
||||||
Cow::Owned(self.signature.ident.to_string())
|
self.signature.ident.to_string().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,9 +204,9 @@ impl Module {
|
|||||||
|
|
||||||
pub fn exported_name(&self) -> Option<Cow<str>> {
|
pub fn exported_name(&self) -> Option<Cow<str>> {
|
||||||
if let Some(ref s) = self.params.name {
|
if let Some(ref s) = self.params.name {
|
||||||
Some(Cow::Borrowed(s))
|
Some(s.into())
|
||||||
} else {
|
} else {
|
||||||
self.module_name().map(|m| Cow::Owned(m.to_string()))
|
self.module_name().map(|m| m.to_string().into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use crate::calc_fn_hash;
|
|||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
use crate::fn_native::{CallableFunction, FnCallArgs, IteratorFn, SendSync};
|
use crate::fn_native::{CallableFunction, FnCallArgs, IteratorFn, SendSync};
|
||||||
use crate::fn_register::by_value as cast_arg;
|
use crate::fn_register::by_value as cast_arg;
|
||||||
use crate::parser::{FnAccess, FnAccess::Public};
|
use crate::parser::FnAccess;
|
||||||
use crate::result::EvalAltResult;
|
use crate::result::EvalAltResult;
|
||||||
use crate::token::{Position, Token};
|
use crate::token::{Position, Token};
|
||||||
use crate::utils::{ImmutableString, StaticVec, StraightHasherBuilder};
|
use crate::utils::{ImmutableString, StaticVec, StraightHasherBuilder};
|
||||||
@ -85,7 +85,7 @@ impl fmt::Debug for Module {
|
|||||||
"Module(\n modules: {}\n vars: {}\n functions: {}\n)",
|
"Module(\n modules: {}\n vars: {}\n functions: {}\n)",
|
||||||
self.modules
|
self.modules
|
||||||
.keys()
|
.keys()
|
||||||
.map(|k| k.as_str())
|
.map(String::as_str)
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", "),
|
.join(", "),
|
||||||
self.variables
|
self.variables
|
||||||
@ -382,10 +382,7 @@ impl Module {
|
|||||||
} else if public_only {
|
} else if public_only {
|
||||||
self.functions
|
self.functions
|
||||||
.get(&hash_fn)
|
.get(&hash_fn)
|
||||||
.map(|(_, access, _, _, _)| match access {
|
.map(|(_, access, _, _, _)| access.is_public())
|
||||||
FnAccess::Public => true,
|
|
||||||
FnAccess::Private => false,
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
} else {
|
} else {
|
||||||
self.functions.contains_key(&hash_fn)
|
self.functions.contains_key(&hash_fn)
|
||||||
@ -506,7 +503,7 @@ impl Module {
|
|||||||
};
|
};
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
arg_types,
|
arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -562,7 +559,7 @@ impl Module {
|
|||||||
let arg_types = [];
|
let arg_types = [];
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_pure(Box::new(f)),
|
CallableFunction::from_pure(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -592,7 +589,7 @@ impl Module {
|
|||||||
let arg_types = [TypeId::of::<A>()];
|
let arg_types = [TypeId::of::<A>()];
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_pure(Box::new(f)),
|
CallableFunction::from_pure(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -622,7 +619,7 @@ impl Module {
|
|||||||
let arg_types = [TypeId::of::<A>()];
|
let arg_types = [TypeId::of::<A>()];
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -679,7 +676,7 @@ impl Module {
|
|||||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>()];
|
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>()];
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_pure(Box::new(f)),
|
CallableFunction::from_pure(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -715,7 +712,7 @@ impl Module {
|
|||||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>()];
|
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>()];
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -825,7 +822,7 @@ impl Module {
|
|||||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_pure(Box::new(f)),
|
CallableFunction::from_pure(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -867,7 +864,7 @@ impl Module {
|
|||||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -924,7 +921,7 @@ impl Module {
|
|||||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
FN_IDX_SET,
|
FN_IDX_SET,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -1012,7 +1009,7 @@ impl Module {
|
|||||||
];
|
];
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_pure(Box::new(f)),
|
CallableFunction::from_pure(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -1061,7 +1058,7 @@ impl Module {
|
|||||||
];
|
];
|
||||||
self.set_fn(
|
self.set_fn(
|
||||||
name,
|
name,
|
||||||
Public,
|
FnAccess::Public,
|
||||||
&arg_types,
|
&arg_types,
|
||||||
CallableFunction::from_method(Box::new(f)),
|
CallableFunction::from_method(Box::new(f)),
|
||||||
)
|
)
|
||||||
@ -1152,11 +1149,11 @@ impl Module {
|
|||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
if !other.modules.is_empty() {
|
if !other.modules.is_empty() {
|
||||||
for (k, v) in &other.modules {
|
other.modules.iter().for_each(|(k, v)| {
|
||||||
let mut m = Self::new();
|
let mut m = Self::new();
|
||||||
m.merge_filtered(v, _filter);
|
m.merge_filtered(v, _filter);
|
||||||
self.modules.insert(k.clone(), m);
|
self.modules.insert(k.clone(), m);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
#[cfg(feature = "no_function")]
|
#[cfg(feature = "no_function")]
|
||||||
if !other.modules.is_empty() {
|
if !other.modules.is_empty() {
|
||||||
@ -1244,13 +1241,14 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
pub fn iter_script_fn_info(&self, mut action: impl FnMut(FnAccess, &str, usize)) {
|
pub fn iter_script_fn_info(&self) -> impl Iterator<Item = (FnAccess, &str, usize)> {
|
||||||
self.functions
|
self.functions
|
||||||
.iter()
|
.values()
|
||||||
.for_each(|(_, (_, _, _, _, v))| match v {
|
.filter(|(_, _, _, _, v)| v.is_script())
|
||||||
CallableFunction::Script(f) => action(f.access, f.name.as_str(), f.params.len()),
|
.map(|(_, _, _, _, v)| {
|
||||||
_ => (),
|
let f = v.get_fn_def();
|
||||||
});
|
(f.access, f.name.as_str(), f.params.len())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new `Module` by evaluating an `AST`.
|
/// Create a new `Module` by evaluating an `AST`.
|
||||||
@ -1310,9 +1308,9 @@ impl Module {
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
if merge_namespaces {
|
if merge_namespaces {
|
||||||
ast.iter_functions(|access, name, num_args| match access {
|
ast.iter_functions()
|
||||||
FnAccess::Private => (),
|
.filter(|(access, _, _)| access.is_public())
|
||||||
FnAccess::Public => {
|
.for_each(|(_, name, num_args)| {
|
||||||
let fn_name = name.to_string();
|
let fn_name = name.to_string();
|
||||||
let ast_lib = ast.lib().clone();
|
let ast_lib = ast.lib().clone();
|
||||||
|
|
||||||
@ -1349,7 +1347,6 @@ impl Module {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
module.merge(ast.lib());
|
module.merge(ast.lib());
|
||||||
@ -1369,45 +1366,31 @@ impl Module {
|
|||||||
variables: &mut Vec<(u64, Dynamic)>,
|
variables: &mut Vec<(u64, Dynamic)>,
|
||||||
functions: &mut Vec<(u64, CallableFunction)>,
|
functions: &mut Vec<(u64, CallableFunction)>,
|
||||||
) {
|
) {
|
||||||
for (name, m) in &module.modules {
|
module.modules.iter().for_each(|(name, m)| {
|
||||||
// Index all the sub-modules first.
|
// Index all the sub-modules first.
|
||||||
qualifiers.push(name);
|
qualifiers.push(name);
|
||||||
index_module(m, qualifiers, variables, functions);
|
index_module(m, qualifiers, variables, functions);
|
||||||
qualifiers.pop();
|
qualifiers.pop();
|
||||||
}
|
});
|
||||||
|
|
||||||
// Index all variables
|
// Index all variables
|
||||||
for (var_name, value) in &module.variables {
|
module.variables.iter().for_each(|(var_name, value)| {
|
||||||
// Qualifiers + variable name
|
// Qualifiers + variable name
|
||||||
let hash_var = calc_fn_hash(qualifiers.iter().map(|&v| v), var_name, 0, empty());
|
let hash_var = calc_fn_hash(qualifiers.iter().map(|&v| v), var_name, 0, empty());
|
||||||
variables.push((hash_var, value.clone()));
|
variables.push((hash_var, value.clone()));
|
||||||
}
|
});
|
||||||
// Index all Rust functions
|
// Index all Rust functions
|
||||||
for (&_hash, (name, access, _num_args, params, func)) in module.functions.iter() {
|
module
|
||||||
match access {
|
.functions
|
||||||
// Private functions are not exported
|
.iter()
|
||||||
FnAccess::Private => continue,
|
.filter(|(_, (_, access, _, _, _))| access.is_public())
|
||||||
FnAccess::Public => (),
|
.for_each(|(&_hash, (name, _, _num_args, params, func))| {
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
|
||||||
if params.is_none() {
|
|
||||||
let hash_qualified_script = if qualifiers.is_empty() {
|
|
||||||
_hash
|
|
||||||
} else {
|
|
||||||
// Qualifiers + function name + number of arguments.
|
|
||||||
calc_fn_hash(qualifiers.iter().map(|&v| v), &name, *_num_args, empty())
|
|
||||||
};
|
|
||||||
functions.push((hash_qualified_script, func.clone()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(params) = params {
|
if let Some(params) = params {
|
||||||
// Qualified Rust functions are indexed in two steps:
|
// Qualified Rust functions are indexed in two steps:
|
||||||
// 1) Calculate a hash in a similar manner to script-defined functions,
|
// 1) Calculate a hash in a similar manner to script-defined functions,
|
||||||
// i.e. qualifiers + function name + number of arguments.
|
// i.e. qualifiers + function name + number of arguments.
|
||||||
let hash_qualified_script =
|
let hash_qualified_script =
|
||||||
calc_fn_hash(qualifiers.iter().map(|&v| v), name, params.len(), empty());
|
calc_fn_hash(qualifiers.iter().cloned(), name, params.len(), empty());
|
||||||
// 2) Calculate a second hash with no qualifiers, empty function name,
|
// 2) Calculate a second hash with no qualifiers, empty function name,
|
||||||
// zero number of arguments, and the actual list of argument `TypeId`'.s
|
// zero number of arguments, and the actual list of argument `TypeId`'.s
|
||||||
let hash_fn_args = calc_fn_hash(empty(), "", 0, params.iter().cloned());
|
let hash_fn_args = calc_fn_hash(empty(), "", 0, params.iter().cloned());
|
||||||
@ -1415,14 +1398,19 @@ impl Module {
|
|||||||
let hash_qualified_fn = hash_qualified_script ^ hash_fn_args;
|
let hash_qualified_fn = hash_qualified_script ^ hash_fn_args;
|
||||||
|
|
||||||
functions.push((hash_qualified_fn, func.clone()));
|
functions.push((hash_qualified_fn, func.clone()));
|
||||||
|
} else if cfg!(not(feature = "no_function")) {
|
||||||
|
let hash_qualified_script = if qualifiers.is_empty() {
|
||||||
|
_hash
|
||||||
|
} else {
|
||||||
|
// Qualifiers + function name + number of arguments.
|
||||||
|
calc_fn_hash(qualifiers.iter().map(|&v| v), &name, *_num_args, empty())
|
||||||
|
};
|
||||||
|
functions.push((hash_qualified_script, func.clone()));
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if self.indexed {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self.indexed {
|
||||||
let mut qualifiers: Vec<_> = Default::default();
|
let mut qualifiers: Vec<_> = Default::default();
|
||||||
let mut variables: Vec<_> = Default::default();
|
let mut variables: Vec<_> = Default::default();
|
||||||
let mut functions: Vec<_> = Default::default();
|
let mut functions: Vec<_> = Default::default();
|
||||||
@ -1435,6 +1423,7 @@ impl Module {
|
|||||||
self.all_functions = functions.into_iter().collect();
|
self.all_functions = functions.into_iter().collect();
|
||||||
self.indexed = true;
|
self.indexed = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Does a type iterator exist in the module?
|
/// Does a type iterator exist in the module?
|
||||||
pub fn contains_iter(&self, id: TypeId) -> bool {
|
pub fn contains_iter(&self, id: TypeId) -> bool {
|
||||||
|
@ -301,8 +301,8 @@ impl AST {
|
|||||||
|
|
||||||
/// Iterate through all functions
|
/// Iterate through all functions
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
pub fn iter_functions(&self, action: impl FnMut(FnAccess, &str, usize)) {
|
pub fn iter_functions(&self) -> impl Iterator<Item = (FnAccess, &str, usize)> {
|
||||||
self.1.iter_script_fn_info(action);
|
self.1.iter_script_fn_info()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear all function definitions in the `AST`.
|
/// Clear all function definitions in the `AST`.
|
||||||
@ -340,10 +340,10 @@ impl AsRef<Module> for AST {
|
|||||||
/// A type representing the access mode of a scripted function.
|
/// A type representing the access mode of a scripted function.
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||||
pub enum FnAccess {
|
pub enum FnAccess {
|
||||||
/// Private function.
|
|
||||||
Private,
|
|
||||||
/// Public function.
|
/// Public function.
|
||||||
Public,
|
Public,
|
||||||
|
/// Private function.
|
||||||
|
Private,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for FnAccess {
|
impl fmt::Display for FnAccess {
|
||||||
@ -355,6 +355,23 @@ impl fmt::Display for FnAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FnAccess {
|
||||||
|
/// Is this access mode private?
|
||||||
|
pub fn is_private(self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Public => false,
|
||||||
|
Self::Private => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Is this access mode public?
|
||||||
|
pub fn is_public(self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Public => true,
|
||||||
|
Self::Private => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// [INTERNALS] A type containing information on a scripted function.
|
/// [INTERNALS] A type containing information on a scripted function.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user