Simplify code.

This commit is contained in:
Stephen Chung 2020-10-01 23:31:27 +08:00
parent a13fcc5cc2
commit e8d5f78f88
5 changed files with 104 additions and 89 deletions

View File

@ -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
============== ==============

View File

@ -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()
} }
} }

View File

@ -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())
} }
} }

View File

@ -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 {

View File

@ -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.
/// ///