Use ImmutableString in more places.

This commit is contained in:
Stephen Chung 2022-10-29 14:59:20 +08:00
parent 8e35f98477
commit 91415b9750
11 changed files with 45 additions and 85 deletions

View File

@ -442,8 +442,8 @@ impl Module {
if f.access != FnAccess::Private { if f.access != FnAccess::Private {
#[cfg(not(feature = "no_custom_syntax"))] #[cfg(not(feature = "no_custom_syntax"))]
let operator = def.engine.custom_keywords.contains_key(&f.name) let operator = def.engine.custom_keywords.contains_key(f.name.as_str())
|| (!f.name.contains('$') && !is_valid_function_name(&f.name)); || (!f.name.contains('$') && !is_valid_function_name(f.name.as_str()));
#[cfg(feature = "no_custom_syntax")] #[cfg(feature = "no_custom_syntax")]
let operator = !f.name.contains('$') && !is_valid_function_name(&f.name); let operator = !f.name.contains('$') && !is_valid_function_name(&f.name);

View File

@ -619,7 +619,7 @@ impl Expr {
if !x.is_qualified() && x.args.len() == 1 && x.name == KEYWORD_FN_PTR => if !x.is_qualified() && x.args.len() == 1 && x.name == KEYWORD_FN_PTR =>
{ {
if let Self::StringConstant(ref s, ..) = x.args[0] { if let Self::StringConstant(ref s, ..) = x.args[0] {
FnPtr::new(s).ok()?.into() FnPtr::new(s.clone()).ok()?.into()
} else { } else {
return None; return None;
} }

View File

@ -516,7 +516,7 @@ fn debug_callback(
if range.contains(&n) { if range.contains(&n) {
let bp = rhai::debugger::BreakPoint::AtPosition { let bp = rhai::debugger::BreakPoint::AtPosition {
source: source.unwrap_or("").into(), source: source.map(|s| s.into()),
pos: Position::new(n as u16, 0), pos: Position::new(n as u16, 0),
enabled: true, enabled: true,
}; };
@ -546,7 +546,7 @@ fn debug_callback(
#[cfg(not(feature = "no_position"))] #[cfg(not(feature = "no_position"))]
["break" | "b"] => { ["break" | "b"] => {
let bp = rhai::debugger::BreakPoint::AtPosition { let bp = rhai::debugger::BreakPoint::AtPosition {
source: source.unwrap_or("").into(), source: source.map(|s| s.into()),
pos, pos,
enabled: true, enabled: true,
}; };

View File

@ -4,8 +4,7 @@
use super::{EvalContext, GlobalRuntimeState}; use super::{EvalContext, GlobalRuntimeState};
use crate::ast::{ASTNode, Expr, Stmt}; use crate::ast::{ASTNode, Expr, Stmt};
use crate::{ use crate::{
Dynamic, Engine, EvalAltResult, Identifier, ImmutableString, Module, Position, RhaiResultOf, Dynamic, Engine, EvalAltResult, ImmutableString, Module, Position, RhaiResultOf, Scope,
Scope,
}; };
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -103,12 +102,10 @@ pub enum BreakPoint {
/// Break at a particular position under a particular source. /// Break at a particular position under a particular source.
/// ///
/// Not available under `no_position`. /// Not available under `no_position`.
///
/// Source is empty if not available.
#[cfg(not(feature = "no_position"))] #[cfg(not(feature = "no_position"))]
AtPosition { AtPosition {
/// Source (empty if not available) of the break-point. /// Source (empty if not available) of the break-point.
source: Identifier, source: Option<ImmutableString>,
/// [Position] of the break-point. /// [Position] of the break-point.
pos: Position, pos: Position,
/// Is the break-point enabled? /// Is the break-point enabled?
@ -117,14 +114,14 @@ pub enum BreakPoint {
/// Break at a particular function call. /// Break at a particular function call.
AtFunctionName { AtFunctionName {
/// Function name. /// Function name.
name: Identifier, name: ImmutableString,
/// Is the break-point enabled? /// Is the break-point enabled?
enabled: bool, enabled: bool,
}, },
/// Break at a particular function call with a particular number of arguments. /// Break at a particular function call with a particular number of arguments.
AtFunctionCall { AtFunctionCall {
/// Function name. /// Function name.
name: Identifier, name: ImmutableString,
/// Number of arguments. /// Number of arguments.
args: usize, args: usize,
/// Is the break-point enabled? /// Is the break-point enabled?
@ -136,7 +133,7 @@ pub enum BreakPoint {
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
AtProperty { AtProperty {
/// Property name. /// Property name.
name: Identifier, name: ImmutableString,
/// Is the break-point enabled? /// Is the break-point enabled?
enabled: bool, enabled: bool,
}, },
@ -151,7 +148,7 @@ impl fmt::Display for BreakPoint {
pos, pos,
enabled, enabled,
} => { } => {
if !source.is_empty() { if let Some(ref source) = source {
write!(f, "{source} ")?; write!(f, "{source} ")?;
} }
write!(f, "@ {pos:?}")?; write!(f, "@ {pos:?}")?;
@ -226,7 +223,7 @@ impl BreakPoint {
#[derive(Debug, Clone, Hash)] #[derive(Debug, Clone, Hash)]
pub struct CallStackFrame { pub struct CallStackFrame {
/// Function name. /// Function name.
pub fn_name: Identifier, pub fn_name: ImmutableString,
/// Copies of function call arguments, if any. /// Copies of function call arguments, if any.
pub args: crate::StaticVec<Dynamic>, pub args: crate::StaticVec<Dynamic>,
/// Source of the function. /// Source of the function.
@ -296,7 +293,7 @@ impl Debugger {
#[inline(always)] #[inline(always)]
pub(crate) fn push_call_stack_frame( pub(crate) fn push_call_stack_frame(
&mut self, &mut self,
fn_name: impl Into<Identifier>, fn_name: ImmutableString,
args: crate::StaticVec<Dynamic>, args: crate::StaticVec<Dynamic>,
source: Option<ImmutableString>, source: Option<ImmutableString>,
pos: Position, pos: Position,
@ -331,7 +328,7 @@ impl Debugger {
} }
/// Returns the first break-point triggered by a particular [`AST` Node][ASTNode]. /// Returns the first break-point triggered by a particular [`AST` Node][ASTNode].
#[must_use] #[must_use]
pub fn is_break_point(&self, src: &str, node: ASTNode) -> Option<usize> { pub fn is_break_point(&self, src: Option<&str>, node: ASTNode) -> Option<usize> {
let _src = src; let _src = src;
self.break_points() self.break_points()
@ -343,11 +340,12 @@ impl Debugger {
BreakPoint::AtPosition { pos, .. } if pos.is_none() => false, BreakPoint::AtPosition { pos, .. } if pos.is_none() => false,
#[cfg(not(feature = "no_position"))] #[cfg(not(feature = "no_position"))]
BreakPoint::AtPosition { source, pos, .. } if pos.is_beginning_of_line() => { BreakPoint::AtPosition { source, pos, .. } if pos.is_beginning_of_line() => {
node.position().line().unwrap_or(0) == pos.line().unwrap() && _src == source node.position().line().unwrap_or(0) == pos.line().unwrap()
&& _src == source.as_ref().map(|s| s.as_str())
} }
#[cfg(not(feature = "no_position"))] #[cfg(not(feature = "no_position"))]
BreakPoint::AtPosition { source, pos, .. } => { BreakPoint::AtPosition { source, pos, .. } => {
node.position() == *pos && _src == source node.position() == *pos && _src == source.as_ref().map(|s| s.as_str())
} }
BreakPoint::AtFunctionName { name, .. } => match node { BreakPoint::AtFunctionName { name, .. } => match node {
ASTNode::Expr(Expr::FnCall(x, ..)) | ASTNode::Stmt(Stmt::FnCall(x, ..)) => { ASTNode::Expr(Expr::FnCall(x, ..)) | ASTNode::Stmt(Stmt::FnCall(x, ..)) => {
@ -490,10 +488,7 @@ impl Engine {
let event = match event { let event = match event {
Some(e) => e, Some(e) => e,
None => match global None => match global.debugger.is_break_point(global.source(), node) {
.debugger
.is_break_point(global.source().unwrap_or(""), node)
{
Some(bp) => DebuggerEvent::BreakPoint(bp), Some(bp) => DebuggerEvent::BreakPoint(bp),
None => return Ok(None), None => return Ok(None),
}, },

View File

@ -400,7 +400,7 @@ impl Engine {
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
if self.debugger.is_some() { if self.debugger.is_some() {
global.debugger.push_call_stack_frame( global.debugger.push_call_stack_frame(
name, self.get_interned_string(name),
args.iter().map(|v| (*v).clone()).collect(), args.iter().map(|v| (*v).clone()).collect(),
source.clone().or_else(|| global.source.clone()), source.clone().or_else(|| global.source.clone()),
pos, pos,

View File

@ -72,7 +72,7 @@ pub struct FuncInfo {
/// Function access mode. /// Function access mode.
pub access: FnAccess, pub access: FnAccess,
/// Function name. /// Function name.
pub name: Identifier, pub name: ImmutableString,
/// Number of parameters. /// Number of parameters.
pub num_params: usize, pub num_params: usize,
/// Parameter types (if applicable). /// Parameter types (if applicable).

View File

@ -40,7 +40,7 @@ mod debugging_functions {
.iter() .iter()
.rev() .rev()
.filter(|crate::debugger::CallStackFrame { fn_name, args, .. }| { .filter(|crate::debugger::CallStackFrame { fn_name, args, .. }| {
fn_name != "back_trace" || !args.is_empty() fn_name.as_str() != "back_trace" || !args.is_empty()
}) })
.map( .map(
|frame @ crate::debugger::CallStackFrame { |frame @ crate::debugger::CallStackFrame {

View File

@ -27,7 +27,7 @@ mod fn_ptr_functions {
/// ``` /// ```
#[rhai_fn(name = "name", get = "name", pure)] #[rhai_fn(name = "name", get = "name", pure)]
pub fn name(fn_ptr: &mut FnPtr) -> ImmutableString { pub fn name(fn_ptr: &mut FnPtr) -> ImmutableString {
fn_ptr.fn_name_raw().into() fn_ptr.fn_name_raw().clone()
} }
/// Return `true` if the function is an anonymous function. /// Return `true` if the function is an anonymous function.

View File

@ -35,7 +35,7 @@ fn check_struct_sizes() {
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
{ {
assert_eq!(size_of::<Scope>(), 536); assert_eq!(size_of::<Scope>(), 536);
assert_eq!(size_of::<FnPtr>(), 80); assert_eq!(size_of::<FnPtr>(), 64);
assert_eq!(size_of::<LexError>(), 56); assert_eq!(size_of::<LexError>(), 56);
assert_eq!( assert_eq!(
size_of::<ParseError>(), size_of::<ParseError>(),

View File

@ -3,7 +3,7 @@
use crate::tokenizer::is_valid_identifier; use crate::tokenizer::is_valid_identifier;
use crate::types::dynamic::Variant; use crate::types::dynamic::Variant;
use crate::{ use crate::{
Dynamic, Engine, FuncArgs, Identifier, Module, NativeCallContext, Position, RhaiError, Dynamic, Engine, FuncArgs, ImmutableString, Module, NativeCallContext, Position, RhaiError,
RhaiResult, RhaiResultOf, StaticVec, AST, ERR, RhaiResult, RhaiResultOf, StaticVec, AST, ERR,
}; };
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
@ -18,7 +18,7 @@ use std::{
/// to be passed onto a function during a call. /// to be passed onto a function during a call.
#[derive(Clone, Hash)] #[derive(Clone, Hash)]
pub struct FnPtr { pub struct FnPtr {
name: Identifier, name: ImmutableString,
curry: StaticVec<Dynamic>, curry: StaticVec<Dynamic>,
} }
@ -42,13 +42,16 @@ impl fmt::Debug for FnPtr {
impl FnPtr { impl FnPtr {
/// Create a new function pointer. /// Create a new function pointer.
#[inline(always)] #[inline(always)]
pub fn new(name: impl Into<Identifier>) -> RhaiResultOf<Self> { pub fn new(name: impl Into<ImmutableString>) -> RhaiResultOf<Self> {
name.into().try_into() name.into().try_into()
} }
/// Create a new function pointer without checking its parameters. /// Create a new function pointer without checking its parameters.
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub(crate) fn new_unchecked(name: impl Into<Identifier>, curry: StaticVec<Dynamic>) -> Self { pub(crate) fn new_unchecked(
name: impl Into<ImmutableString>,
curry: StaticVec<Dynamic>,
) -> Self {
Self { Self {
name: name.into(), name: name.into(),
curry, curry,
@ -63,13 +66,13 @@ impl FnPtr {
/// Get the name of the function. /// Get the name of the function.
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub(crate) const fn fn_name_raw(&self) -> &Identifier { pub(crate) const fn fn_name_raw(&self) -> &ImmutableString {
&self.name &self.name
} }
/// Get the underlying data of the function pointer. /// Get the underlying data of the function pointer.
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub(crate) fn take_data(self) -> (Identifier, StaticVec<Dynamic>) { pub(crate) fn take_data(self) -> (ImmutableString, StaticVec<Dynamic>) {
(self.name, self.curry) (self.name, self.curry)
} }
/// Get the curried arguments. /// Get the curried arguments.
@ -246,11 +249,11 @@ impl fmt::Display for FnPtr {
} }
} }
impl TryFrom<Identifier> for FnPtr { impl TryFrom<ImmutableString> for FnPtr {
type Error = RhaiError; type Error = RhaiError;
#[inline] #[inline(always)]
fn try_from(value: Identifier) -> RhaiResultOf<Self> { fn try_from(value: ImmutableString) -> RhaiResultOf<Self> {
if is_valid_identifier(value.chars()) { if is_valid_identifier(value.chars()) {
Ok(Self { Ok(Self {
name: value, name: value,
@ -261,43 +264,3 @@ impl TryFrom<Identifier> for FnPtr {
} }
} }
} }
impl TryFrom<crate::ImmutableString> for FnPtr {
type Error = RhaiError;
#[inline(always)]
fn try_from(value: crate::ImmutableString) -> RhaiResultOf<Self> {
let s: Identifier = value.into();
Self::try_from(s)
}
}
impl TryFrom<String> for FnPtr {
type Error = RhaiError;
#[inline(always)]
fn try_from(value: String) -> RhaiResultOf<Self> {
let s: Identifier = value.into();
Self::try_from(s)
}
}
impl TryFrom<Box<str>> for FnPtr {
type Error = RhaiError;
#[inline(always)]
fn try_from(value: Box<str>) -> RhaiResultOf<Self> {
let s: Identifier = value.into();
Self::try_from(s)
}
}
impl TryFrom<&str> for FnPtr {
type Error = RhaiError;
#[inline(always)]
fn try_from(value: &str) -> RhaiResultOf<Self> {
let s: Identifier = value.into();
Self::try_from(s)
}
}

View File

@ -1,7 +1,7 @@
//! Module that defines the [`Scope`] type representing a function call-stack scope. //! Module that defines the [`Scope`] type representing a function call-stack scope.
use super::dynamic::{AccessMode, Variant}; use super::dynamic::{AccessMode, Variant};
use crate::{Dynamic, Identifier}; use crate::{Dynamic, Identifier, ImmutableString};
use smallvec::SmallVec; use smallvec::SmallVec;
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
@ -75,7 +75,7 @@ pub struct Scope<'a, const N: usize = SCOPE_ENTRIES_INLINED> {
/// Name of the entry. /// Name of the entry.
names: SmallVec<[Identifier; SCOPE_ENTRIES_INLINED]>, names: SmallVec<[Identifier; SCOPE_ENTRIES_INLINED]>,
/// Aliases of the entry. /// Aliases of the entry.
aliases: SmallVec<[Vec<Identifier>; SCOPE_ENTRIES_INLINED]>, aliases: SmallVec<[Vec<ImmutableString>; SCOPE_ENTRIES_INLINED]>,
/// Phantom to keep the lifetime parameter in order not to break existing code. /// Phantom to keep the lifetime parameter in order not to break existing code.
dummy: PhantomData<&'a ()>, dummy: PhantomData<&'a ()>,
} }
@ -125,7 +125,7 @@ impl Clone for Scope<'_> {
} }
impl IntoIterator for Scope<'_> { impl IntoIterator for Scope<'_> {
type Item = (String, Dynamic, Vec<Identifier>); type Item = (String, Dynamic, Vec<ImmutableString>);
type IntoIter = Box<dyn Iterator<Item = Self::Item>>; type IntoIter = Box<dyn Iterator<Item = Self::Item>>;
#[must_use] #[must_use]
@ -140,7 +140,7 @@ impl IntoIterator for Scope<'_> {
} }
impl<'a> IntoIterator for &'a Scope<'_> { impl<'a> IntoIterator for &'a Scope<'_> {
type Item = (&'a Identifier, &'a Dynamic, &'a Vec<Identifier>); type Item = (&'a Identifier, &'a Dynamic, &'a Vec<ImmutableString>);
type IntoIter = Box<dyn Iterator<Item = Self::Item> + 'a>; type IntoIter = Box<dyn Iterator<Item = Self::Item> + 'a>;
#[must_use] #[must_use]
@ -669,7 +669,7 @@ impl Scope<'_> {
/// Panics if the index is out of bounds. /// Panics if the index is out of bounds.
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
#[inline] #[inline]
pub(crate) fn add_alias_by_index(&mut self, index: usize, alias: Identifier) -> &mut Self { pub(crate) fn add_alias_by_index(&mut self, index: usize, alias: ImmutableString) -> &mut Self {
let aliases = self.aliases.get_mut(index).unwrap(); let aliases = self.aliases.get_mut(index).unwrap();
if aliases.is_empty() || !aliases.contains(&alias) { if aliases.is_empty() || !aliases.contains(&alias) {
aliases.push(alias); aliases.push(alias);
@ -690,11 +690,11 @@ impl Scope<'_> {
pub fn set_alias( pub fn set_alias(
&mut self, &mut self,
name: impl AsRef<str> + Into<Identifier>, name: impl AsRef<str> + Into<Identifier>,
alias: impl Into<Identifier>, alias: impl Into<ImmutableString>,
) { ) {
if let Some(index) = self.search(name.as_ref()) { if let Some(index) = self.search(name.as_ref()) {
let alias = match alias.into() { let alias = match alias.into() {
x if x.is_empty() => name.into(), x if x.is_empty() => name.into().into(),
x => x, x => x,
}; };
self.add_alias_by_index(index, alias); self.add_alias_by_index(index, alias);
@ -727,7 +727,9 @@ impl Scope<'_> {
} }
/// Get an iterator to entries in the [`Scope`]. /// Get an iterator to entries in the [`Scope`].
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn into_iter(self) -> impl Iterator<Item = (Identifier, Dynamic, Vec<Identifier>)> { pub(crate) fn into_iter(
self,
) -> impl Iterator<Item = (Identifier, Dynamic, Vec<ImmutableString>)> {
self.names self.names
.into_iter() .into_iter()
.zip(self.values.into_iter().zip(self.aliases.into_iter())) .zip(self.values.into_iter().zip(self.aliases.into_iter()))