reduce cloning in argument evaluation

This commit is contained in:
connorskees 2023-01-08 15:05:59 +00:00
parent bf0d912dc8
commit f321f36faf
3 changed files with 56 additions and 53 deletions

View File

@ -78,8 +78,8 @@ impl CssTree {
}
fn add_child_to_parent(&self, child: CssStmt, parent_idx: CssTreeIdx) {
let mut parent = self.stmts[parent_idx.0].borrow_mut().take();
match &mut parent {
RefMut::map(self.stmts[parent_idx.0].borrow_mut(), |parent| {
match parent {
Some(CssStmt::RuleSet { body, .. }) => body.push(child),
Some(CssStmt::Style(..) | CssStmt::Comment(..) | CssStmt::Import(..)) | None => {
unreachable!()
@ -96,10 +96,9 @@ impl CssTree {
Some(CssStmt::KeyframesRuleSet(keyframes)) => {
keyframes.body.push(child);
}
}
self.stmts[parent_idx.0]
.borrow_mut()
.replace(parent.unwrap());
};
parent
});
}
pub fn add_child(&mut self, child: CssStmt, parent_idx: CssTreeIdx) -> CssTreeIdx {

View File

@ -2125,23 +2125,22 @@ impl<'a> Visitor<'a> {
evaluated.span,
)?;
// todo: superfluous clone
let declared_arguments = func.arguments().args.clone();
let declared_arguments = &func.arguments().args;
let min_len = evaluated.positional.len().min(declared_arguments.len());
let positional_len = evaluated.positional.len();
#[allow(clippy::needless_range_loop)]
for i in 0..min_len {
// todo: superfluous clone
for i in (0..min_len).rev() {
visitor.env.scopes_mut().insert_var_last(
declared_arguments[i].name,
evaluated.positional[i].clone(),
evaluated.positional.remove(i),
);
}
// todo: better name for var
let additional_declared_args =
if declared_arguments.len() > evaluated.positional.len() {
&declared_arguments[evaluated.positional.len()..declared_arguments.len()]
let additional_declared_args = if declared_arguments.len() > positional_len {
&declared_arguments[positional_len..declared_arguments.len()]
} else {
&[]
};
@ -2161,17 +2160,19 @@ impl<'a> Visitor<'a> {
let were_keywords_accessed = Arc::new(Cell::new(false));
let argument_list = if let Some(rest_arg) = func.arguments().rest {
let rest = if evaluated.positional.len() > declared_arguments.len() {
&evaluated.positional[declared_arguments.len()..]
let num_named_args = evaluated.named.len();
let has_arg_list = if let Some(rest_arg) = func.arguments().rest {
let rest = if evaluated.positional.len() > 0 {
evaluated.positional
} else {
&[]
Vec::new()
};
let arg_list = Value::ArgList(ArgList::new(
rest.to_vec(),
// todo: superfluous clone
rest,
Arc::clone(&were_keywords_accessed),
// todo: superfluous clone
evaluated.named.clone(),
if evaluated.separator == ListSeparator::Undecided {
ListSeparator::Comma
@ -2180,20 +2181,16 @@ impl<'a> Visitor<'a> {
},
));
visitor
.env
.scopes_mut()
// todo: superfluous clone
.insert_var_last(rest_arg, arg_list.clone());
visitor.env.scopes_mut().insert_var_last(rest_arg, arg_list);
Some(arg_list)
true
} else {
None
false
};
let val = run(func, visitor)?;
if argument_list.is_none() || evaluated.named.is_empty() {
if !has_arg_list || num_named_args == 0 {
return Ok(val);
}
@ -2201,7 +2198,7 @@ impl<'a> Visitor<'a> {
return Ok(val);
}
let argument_word = if evaluated.named.len() == 1 {
let argument_word = if num_named_args == 1 {
"argument"
} else {
"arguments"

View File

@ -13,8 +13,8 @@ use crate::{
},
utils::hex_char_for,
value::{
fuzzy_equals, ArgList, CalculationArg, SassCalculation, SassFunction, SassMap, SassNumber,
Value,
fuzzy_equals, ArgList, CalculationArg, CalculationName, SassCalculation, SassFunction,
SassMap, SassNumber, Value,
},
Options,
};
@ -299,10 +299,17 @@ impl<'a> Serializer<'a> {
self.write_optional_space();
}
fn write_calculation_name(&mut self, name: CalculationName) {
match name {
CalculationName::Calc => self.buffer.extend_from_slice(b"calc"),
CalculationName::Min => self.buffer.extend_from_slice(b"min"),
CalculationName::Max => self.buffer.extend_from_slice(b"max"),
CalculationName::Clamp => self.buffer.extend_from_slice(b"clamp"),
}
}
fn visit_calculation(&mut self, calculation: &SassCalculation) -> SassResult<()> {
// todo: superfluous allocation
self.buffer
.extend_from_slice(calculation.name.to_string().as_bytes());
self.write_calculation_name(calculation.name);
self.buffer.push(b'(');
if let Some((last, slice)) = calculation.args.split_last() {