Fixup AsRef<str> vs &str.
This commit is contained in:
parent
1d1e473ac4
commit
d99953c101
@ -193,10 +193,10 @@ impl Engine {
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn compile_scripts_with_scope(
|
||||
pub fn compile_scripts_with_scope<S: AsRef<str>>(
|
||||
&self,
|
||||
scope: &Scope,
|
||||
scripts: &[impl AsRef<str>],
|
||||
scripts: impl AsRef<[S]>,
|
||||
) -> ParseResult<AST> {
|
||||
self.compile_with_scope_and_optimization_level(
|
||||
scope,
|
||||
@ -213,14 +213,16 @@ impl Engine {
|
||||
/// throughout the script _including_ functions. This allows functions to be optimized based on
|
||||
/// dynamic global constants.
|
||||
#[inline]
|
||||
pub(crate) fn compile_with_scope_and_optimization_level(
|
||||
pub(crate) fn compile_with_scope_and_optimization_level<S: AsRef<str>>(
|
||||
&self,
|
||||
scope: &Scope,
|
||||
scripts: &[impl AsRef<str>],
|
||||
scripts: impl AsRef<[S]>,
|
||||
#[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel,
|
||||
) -> ParseResult<AST> {
|
||||
let (stream, tokenizer_control) =
|
||||
self.lex_raw(scripts, self.token_mapper.as_ref().map(Box::as_ref));
|
||||
let (stream, tokenizer_control) = self.lex_raw(
|
||||
scripts.as_ref(),
|
||||
self.token_mapper.as_ref().map(Box::as_ref),
|
||||
);
|
||||
let mut state = ParseState::new(self, tokenizer_control);
|
||||
self.parse(
|
||||
&mut stream.peekable(),
|
||||
|
@ -209,9 +209,9 @@ impl Engine {
|
||||
/// Replacing one variable with another (i.e. adding a new variable and removing one variable at
|
||||
/// the same time so that the total _size_ of the [`Scope`][crate::Scope] is unchanged) also
|
||||
/// does NOT count, so `false` should be passed.
|
||||
pub fn register_custom_syntax(
|
||||
pub fn register_custom_syntax<S: AsRef<str> + Into<Identifier>>(
|
||||
&mut self,
|
||||
symbols: &[impl AsRef<str> + Into<Identifier>],
|
||||
symbols: impl AsRef<[S]>,
|
||||
scope_may_be_changed: bool,
|
||||
func: impl Fn(&mut EvalContext, &[Expression]) -> RhaiResult + SendSync + 'static,
|
||||
) -> ParseResult<&mut Self> {
|
||||
@ -219,7 +219,7 @@ impl Engine {
|
||||
|
||||
let mut segments = StaticVec::<ImmutableString>::new();
|
||||
|
||||
for s in symbols {
|
||||
for s in symbols.as_ref() {
|
||||
let s = s.as_ref().trim();
|
||||
|
||||
// Skip empty symbols
|
||||
|
@ -213,7 +213,7 @@ impl Engine {
|
||||
/// ```
|
||||
pub fn register_custom_operator(
|
||||
&mut self,
|
||||
keyword: impl AsRef<str> + Into<Identifier>,
|
||||
keyword: impl AsRef<str>,
|
||||
precedence: u8,
|
||||
) -> Result<&mut Self, String> {
|
||||
let precedence = Precedence::new(precedence);
|
||||
@ -247,7 +247,8 @@ impl Engine {
|
||||
}
|
||||
|
||||
// Add to custom keywords
|
||||
self.custom_keywords.insert(keyword.into(), precedence);
|
||||
self.custom_keywords
|
||||
.insert(keyword.as_ref().into(), precedence);
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ impl Engine {
|
||||
pub fn register_raw_fn<N, T>(
|
||||
&mut self,
|
||||
name: N,
|
||||
arg_types: &[TypeId],
|
||||
arg_types: impl AsRef<[TypeId]>,
|
||||
func: impl Fn(NativeCallContext, &mut FnCallArgs) -> RhaiResultOf<T> + SendSync + 'static,
|
||||
) -> &mut Self
|
||||
where
|
||||
@ -346,7 +346,7 @@ impl Engine {
|
||||
name: impl AsRef<str>,
|
||||
get_fn: impl Fn(&mut T) -> V + SendSync + 'static,
|
||||
) -> &mut Self {
|
||||
self.register_fn(&crate::engine::make_getter(name.as_ref()), get_fn)
|
||||
self.register_fn(crate::engine::make_getter(name.as_ref()).as_str(), get_fn)
|
||||
}
|
||||
/// Register a getter function for a member of a registered type with the [`Engine`].
|
||||
///
|
||||
@ -395,7 +395,7 @@ impl Engine {
|
||||
name: impl AsRef<str>,
|
||||
get_fn: impl Fn(&mut T) -> RhaiResultOf<V> + SendSync + 'static,
|
||||
) -> &mut Self {
|
||||
self.register_result_fn(&crate::engine::make_getter(name.as_ref()), get_fn)
|
||||
self.register_result_fn(crate::engine::make_getter(name.as_ref()).as_str(), get_fn)
|
||||
}
|
||||
/// Register a setter function for a member of a registered type with the [`Engine`].
|
||||
///
|
||||
@ -445,7 +445,7 @@ impl Engine {
|
||||
name: impl AsRef<str>,
|
||||
set_fn: impl Fn(&mut T, V) + SendSync + 'static,
|
||||
) -> &mut Self {
|
||||
self.register_fn(&crate::engine::make_setter(name.as_ref()), set_fn)
|
||||
self.register_fn(crate::engine::make_setter(name.as_ref()).as_str(), set_fn)
|
||||
}
|
||||
/// Register a setter function for a member of a registered type with the [`Engine`].
|
||||
///
|
||||
@ -496,7 +496,7 @@ impl Engine {
|
||||
name: impl AsRef<str>,
|
||||
set_fn: impl Fn(&mut T, V) -> RhaiResultOf<()> + SendSync + 'static,
|
||||
) -> &mut Self {
|
||||
self.register_result_fn(&crate::engine::make_setter(name.as_ref()), set_fn)
|
||||
self.register_result_fn(crate::engine::make_setter(name.as_ref()).as_str(), set_fn)
|
||||
}
|
||||
/// Short-hand for registering both getter and setter functions
|
||||
/// of a registered type with the [`Engine`].
|
||||
@ -975,17 +975,17 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
pub fn register_static_module(
|
||||
&mut self,
|
||||
name: impl AsRef<str> + Into<Identifier>,
|
||||
name: impl AsRef<str>,
|
||||
module: Shared<Module>,
|
||||
) -> &mut Self {
|
||||
fn register_static_module_raw(
|
||||
root: &mut std::collections::BTreeMap<Identifier, Shared<Module>>,
|
||||
name: impl AsRef<str> + Into<Identifier>,
|
||||
name: &str,
|
||||
module: Shared<Module>,
|
||||
) {
|
||||
let separator = crate::tokenizer::Token::DoubleColon.syntax();
|
||||
|
||||
if !name.as_ref().contains(separator.as_ref()) {
|
||||
if !name.contains(separator.as_ref()) {
|
||||
if !module.is_indexed() {
|
||||
// Index the module (making a clone copy if necessary) if it is not indexed
|
||||
let mut module = crate::func::native::shared_take_or_clone(module);
|
||||
@ -995,7 +995,7 @@ impl Engine {
|
||||
root.insert(name.into(), module);
|
||||
}
|
||||
} else {
|
||||
let mut iter = name.as_ref().splitn(2, separator.as_ref());
|
||||
let mut iter = name.splitn(2, separator.as_ref());
|
||||
let sub_module = iter.next().expect("contains separator").trim();
|
||||
let remainder = iter.next().expect("contains separator").trim();
|
||||
|
||||
@ -1014,7 +1014,7 @@ impl Engine {
|
||||
}
|
||||
}
|
||||
|
||||
register_static_module_raw(&mut self.global_sub_modules, name, module);
|
||||
register_static_module_raw(&mut self.global_sub_modules, name.as_ref(), module);
|
||||
self
|
||||
}
|
||||
/// _(metadata)_ Generate a list of all registered functions.
|
||||
|
@ -626,8 +626,7 @@ impl GlobalRuntimeState {
|
||||
/// Get the index of a globally-imported [module][Module] by name.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn find_module(&self, name: impl AsRef<str>) -> Option<usize> {
|
||||
let name = name.as_ref();
|
||||
pub fn find_module(&self, name: &str) -> Option<usize> {
|
||||
let len = self.keys.len();
|
||||
|
||||
self.keys.iter().rev().enumerate().find_map(|(i, key)| {
|
||||
@ -1041,26 +1040,32 @@ impl Default for Engine {
|
||||
|
||||
/// Make getter function
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn make_getter(id: &str) -> String {
|
||||
format!("{}{}", FN_GET, id)
|
||||
pub fn make_getter(id: &str) -> Identifier {
|
||||
let mut buf = Identifier::new_const();
|
||||
buf.push_str(FN_GET);
|
||||
buf.push_str(id);
|
||||
buf
|
||||
}
|
||||
|
||||
/// Make setter function
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn make_setter(id: &str) -> String {
|
||||
format!("{}{}", FN_SET, id)
|
||||
pub fn make_setter(id: &str) -> Identifier {
|
||||
let mut buf = Identifier::new_const();
|
||||
buf.push_str(FN_SET);
|
||||
buf.push_str(id);
|
||||
buf
|
||||
}
|
||||
|
||||
/// Is this function an anonymous function?
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn is_anonymous_fn(fn_name: impl AsRef<str>) -> bool {
|
||||
fn_name.as_ref().starts_with(FN_ANONYMOUS)
|
||||
pub fn is_anonymous_fn(fn_name: &str) -> bool {
|
||||
fn_name.starts_with(FN_ANONYMOUS)
|
||||
}
|
||||
|
||||
/// Print to `stdout`
|
||||
|
@ -105,7 +105,7 @@ impl Drop for ArgBackup<'_> {
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
#[inline]
|
||||
pub fn ensure_no_data_race(
|
||||
fn_name: impl AsRef<str>,
|
||||
fn_name: &str,
|
||||
args: &FnCallArgs,
|
||||
is_method_call: bool,
|
||||
) -> RhaiResultOf<()> {
|
||||
@ -116,7 +116,7 @@ pub fn ensure_no_data_race(
|
||||
.find(|(_, a)| a.is_locked())
|
||||
{
|
||||
return Err(ERR::ErrorDataRace(
|
||||
format!("argument #{} of function '{}'", n + 1, fn_name.as_ref()),
|
||||
format!("argument #{} of function '{}'", n + 1, fn_name),
|
||||
Position::NONE,
|
||||
)
|
||||
.into());
|
||||
@ -150,7 +150,7 @@ impl Engine {
|
||||
fn gen_call_signature(
|
||||
&self,
|
||||
namespace: Option<&Namespace>,
|
||||
fn_name: impl AsRef<str>,
|
||||
fn_name: &str,
|
||||
args: &[&mut Dynamic],
|
||||
) -> String {
|
||||
format!(
|
||||
@ -161,7 +161,7 @@ impl Engine {
|
||||
} else {
|
||||
""
|
||||
},
|
||||
fn_name.as_ref(),
|
||||
fn_name,
|
||||
args.iter()
|
||||
.map(|a| if a.is::<ImmutableString>() {
|
||||
"&str | ImmutableString | String"
|
||||
@ -187,7 +187,7 @@ impl Engine {
|
||||
global: &GlobalRuntimeState,
|
||||
state: &'s mut EvalState,
|
||||
lib: &[&Module],
|
||||
fn_name: impl AsRef<str>,
|
||||
fn_name: &str,
|
||||
hash_script: u64,
|
||||
args: Option<&mut FnCallArgs>,
|
||||
allow_dynamic: bool,
|
||||
@ -197,8 +197,6 @@ impl Engine {
|
||||
return None;
|
||||
}
|
||||
|
||||
let fn_name = fn_name.as_ref();
|
||||
|
||||
let mut hash = args.as_ref().map_or(hash_script, |args| {
|
||||
combine_hashes(
|
||||
hash_script,
|
||||
@ -332,7 +330,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
state: &mut EvalState,
|
||||
lib: &[&Module],
|
||||
name: impl AsRef<str>,
|
||||
name: &str,
|
||||
hash: u64,
|
||||
args: &mut FnCallArgs,
|
||||
is_ref_mut: bool,
|
||||
@ -342,7 +340,6 @@ impl Engine {
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
self.inc_operations(&mut global.num_operations, pos)?;
|
||||
|
||||
let name = name.as_ref();
|
||||
let parent_source = global.source.clone();
|
||||
|
||||
// Check if function access already in the cache
|
||||
@ -521,7 +518,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
state: &mut EvalState,
|
||||
lib: &[&Module],
|
||||
fn_name: impl AsRef<str>,
|
||||
fn_name: &str,
|
||||
hashes: FnCallHashes,
|
||||
args: &mut FnCallArgs,
|
||||
is_ref_mut: bool,
|
||||
@ -535,8 +532,6 @@ impl Engine {
|
||||
Err(ERR::ErrorRuntime(msg.into(), pos).into())
|
||||
}
|
||||
|
||||
let fn_name = fn_name.as_ref();
|
||||
|
||||
// Check for data race.
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
ensure_no_data_race(fn_name, args, is_ref_mut)?;
|
||||
@ -717,14 +712,13 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
state: &mut EvalState,
|
||||
lib: &[&Module],
|
||||
fn_name: impl AsRef<str>,
|
||||
fn_name: &str,
|
||||
mut hash: FnCallHashes,
|
||||
target: &mut crate::engine::Target,
|
||||
(call_args, call_arg_pos): &mut (FnArgsVec<Dynamic>, Position),
|
||||
pos: Position,
|
||||
level: usize,
|
||||
) -> RhaiResultOf<(Dynamic, bool)> {
|
||||
let fn_name = fn_name.as_ref();
|
||||
let is_ref_mut = target.is_ref();
|
||||
|
||||
let (result, updated) = match fn_name {
|
||||
@ -902,7 +896,7 @@ impl Engine {
|
||||
state: &mut EvalState,
|
||||
lib: &[&Module],
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
fn_name: impl AsRef<str>,
|
||||
fn_name: &str,
|
||||
args_expr: &[Expr],
|
||||
constants: &[Dynamic],
|
||||
hashes: FnCallHashes,
|
||||
@ -910,7 +904,6 @@ impl Engine {
|
||||
capture_scope: bool,
|
||||
level: usize,
|
||||
) -> RhaiResult {
|
||||
let fn_name = fn_name.as_ref();
|
||||
let mut a_expr = args_expr;
|
||||
let mut total_args = a_expr.len();
|
||||
let mut curry = FnArgsVec::new_const();
|
||||
@ -1179,14 +1172,13 @@ impl Engine {
|
||||
lib: &[&Module],
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
namespace: &Namespace,
|
||||
fn_name: impl AsRef<str>,
|
||||
fn_name: &str,
|
||||
args_expr: &[Expr],
|
||||
constants: &[Dynamic],
|
||||
hash: u64,
|
||||
pos: Position,
|
||||
level: usize,
|
||||
) -> RhaiResult {
|
||||
let fn_name = fn_name.as_ref();
|
||||
let mut arg_values = FnArgsVec::with_capacity(args_expr.len());
|
||||
let mut args = FnArgsVec::with_capacity(args_expr.len());
|
||||
let mut first_arg_value = None;
|
||||
@ -1324,14 +1316,17 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
state: &mut EvalState,
|
||||
lib: &[&Module],
|
||||
script: impl AsRef<str>,
|
||||
_pos: Position,
|
||||
script: &str,
|
||||
pos: Position,
|
||||
level: usize,
|
||||
) -> RhaiResult {
|
||||
let _pos = pos;
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
self.inc_operations(&mut global.num_operations, _pos)?;
|
||||
|
||||
let script = script.as_ref().trim();
|
||||
let script = script.trim();
|
||||
|
||||
if script.is_empty() {
|
||||
return Ok(Dynamic::UNIT);
|
||||
}
|
||||
|
@ -87,10 +87,7 @@ pub fn get_hasher() -> ahash::AHasher {
|
||||
/// The first module name is skipped. Hashing starts from the _second_ module in the chain.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn calc_qualified_var_hash<'a>(
|
||||
modules: impl Iterator<Item = impl AsRef<str> + 'a>,
|
||||
var_name: impl AsRef<str>,
|
||||
) -> u64 {
|
||||
pub fn calc_qualified_var_hash<'a>(modules: impl Iterator<Item = &'a str>, var_name: &str) -> u64 {
|
||||
let s = &mut get_hasher();
|
||||
|
||||
// We always skip the first module
|
||||
@ -98,9 +95,9 @@ pub fn calc_qualified_var_hash<'a>(
|
||||
modules
|
||||
.inspect(|_| len += 1)
|
||||
.skip(1)
|
||||
.for_each(|m| m.as_ref().hash(s));
|
||||
.for_each(|m| m.hash(s));
|
||||
len.hash(s);
|
||||
var_name.as_ref().hash(s);
|
||||
var_name.hash(s);
|
||||
|
||||
match s.finish() {
|
||||
0 => ALT_ZERO_HASH,
|
||||
@ -123,9 +120,9 @@ pub fn calc_qualified_var_hash<'a>(
|
||||
/// The first module name is skipped. Hashing starts from the _second_ module in the chain.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn calc_qualified_fn_hash(
|
||||
modules: impl Iterator<Item = impl AsRef<str>>,
|
||||
fn_name: impl AsRef<str>,
|
||||
pub fn calc_qualified_fn_hash<'a>(
|
||||
modules: impl Iterator<Item = &'a str>,
|
||||
fn_name: &str,
|
||||
num: usize,
|
||||
) -> u64 {
|
||||
let s = &mut get_hasher();
|
||||
@ -135,9 +132,9 @@ pub fn calc_qualified_fn_hash(
|
||||
modules
|
||||
.inspect(|_| len += 1)
|
||||
.skip(1)
|
||||
.for_each(|m| m.as_ref().hash(s));
|
||||
.for_each(|m| m.hash(s));
|
||||
len.hash(s);
|
||||
fn_name.as_ref().hash(s);
|
||||
fn_name.hash(s);
|
||||
num.hash(s);
|
||||
|
||||
match s.finish() {
|
||||
@ -156,8 +153,8 @@ pub fn calc_qualified_fn_hash(
|
||||
/// If the hash happens to be zero, it is mapped to `DEFAULT_HASH`.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn calc_fn_hash(fn_name: impl AsRef<str>, num: usize) -> u64 {
|
||||
calc_qualified_fn_hash(empty::<&str>(), fn_name, num)
|
||||
pub fn calc_fn_hash(fn_name: &str, num: usize) -> u64 {
|
||||
calc_qualified_fn_hash(empty(), fn_name, num)
|
||||
}
|
||||
|
||||
/// Calculate a non-zero [`u64`] hash key from a list of parameter types.
|
||||
|
@ -287,15 +287,16 @@ impl<'a> NativeCallContext<'a> {
|
||||
args: &mut [&mut Dynamic],
|
||||
) -> RhaiResult {
|
||||
let fn_name = fn_name.as_ref();
|
||||
let len = args.len();
|
||||
|
||||
let hash = if is_method_call {
|
||||
FnCallHashes::from_all(
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
calc_fn_hash(fn_name, args.len() - 1),
|
||||
calc_fn_hash(fn_name, args.len()),
|
||||
calc_fn_hash(fn_name, len - 1),
|
||||
calc_fn_hash(fn_name, len),
|
||||
)
|
||||
} else {
|
||||
calc_fn_hash(fn_name, args.len()).into()
|
||||
calc_fn_hash(fn_name, len).into()
|
||||
};
|
||||
|
||||
self.engine()
|
||||
|
@ -116,12 +116,12 @@ impl FuncInfo {
|
||||
///
|
||||
/// The first module name is skipped. Hashing starts from the _second_ module in the chain.
|
||||
#[inline]
|
||||
pub fn calc_native_fn_hash(
|
||||
modules: impl Iterator<Item = impl AsRef<str>>,
|
||||
fn_name: impl AsRef<str>,
|
||||
pub fn calc_native_fn_hash<'a>(
|
||||
modules: impl Iterator<Item = &'a str>,
|
||||
fn_name: &str,
|
||||
params: &[TypeId],
|
||||
) -> u64 {
|
||||
let hash_script = calc_qualified_fn_hash(modules, fn_name.as_ref(), params.len());
|
||||
let hash_script = calc_qualified_fn_hash(modules, fn_name, params.len());
|
||||
let hash_params = calc_fn_params_hash(params.iter().cloned());
|
||||
combine_hashes(hash_script, hash_params)
|
||||
}
|
||||
@ -644,8 +644,13 @@ impl Module {
|
||||
/// In other words, the number of entries should be one larger than the number of parameters.
|
||||
#[cfg(feature = "metadata")]
|
||||
#[inline]
|
||||
pub fn update_fn_metadata(&mut self, hash_fn: u64, arg_names: &[impl AsRef<str>]) -> &mut Self {
|
||||
pub fn update_fn_metadata<S: AsRef<str>>(
|
||||
&mut self,
|
||||
hash_fn: u64,
|
||||
arg_names: impl AsRef<[S]>,
|
||||
) -> &mut Self {
|
||||
let mut param_names: StaticVec<_> = arg_names
|
||||
.as_ref()
|
||||
.iter()
|
||||
.map(|name| self.interner.get("", name.as_ref()).into())
|
||||
.collect();
|
||||
@ -689,17 +694,23 @@ impl Module {
|
||||
/// doc-comment leader: `///` or `/**`.
|
||||
#[cfg(feature = "metadata")]
|
||||
#[inline]
|
||||
pub fn update_fn_metadata_with_comments(
|
||||
pub fn update_fn_metadata_with_comments<A: AsRef<str>, C: AsRef<str>>(
|
||||
&mut self,
|
||||
hash_fn: u64,
|
||||
arg_names: &[impl AsRef<str>],
|
||||
comments: &[impl AsRef<str>],
|
||||
arg_names: impl AsRef<[A]>,
|
||||
comments: impl AsRef<[C]>,
|
||||
) -> &mut Self {
|
||||
self.update_fn_metadata(hash_fn, arg_names);
|
||||
|
||||
if !comments.is_empty() {
|
||||
if !comments.as_ref().is_empty() {
|
||||
let f = self.functions.get_mut(&hash_fn).expect("exists");
|
||||
f.comments = Some(comments.iter().map(|s| s.as_ref().into()).collect());
|
||||
f.comments = Some(
|
||||
comments
|
||||
.as_ref()
|
||||
.iter()
|
||||
.map(|s| s.as_ref().into())
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
|
||||
self
|
||||
@ -756,17 +767,18 @@ impl Module {
|
||||
#[inline]
|
||||
pub fn set_fn(
|
||||
&mut self,
|
||||
name: impl AsRef<str> + Into<Identifier>,
|
||||
name: impl AsRef<str>,
|
||||
namespace: FnNamespace,
|
||||
access: FnAccess,
|
||||
arg_names: Option<&[&str]>,
|
||||
arg_types: &[TypeId],
|
||||
arg_types: impl AsRef<[TypeId]>,
|
||||
func: CallableFunction,
|
||||
) -> u64 {
|
||||
let _arg_names = arg_names;
|
||||
let is_method = func.is_method();
|
||||
|
||||
let mut param_types: StaticVec<_> = arg_types
|
||||
.as_ref()
|
||||
.iter()
|
||||
.cloned()
|
||||
.enumerate()
|
||||
@ -781,7 +793,7 @@ impl Module {
|
||||
.flat_map(|&p| p.iter())
|
||||
.map(|&arg| self.interner.get("", arg).into())
|
||||
.collect::<StaticVec<_>>();
|
||||
let return_type = if names.len() > arg_types.len() {
|
||||
let return_type = if names.len() > arg_types.as_ref().len() {
|
||||
names.pop().expect("exists")
|
||||
} else {
|
||||
Default::default()
|
||||
@ -795,7 +807,7 @@ impl Module {
|
||||
self.functions.insert(
|
||||
hash_fn,
|
||||
FuncInfo {
|
||||
name: self.interner.get("", name.as_ref()).into(),
|
||||
name: self.interner.get("", name).into(),
|
||||
namespace,
|
||||
access,
|
||||
params: param_types.len(),
|
||||
@ -845,21 +857,27 @@ impl Module {
|
||||
/// doc-comment leader: `///` or `/**`.
|
||||
#[cfg(feature = "metadata")]
|
||||
#[inline]
|
||||
pub fn set_fn_with_comments(
|
||||
pub fn set_fn_with_comments<S: AsRef<str>>(
|
||||
&mut self,
|
||||
name: impl AsRef<str> + Into<Identifier>,
|
||||
name: impl AsRef<str>,
|
||||
namespace: FnNamespace,
|
||||
access: FnAccess,
|
||||
arg_names: Option<&[&str]>,
|
||||
arg_types: &[TypeId],
|
||||
comments: &[impl AsRef<str>],
|
||||
arg_types: impl AsRef<[TypeId]>,
|
||||
comments: impl AsRef<[S]>,
|
||||
func: CallableFunction,
|
||||
) -> u64 {
|
||||
let hash = self.set_fn(name, namespace, access, arg_names, arg_types, func);
|
||||
|
||||
if !comments.is_empty() {
|
||||
if !comments.as_ref().is_empty() {
|
||||
let f = self.functions.get_mut(&hash).expect("exists");
|
||||
f.comments = Some(comments.iter().map(|s| s.as_ref().into()).collect());
|
||||
f.comments = Some(
|
||||
comments
|
||||
.as_ref()
|
||||
.iter()
|
||||
.map(|s| s.as_ref().into())
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
|
||||
hash
|
||||
@ -932,16 +950,15 @@ impl Module {
|
||||
/// assert!(module.contains_fn(hash));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_raw_fn<N, T, F>(
|
||||
pub fn set_raw_fn<T, F>(
|
||||
&mut self,
|
||||
name: N,
|
||||
name: impl AsRef<str>,
|
||||
namespace: FnNamespace,
|
||||
access: FnAccess,
|
||||
arg_types: &[TypeId],
|
||||
arg_types: impl AsRef<[TypeId]>,
|
||||
func: F,
|
||||
) -> u64
|
||||
where
|
||||
N: AsRef<str> + Into<Identifier>,
|
||||
T: Variant + Clone,
|
||||
F: Fn(NativeCallContext, &mut FnCallArgs) -> RhaiResultOf<T> + SendSync + 'static,
|
||||
{
|
||||
@ -1025,7 +1042,7 @@ impl Module {
|
||||
F: Fn(&mut A) -> RhaiResultOf<T> + SendSync + 'static,
|
||||
{
|
||||
self.set_fn(
|
||||
&crate::engine::make_getter(name.as_ref()),
|
||||
crate::engine::make_getter(name.as_ref()).as_str(),
|
||||
FnNamespace::Global,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
@ -1067,7 +1084,7 @@ impl Module {
|
||||
F: Fn(&mut A, B) -> RhaiResultOf<()> + SendSync + 'static,
|
||||
{
|
||||
self.set_fn(
|
||||
&crate::engine::make_setter(name.as_ref()),
|
||||
crate::engine::make_setter(name.as_ref()).as_str(),
|
||||
FnNamespace::Global,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
|
@ -110,13 +110,11 @@ impl<'a> OptimizerState<'a> {
|
||||
}
|
||||
/// Look up a constant from the list.
|
||||
#[inline]
|
||||
pub fn find_constant(&self, name: impl AsRef<str>) -> Option<&Dynamic> {
|
||||
pub fn find_constant(&self, name: &str) -> Option<&Dynamic> {
|
||||
if !self.propagate_constants {
|
||||
return None;
|
||||
}
|
||||
|
||||
let name = name.as_ref();
|
||||
|
||||
for (n, access, value) in self.variables.iter().rev() {
|
||||
if n == name {
|
||||
return match access {
|
||||
@ -132,7 +130,7 @@ impl<'a> OptimizerState<'a> {
|
||||
#[inline]
|
||||
pub fn call_fn_with_constant_arguments(
|
||||
&self,
|
||||
fn_name: impl AsRef<str>,
|
||||
fn_name: &str,
|
||||
arg_values: &mut [Dynamic],
|
||||
) -> Option<Dynamic> {
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
@ -145,7 +143,7 @@ impl<'a> OptimizerState<'a> {
|
||||
&mut GlobalRuntimeState::new(),
|
||||
&mut EvalState::new(),
|
||||
lib,
|
||||
&fn_name,
|
||||
fn_name,
|
||||
calc_fn_hash(&fn_name, arg_values.len()),
|
||||
&mut arg_values.iter_mut().collect::<StaticVec<_>>(),
|
||||
false,
|
||||
@ -158,8 +156,12 @@ impl<'a> OptimizerState<'a> {
|
||||
}
|
||||
|
||||
// Has a system function a Rust-native override?
|
||||
fn has_native_fn_override(engine: &Engine, hash_script: u64, arg_types: &[TypeId]) -> bool {
|
||||
let hash_params = calc_fn_params_hash(arg_types.iter().cloned());
|
||||
fn has_native_fn_override(
|
||||
engine: &Engine,
|
||||
hash_script: u64,
|
||||
arg_types: impl AsRef<[TypeId]>,
|
||||
) -> bool {
|
||||
let hash_params = calc_fn_params_hash(arg_types.as_ref().iter().cloned());
|
||||
let hash = combine_hashes(hash_script, hash_params);
|
||||
|
||||
// First check the global namespace and packages, but skip modules that are standard because
|
||||
|
@ -108,8 +108,7 @@ impl<'e> ParseState<'e> {
|
||||
/// Return `None` when the variable name is not found in the `stack`.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn access_var(&mut self, name: impl AsRef<str>, pos: Position) -> Option<NonZeroUsize> {
|
||||
let name = name.as_ref();
|
||||
pub fn access_var(&mut self, name: &str, pos: Position) -> Option<NonZeroUsize> {
|
||||
let mut barrier = false;
|
||||
let _pos = pos;
|
||||
|
||||
@ -158,9 +157,7 @@ impl<'e> ParseState<'e> {
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn find_module(&self, name: impl AsRef<str>) -> Option<NonZeroUsize> {
|
||||
let name = name.as_ref();
|
||||
|
||||
pub fn find_module(&self, name: &str) -> Option<NonZeroUsize> {
|
||||
self.modules
|
||||
.iter()
|
||||
.rev()
|
||||
@ -172,11 +169,7 @@ impl<'e> ParseState<'e> {
|
||||
/// Get an interned identifier, creating one if it is not yet interned.
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn get_identifier(
|
||||
&mut self,
|
||||
prefix: &'static str,
|
||||
text: impl AsRef<str> + Into<Identifier> + Into<ImmutableString>,
|
||||
) -> Identifier {
|
||||
pub fn get_identifier(&mut self, prefix: impl AsRef<str>, text: impl AsRef<str>) -> Identifier {
|
||||
self.interned_strings.get(prefix, text).into()
|
||||
}
|
||||
|
||||
@ -186,8 +179,8 @@ impl<'e> ParseState<'e> {
|
||||
#[must_use]
|
||||
pub fn get_interned_string(
|
||||
&mut self,
|
||||
prefix: &'static str,
|
||||
text: impl AsRef<str> + Into<Identifier> + Into<ImmutableString>,
|
||||
prefix: impl AsRef<str>,
|
||||
text: impl AsRef<str>,
|
||||
) -> ImmutableString {
|
||||
self.interned_strings.get(prefix, text)
|
||||
}
|
||||
@ -259,15 +252,15 @@ impl Expr {
|
||||
match self {
|
||||
Self::Variable(_, pos, x) if x.1.is_none() => {
|
||||
let ident = x.2;
|
||||
let getter = state.get_identifier(crate::engine::FN_GET, ident.as_str());
|
||||
let getter = state.get_identifier(crate::engine::FN_GET, &ident);
|
||||
let hash_get = calc_fn_hash(&getter, 1);
|
||||
let setter = state.get_identifier(crate::engine::FN_SET, ident.as_str());
|
||||
let setter = state.get_identifier(crate::engine::FN_SET, &ident);
|
||||
let hash_set = calc_fn_hash(&setter, 2);
|
||||
|
||||
Self::Property(Box::new((
|
||||
(getter, hash_get),
|
||||
(setter, hash_set),
|
||||
(state.get_interned_string("", ident.as_str()), pos),
|
||||
(state.get_interned_string("", &ident), pos),
|
||||
)))
|
||||
}
|
||||
_ => self,
|
||||
@ -1159,7 +1152,7 @@ fn parse_primary(
|
||||
Token::IntegerConstant(x) => Expr::IntegerConstant(x, settings.pos),
|
||||
Token::CharConstant(c) => Expr::CharConstant(c, settings.pos),
|
||||
Token::StringConstant(s) => {
|
||||
Expr::StringConstant(state.get_identifier("", s).into(), settings.pos)
|
||||
Expr::StringConstant(state.get_interned_string("", s), settings.pos)
|
||||
}
|
||||
Token::True => Expr::BoolConstant(true, settings.pos),
|
||||
Token::False => Expr::BoolConstant(false, settings.pos),
|
||||
@ -1998,7 +1991,7 @@ fn parse_binary_op(
|
||||
let hash = calc_fn_hash(&op, 2);
|
||||
|
||||
let op_base = FnCallExpr {
|
||||
name: state.get_identifier("", op.as_ref()),
|
||||
name: state.get_identifier("", op),
|
||||
hashes: FnCallHashes::from_native(hash),
|
||||
..Default::default()
|
||||
};
|
||||
@ -2125,7 +2118,7 @@ fn parse_custom_syntax(
|
||||
&& seg.len() > CUSTOM_SYNTAX_MARKER_SYNTAX_VARIANT.len() =>
|
||||
{
|
||||
inputs.push(Expr::StringConstant(
|
||||
state.get_identifier("", seg).into(),
|
||||
state.get_interned_string("", seg),
|
||||
pos,
|
||||
));
|
||||
break;
|
||||
@ -2145,7 +2138,7 @@ fn parse_custom_syntax(
|
||||
}
|
||||
CUSTOM_SYNTAX_MARKER_SYMBOL => {
|
||||
let (symbol, pos) = parse_symbol(input)?;
|
||||
let symbol: ImmutableString = state.get_identifier("", symbol).into();
|
||||
let symbol = state.get_interned_string("", symbol);
|
||||
segments.push(symbol.clone());
|
||||
tokens.push(state.get_identifier("", CUSTOM_SYNTAX_MARKER_SYMBOL));
|
||||
inputs.push(Expr::StringConstant(symbol, pos));
|
||||
@ -2168,7 +2161,7 @@ fn parse_custom_syntax(
|
||||
CUSTOM_SYNTAX_MARKER_BOOL => match input.next().expect(NEVER_ENDS) {
|
||||
(b @ Token::True, pos) | (b @ Token::False, pos) => {
|
||||
inputs.push(Expr::BoolConstant(b == Token::True, pos));
|
||||
segments.push(state.get_identifier("", b.literal_syntax()).into());
|
||||
segments.push(state.get_interned_string("", b.literal_syntax()));
|
||||
tokens.push(state.get_identifier("", CUSTOM_SYNTAX_MARKER_BOOL));
|
||||
}
|
||||
(_, pos) => {
|
||||
@ -2207,7 +2200,7 @@ fn parse_custom_syntax(
|
||||
},
|
||||
CUSTOM_SYNTAX_MARKER_STRING => match input.next().expect(NEVER_ENDS) {
|
||||
(Token::StringConstant(s), pos) => {
|
||||
let s: ImmutableString = state.get_identifier("", s).into();
|
||||
let s = state.get_interned_string("", s);
|
||||
inputs.push(Expr::StringConstant(s.clone(), pos));
|
||||
segments.push(s);
|
||||
tokens.push(state.get_identifier("", CUSTOM_SYNTAX_MARKER_STRING));
|
||||
@ -3268,11 +3261,7 @@ fn parse_anon_fn(
|
||||
params.iter().for_each(|p| p.hash(hasher));
|
||||
body.hash(hasher);
|
||||
let hash = hasher.finish();
|
||||
|
||||
let fn_name = state.get_identifier(
|
||||
"",
|
||||
&(format!("{}{:016x}", crate::engine::FN_ANONYMOUS, hash)),
|
||||
);
|
||||
let fn_name = state.get_identifier("", format!("{}{:016x}", crate::engine::FN_ANONYMOUS, hash));
|
||||
|
||||
// Define the function
|
||||
let script = ScriptFnDef {
|
||||
|
@ -694,11 +694,9 @@ impl Token {
|
||||
|
||||
/// Reverse lookup a token from a piece of syntax.
|
||||
#[must_use]
|
||||
pub fn lookup_from_syntax(syntax: impl AsRef<str>) -> Option<Self> {
|
||||
pub fn lookup_from_syntax(syntax: &str) -> Option<Self> {
|
||||
use Token::*;
|
||||
|
||||
let syntax = syntax.as_ref();
|
||||
|
||||
Some(match syntax {
|
||||
"{" => LeftBrace,
|
||||
"}" => RightBrace,
|
||||
@ -1355,9 +1353,7 @@ fn is_numeric_digit(c: char) -> bool {
|
||||
#[cfg(feature = "metadata")]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn is_doc_comment(comment: impl AsRef<str>) -> bool {
|
||||
let comment = comment.as_ref();
|
||||
|
||||
pub fn is_doc_comment(comment: &str) -> bool {
|
||||
(comment.starts_with("///") && !comment.starts_with("////"))
|
||||
|| (comment.starts_with("/**") && !comment.starts_with("/***"))
|
||||
}
|
||||
@ -2018,8 +2014,8 @@ fn get_identifier(
|
||||
/// Is this keyword allowed as a function?
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn is_keyword_function(name: impl AsRef<str>) -> bool {
|
||||
match name.as_ref() {
|
||||
pub fn is_keyword_function(name: &str) -> bool {
|
||||
match name {
|
||||
KEYWORD_PRINT | KEYWORD_DEBUG | KEYWORD_TYPE_OF | KEYWORD_EVAL | KEYWORD_FN_PTR
|
||||
| KEYWORD_FN_PTR_CALL | KEYWORD_FN_PTR_CURRY | KEYWORD_IS_DEF_VAR => true,
|
||||
|
||||
@ -2051,8 +2047,8 @@ pub fn is_valid_identifier(name: impl Iterator<Item = char>) -> bool {
|
||||
/// Is a text string a valid script-defined function name?
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn is_valid_function_name(name: impl AsRef<str>) -> bool {
|
||||
is_valid_identifier(name.as_ref().chars())
|
||||
pub fn is_valid_function_name(name: &str) -> bool {
|
||||
is_valid_identifier(name.chars())
|
||||
}
|
||||
|
||||
/// Is a character valid to start an identifier?
|
||||
|
@ -8,12 +8,11 @@ use std::prelude::v1::*;
|
||||
/// _(internals)_ A factory of identifiers from text strings.
|
||||
/// Exported under the `internals` feature only.
|
||||
///
|
||||
/// Normal identifiers are not interned since they use `SmartString` because most identifiers in
|
||||
/// Rhai are short and ASCII-based. Thus copying is relatively fast.
|
||||
///
|
||||
/// Property getters and setters are interned separately.
|
||||
/// Normal identifiers, property getters and setters are interned separately.
|
||||
#[derive(Debug, Clone, Default, Hash)]
|
||||
pub struct StringsInterner {
|
||||
/// Normal strings.
|
||||
strings: std::collections::BTreeMap<Identifier, ImmutableString>,
|
||||
/// Property getters.
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
getters: std::collections::BTreeMap<Identifier, ImmutableString>,
|
||||
@ -28,6 +27,7 @@ impl StringsInterner {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
strings: std::collections::BTreeMap::new(),
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
getters: std::collections::BTreeMap::new(),
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
@ -36,67 +36,62 @@ impl StringsInterner {
|
||||
}
|
||||
/// Get an identifier from a text string and prefix, adding it to the interner if necessary.
|
||||
///
|
||||
/// # Prefix
|
||||
///
|
||||
/// Currently recognized prefixes are:
|
||||
///
|
||||
/// * `""` - None (normal string)
|
||||
/// * `"get$"` - Property getter, not available under `no_object`
|
||||
/// * `"set$"` - Property setter, not available under `no_object`
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the prefix is not recognized.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn get(
|
||||
&mut self,
|
||||
prefix: &'static str,
|
||||
text: impl AsRef<str> + Into<Identifier> + Into<ImmutableString>,
|
||||
) -> ImmutableString {
|
||||
pub fn get(&mut self, prefix: impl AsRef<str>, text: impl AsRef<str>) -> ImmutableString {
|
||||
let (dict, mapper): (_, fn(&str) -> Identifier) = match prefix.as_ref() {
|
||||
"" => (&mut self.strings, |s| s.into()),
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
{
|
||||
let (dict, mapper) = match prefix {
|
||||
"" => return text.into(),
|
||||
FN_GET => (&mut self.getters, make_getter as fn(&str) -> String),
|
||||
FN_SET => (&mut self.setters, make_setter as fn(&str) -> String),
|
||||
_ => unreachable!("unsupported prefix {}", prefix),
|
||||
FN_GET => (&mut self.getters, |s| make_getter(s)),
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
FN_SET => (&mut self.setters, |s| make_setter(s)),
|
||||
|
||||
_ => unreachable!("unsupported prefix {}", prefix.as_ref()),
|
||||
};
|
||||
|
||||
if dict.contains_key(text.as_ref()) {
|
||||
self.getters.get(text.as_ref()).expect("exists").clone()
|
||||
dict.get(text.as_ref()).expect("exists").clone()
|
||||
} else {
|
||||
let value: ImmutableString = mapper(text.as_ref()).into();
|
||||
let text = text.into();
|
||||
dict.insert(text, value.clone());
|
||||
dict.insert(text.as_ref().into(), value.clone());
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "no_object")]
|
||||
match prefix {
|
||||
"" => return text.into(),
|
||||
_ => unreachable!("unsupported prefix {}", prefix),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<Self> for StringsInterner {
|
||||
#[inline(always)]
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
let _rhs = rhs;
|
||||
|
||||
self.strings.extend(rhs.strings.into_iter());
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
{
|
||||
self.getters.extend(_rhs.getters.into_iter());
|
||||
self.setters.extend(_rhs.setters.into_iter());
|
||||
}
|
||||
self.getters.extend(rhs.getters.into_iter());
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
self.setters.extend(rhs.setters.into_iter());
|
||||
}
|
||||
}
|
||||
|
||||
impl AddAssign<&Self> for StringsInterner {
|
||||
#[inline(always)]
|
||||
fn add_assign(&mut self, rhs: &Self) {
|
||||
let _rhs = rhs;
|
||||
|
||||
self.strings
|
||||
.extend(rhs.strings.iter().map(|(k, v)| (k.clone(), v.clone())));
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
{
|
||||
self.getters
|
||||
.extend(_rhs.getters.iter().map(|(k, v)| (k.clone(), v.clone())));
|
||||
.extend(rhs.getters.iter().map(|(k, v)| (k.clone(), v.clone())));
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
self.setters
|
||||
.extend(_rhs.setters.iter().map(|(k, v)| (k.clone(), v.clone())));
|
||||
}
|
||||
.extend(rhs.setters.iter().map(|(k, v)| (k.clone(), v.clone())));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user