Fixup AsRef<str> vs &str.

This commit is contained in:
Stephen Chung 2022-01-04 15:22:48 +08:00
parent 1d1e473ac4
commit d99953c101
13 changed files with 181 additions and 181 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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