Reduce size of Variant trait.

This commit is contained in:
Stephen Chung 2022-01-01 19:54:46 +08:00
parent a6ddb64596
commit d60ed5a502
6 changed files with 38 additions and 46 deletions

View File

@ -57,10 +57,19 @@ pub const FN_IDX_SET: &str = "index$set$";
pub const FN_ANONYMOUS: &str = "anon$"; pub const FN_ANONYMOUS: &str = "anon$";
/// Standard equality comparison operator. /// Standard equality comparison operator.
///
/// Some standard functions (e.g. searching an [`Array`][crate::Array]) implicitly call this
/// function to compare two [`Dynamic`] values.
pub const OP_EQUALS: &str = Token::EqualsTo.literal_syntax(); pub const OP_EQUALS: &str = Token::EqualsTo.literal_syntax();
/// Standard method function for containment testing. /// Standard concatenation operator.
/// The `in` operator is implemented as a call to this method. ///
/// Used primarily to build up interpolated strings.
pub const OP_CONCAT: &str = Token::PlusAssign.literal_syntax();
/// Standard containment testing function.
///
/// The `in` operator is implemented as a call to this function.
pub const OP_CONTAINS: &str = "contains"; pub const OP_CONTAINS: &str = "contains";
/// Standard exclusive range operator. /// Standard exclusive range operator.
@ -69,9 +78,6 @@ pub const OP_EXCLUSIVE_RANGE: &str = Token::ExclusiveRange.literal_syntax();
/// Standard inclusive range operator. /// Standard inclusive range operator.
pub const OP_INCLUSIVE_RANGE: &str = Token::InclusiveRange.literal_syntax(); pub const OP_INCLUSIVE_RANGE: &str = Token::InclusiveRange.literal_syntax();
/// Standard concatenation operator token.
pub const OP_CONCAT: &str = Token::PlusAssign.literal_syntax();
/// Method of chaining. /// Method of chaining.
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]

View File

@ -61,7 +61,7 @@ pub trait FuncArgs {
impl<T: Variant + Clone> FuncArgs for Vec<T> { impl<T: Variant + Clone> FuncArgs for Vec<T> {
#[inline] #[inline]
fn parse<ARGS: Extend<Dynamic>>(self, args: &mut ARGS) { fn parse<ARGS: Extend<Dynamic>>(self, args: &mut ARGS) {
args.extend(self.into_iter().map(Variant::into_dynamic)); args.extend(self.into_iter().map(Dynamic::from));
} }
} }
@ -75,7 +75,7 @@ macro_rules! impl_args {
#[allow(unused_variables)] #[allow(unused_variables)]
fn parse<ARGS: Extend<Dynamic>>(self, args: &mut ARGS) { fn parse<ARGS: Extend<Dynamic>>(self, args: &mut ARGS) {
let ($($p,)*) = self; let ($($p,)*) = self;
$(args.extend(Some($p.into_dynamic()));)* $(args.extend(Some(Dynamic::from($p)));)*
} }
} }

View File

@ -135,7 +135,7 @@ macro_rules! def_register {
let r = self($($arg),*); let r = self($($arg),*);
// Map the result // Map the result
Ok(r.into_dynamic()) Ok(Dynamic::from(r))
}) as Box<FnAny>) }) as Box<FnAny>)
} }
} }
@ -163,7 +163,7 @@ macro_rules! def_register {
let r = self(ctx, $($arg),*); let r = self(ctx, $($arg),*);
// Map the result // Map the result
Ok(r.into_dynamic()) Ok(Dynamic::from(r))
}) as Box<FnAny>) }) as Box<FnAny>)
} }
} }

View File

@ -144,9 +144,7 @@ type InclusiveRange = std::ops::RangeInclusive<INT>;
pub use api::custom_syntax::Expression; pub use api::custom_syntax::Expression;
pub use ast::{FnAccess, AST}; pub use ast::{FnAccess, AST};
pub use engine::{ pub use engine::{Engine, EvalContext, OP_CONTAINS, OP_EQUALS};
Engine, EvalContext, OP_CONTAINS, OP_EQUALS, OP_EXCLUSIVE_RANGE, OP_INCLUSIVE_RANGE,
};
pub use func::{NativeCallContext, RegisterNativeFunction}; pub use func::{NativeCallContext, RegisterNativeFunction};
pub use module::{FnNamespace, Module}; pub use module::{FnNamespace, Module};
pub use tokenizer::Position; pub use tokenizer::Position;

View File

@ -1026,7 +1026,7 @@ pub trait InputStream {
fn peek_next(&mut self) -> Option<char>; fn peek_next(&mut self) -> Option<char>;
} }
/// _(internals)_ Parse a string literal ended by `termination_char`. /// _(internals)_ Parse a string literal ended by a specified termination character.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
/// ///
/// Returns the parsed string and a boolean indicating whether the string is /// Returns the parsed string and a boolean indicating whether the string is
@ -1034,7 +1034,7 @@ pub trait InputStream {
/// ///
/// # Returns /// # Returns
/// ///
/// |Type |Return Value |`state.is_within_text_terminated_by`| /// | Type | Return Value |`state.is_within_text_terminated_by`|
/// |---------------------------------|:--------------------------:|:----------------------------------:| /// |---------------------------------|:--------------------------:|:----------------------------------:|
/// |`"hello"` |`StringConstant("hello")` |`None` | /// |`"hello"` |`StringConstant("hello")` |`None` |
/// |`"hello`_{LF}_ or _{EOF}_ |`LexError` |`None` | /// |`"hello`_{LF}_ or _{EOF}_ |`LexError` |`None` |
@ -1061,8 +1061,8 @@ pub fn parse_string_literal(
state: &mut TokenizeState, state: &mut TokenizeState,
pos: &mut Position, pos: &mut Position,
termination_char: char, termination_char: char,
continuation: bool,
verbatim: bool, verbatim: bool,
allow_line_continuation: bool,
allow_interpolation: bool, allow_interpolation: bool,
) -> Result<(Box<str>, bool), (LexError, Position)> { ) -> Result<(Box<str>, bool), (LexError, Position)> {
let mut result = String::with_capacity(12); let mut result = String::with_capacity(12);
@ -1091,7 +1091,7 @@ pub fn parse_string_literal(
pos.advance(); pos.advance();
break; break;
} }
None if continuation && !escape.is_empty() => { None if allow_line_continuation && !escape.is_empty() => {
assert_eq!(escape, "\\", "unexpected escape {} at end of line", escape); assert_eq!(escape, "\\", "unexpected escape {} at end of line", escape);
pos.advance(); pos.advance();
break; break;
@ -1211,7 +1211,7 @@ pub fn parse_string_literal(
} }
// Line continuation // Line continuation
'\n' if continuation && !escape.is_empty() => { '\n' if allow_line_continuation && !escape.is_empty() => {
assert_eq!(escape, "\\", "unexpected escape {} at end of line", escape); assert_eq!(escape, "\\", "unexpected escape {} at end of line", escape);
escape.clear(); escape.clear();
pos.new_line(); pos.new_line();
@ -1319,7 +1319,7 @@ fn scan_block_comment(
level level
} }
/// _(internals)_ Get the next token from the `stream`. /// _(internals)_ Get the next token from the input stream.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[inline] #[inline]
#[must_use] #[must_use]
@ -1400,7 +1400,7 @@ fn get_next_token_inner(
if let Some(ch) = state.is_within_text_terminated_by.take() { if let Some(ch) = state.is_within_text_terminated_by.take() {
let start_pos = *pos; let start_pos = *pos;
return parse_string_literal(stream, state, pos, ch, false, true, true).map_or_else( return parse_string_literal(stream, state, pos, ch, true, false, true).map_or_else(
|(err, err_pos)| Some((Token::LexError(err), err_pos)), |(err, err_pos)| Some((Token::LexError(err), err_pos)),
|(result, interpolated)| { |(result, interpolated)| {
if interpolated { if interpolated {
@ -1584,7 +1584,7 @@ fn get_next_token_inner(
// " - string literal // " - string literal
('"', _) => { ('"', _) => {
return parse_string_literal(stream, state, pos, c, true, false, false) return parse_string_literal(stream, state, pos, c, false, true, false)
.map_or_else( .map_or_else(
|(err, err_pos)| Some((Token::LexError(err), err_pos)), |(err, err_pos)| Some((Token::LexError(err), err_pos)),
|(result, _)| Some((Token::StringConstant(result), start_pos)), |(result, _)| Some((Token::StringConstant(result), start_pos)),
@ -1611,7 +1611,7 @@ fn get_next_token_inner(
_ => (), _ => (),
} }
return parse_string_literal(stream, state, pos, c, false, true, true).map_or_else( return parse_string_literal(stream, state, pos, c, true, false, true).map_or_else(
|(err, err_pos)| Some((Token::LexError(err), err_pos)), |(err, err_pos)| Some((Token::LexError(err), err_pos)),
|(result, interpolated)| { |(result, interpolated)| {
if interpolated { if interpolated {

View File

@ -52,7 +52,7 @@ pub trait Variant: Any + private::Sealed {
#[must_use] #[must_use]
fn as_mut_any(&mut self) -> &mut dyn Any; fn as_mut_any(&mut self) -> &mut dyn Any;
/// Convert this [`Variant`] trait object to an [`Any`] trait object. /// Convert this [`Variant`] trait object to [`Box<dyn Any>`].
#[must_use] #[must_use]
fn as_box_any(self: Box<Self>) -> Box<dyn Any>; fn as_box_any(self: Box<Self>) -> Box<dyn Any>;
@ -60,13 +60,9 @@ pub trait Variant: Any + private::Sealed {
#[must_use] #[must_use]
fn type_name(&self) -> &'static str; fn type_name(&self) -> &'static str;
/// Convert into [`Dynamic`]. /// Clone this [`Variant`] trait object.
#[must_use] #[must_use]
fn into_dynamic(self) -> Dynamic; fn clone_object(&self) -> Box<dyn Variant>;
/// Clone into [`Dynamic`].
#[must_use]
fn clone_into_dynamic(&self) -> Dynamic;
} }
/// _(internals)_ Trait to represent any type. /// _(internals)_ Trait to represent any type.
@ -83,7 +79,7 @@ pub trait Variant: Any + Send + Sync + private::Sealed {
#[must_use] #[must_use]
fn as_mut_any(&mut self) -> &mut dyn Any; fn as_mut_any(&mut self) -> &mut dyn Any;
/// Convert this [`Variant`] trait object to an [`Any`] trait object. /// Convert this [`Variant`] trait object to [`Box<dyn Any>`].
#[must_use] #[must_use]
fn as_box_any(self: Box<Self>) -> Box<dyn Any>; fn as_box_any(self: Box<Self>) -> Box<dyn Any>;
@ -91,13 +87,9 @@ pub trait Variant: Any + Send + Sync + private::Sealed {
#[must_use] #[must_use]
fn type_name(&self) -> &'static str; fn type_name(&self) -> &'static str;
/// Convert into [`Dynamic`]. /// Clone this [`Variant`] trait object.
#[must_use] #[must_use]
fn into_dynamic(self) -> Dynamic; fn clone_object(&self) -> Box<dyn Variant>;
/// Clone into [`Dynamic`].
#[must_use]
fn clone_into_dynamic(&self) -> Dynamic;
} }
impl<T: Any + Clone + SendSync> Variant for T { impl<T: Any + Clone + SendSync> Variant for T {
@ -118,12 +110,8 @@ impl<T: Any + Clone + SendSync> Variant for T {
type_name::<T>() type_name::<T>()
} }
#[inline(always)] #[inline(always)]
fn into_dynamic(self) -> Dynamic { fn clone_object(&self) -> Box<dyn Variant> {
Dynamic::from(self) Box::new(self.clone()) as Box<dyn Variant>
}
#[inline(always)]
fn clone_into_dynamic(&self) -> Dynamic {
Dynamic::from(self.clone())
} }
} }
@ -818,11 +806,11 @@ impl Clone for Dynamic {
Self(Union::TimeStamp(value.clone(), tag, ReadWrite)) Self(Union::TimeStamp(value.clone(), tag, ReadWrite))
} }
Union::Variant(ref value, tag, _) => { Union::Variant(ref value, tag, _) => Self(Union::Variant(
let mut x = value.as_ref().as_ref().clone_into_dynamic(); value.as_ref().as_ref().clone_object().into(),
x.set_tag(tag); tag,
x ReadWrite,
} )),
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
Union::Shared(ref cell, tag, _) => Self(Union::Shared(cell.clone(), tag, ReadWrite)), Union::Shared(ref cell, tag, _) => Self(Union::Shared(cell.clone(), tag, ReadWrite)),