reduce cloning in argument evaluation
This commit is contained in:
parent
bf0d912dc8
commit
f321f36faf
@ -78,28 +78,27 @@ impl CssTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_child_to_parent(&self, child: CssStmt, parent_idx: CssTreeIdx) {
|
fn add_child_to_parent(&self, child: CssStmt, parent_idx: CssTreeIdx) {
|
||||||
let mut parent = self.stmts[parent_idx.0].borrow_mut().take();
|
RefMut::map(self.stmts[parent_idx.0].borrow_mut(), |parent| {
|
||||||
match &mut parent {
|
match parent {
|
||||||
Some(CssStmt::RuleSet { body, .. }) => body.push(child),
|
Some(CssStmt::RuleSet { body, .. }) => body.push(child),
|
||||||
Some(CssStmt::Style(..) | CssStmt::Comment(..) | CssStmt::Import(..)) | None => {
|
Some(CssStmt::Style(..) | CssStmt::Comment(..) | CssStmt::Import(..)) | None => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
Some(CssStmt::Media(media, ..)) => {
|
Some(CssStmt::Media(media, ..)) => {
|
||||||
media.body.push(child);
|
media.body.push(child);
|
||||||
}
|
}
|
||||||
Some(CssStmt::UnknownAtRule(at_rule, ..)) => {
|
Some(CssStmt::UnknownAtRule(at_rule, ..)) => {
|
||||||
at_rule.body.push(child);
|
at_rule.body.push(child);
|
||||||
}
|
}
|
||||||
Some(CssStmt::Supports(supports, ..)) => {
|
Some(CssStmt::Supports(supports, ..)) => {
|
||||||
supports.body.push(child);
|
supports.body.push(child);
|
||||||
}
|
}
|
||||||
Some(CssStmt::KeyframesRuleSet(keyframes)) => {
|
Some(CssStmt::KeyframesRuleSet(keyframes)) => {
|
||||||
keyframes.body.push(child);
|
keyframes.body.push(child);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
self.stmts[parent_idx.0]
|
parent
|
||||||
.borrow_mut()
|
});
|
||||||
.replace(parent.unwrap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_child(&mut self, child: CssStmt, parent_idx: CssTreeIdx) -> CssTreeIdx {
|
pub fn add_child(&mut self, child: CssStmt, parent_idx: CssTreeIdx) -> CssTreeIdx {
|
||||||
|
@ -2125,26 +2125,25 @@ impl<'a> Visitor<'a> {
|
|||||||
evaluated.span,
|
evaluated.span,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// todo: superfluous clone
|
let declared_arguments = &func.arguments().args;
|
||||||
let declared_arguments = func.arguments().args.clone();
|
|
||||||
let min_len = evaluated.positional.len().min(declared_arguments.len());
|
let min_len = evaluated.positional.len().min(declared_arguments.len());
|
||||||
|
|
||||||
|
let positional_len = evaluated.positional.len();
|
||||||
|
|
||||||
#[allow(clippy::needless_range_loop)]
|
#[allow(clippy::needless_range_loop)]
|
||||||
for i in 0..min_len {
|
for i in (0..min_len).rev() {
|
||||||
// todo: superfluous clone
|
|
||||||
visitor.env.scopes_mut().insert_var_last(
|
visitor.env.scopes_mut().insert_var_last(
|
||||||
declared_arguments[i].name,
|
declared_arguments[i].name,
|
||||||
evaluated.positional[i].clone(),
|
evaluated.positional.remove(i),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: better name for var
|
// todo: better name for var
|
||||||
let additional_declared_args =
|
let additional_declared_args = if declared_arguments.len() > positional_len {
|
||||||
if declared_arguments.len() > evaluated.positional.len() {
|
&declared_arguments[positional_len..declared_arguments.len()]
|
||||||
&declared_arguments[evaluated.positional.len()..declared_arguments.len()]
|
} else {
|
||||||
} else {
|
&[]
|
||||||
&[]
|
};
|
||||||
};
|
|
||||||
|
|
||||||
for argument in additional_declared_args {
|
for argument in additional_declared_args {
|
||||||
let name = argument.name;
|
let name = argument.name;
|
||||||
@ -2161,17 +2160,19 @@ impl<'a> Visitor<'a> {
|
|||||||
|
|
||||||
let were_keywords_accessed = Arc::new(Cell::new(false));
|
let were_keywords_accessed = Arc::new(Cell::new(false));
|
||||||
|
|
||||||
let argument_list = if let Some(rest_arg) = func.arguments().rest {
|
let num_named_args = evaluated.named.len();
|
||||||
let rest = if evaluated.positional.len() > declared_arguments.len() {
|
|
||||||
&evaluated.positional[declared_arguments.len()..]
|
let has_arg_list = if let Some(rest_arg) = func.arguments().rest {
|
||||||
|
let rest = if evaluated.positional.len() > 0 {
|
||||||
|
evaluated.positional
|
||||||
} else {
|
} else {
|
||||||
&[]
|
Vec::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let arg_list = Value::ArgList(ArgList::new(
|
let arg_list = Value::ArgList(ArgList::new(
|
||||||
rest.to_vec(),
|
rest,
|
||||||
// todo: superfluous clone
|
|
||||||
Arc::clone(&were_keywords_accessed),
|
Arc::clone(&were_keywords_accessed),
|
||||||
|
// todo: superfluous clone
|
||||||
evaluated.named.clone(),
|
evaluated.named.clone(),
|
||||||
if evaluated.separator == ListSeparator::Undecided {
|
if evaluated.separator == ListSeparator::Undecided {
|
||||||
ListSeparator::Comma
|
ListSeparator::Comma
|
||||||
@ -2180,20 +2181,16 @@ impl<'a> Visitor<'a> {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
visitor
|
visitor.env.scopes_mut().insert_var_last(rest_arg, arg_list);
|
||||||
.env
|
|
||||||
.scopes_mut()
|
|
||||||
// todo: superfluous clone
|
|
||||||
.insert_var_last(rest_arg, arg_list.clone());
|
|
||||||
|
|
||||||
Some(arg_list)
|
true
|
||||||
} else {
|
} else {
|
||||||
None
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
let val = run(func, visitor)?;
|
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);
|
return Ok(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2201,7 +2198,7 @@ impl<'a> Visitor<'a> {
|
|||||||
return Ok(val);
|
return Ok(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
let argument_word = if evaluated.named.len() == 1 {
|
let argument_word = if num_named_args == 1 {
|
||||||
"argument"
|
"argument"
|
||||||
} else {
|
} else {
|
||||||
"arguments"
|
"arguments"
|
||||||
|
@ -13,8 +13,8 @@ use crate::{
|
|||||||
},
|
},
|
||||||
utils::hex_char_for,
|
utils::hex_char_for,
|
||||||
value::{
|
value::{
|
||||||
fuzzy_equals, ArgList, CalculationArg, SassCalculation, SassFunction, SassMap, SassNumber,
|
fuzzy_equals, ArgList, CalculationArg, CalculationName, SassCalculation, SassFunction,
|
||||||
Value,
|
SassMap, SassNumber, Value,
|
||||||
},
|
},
|
||||||
Options,
|
Options,
|
||||||
};
|
};
|
||||||
@ -299,10 +299,17 @@ impl<'a> Serializer<'a> {
|
|||||||
self.write_optional_space();
|
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<()> {
|
fn visit_calculation(&mut self, calculation: &SassCalculation) -> SassResult<()> {
|
||||||
// todo: superfluous allocation
|
self.write_calculation_name(calculation.name);
|
||||||
self.buffer
|
|
||||||
.extend_from_slice(calculation.name.to_string().as_bytes());
|
|
||||||
self.buffer.push(b'(');
|
self.buffer.push(b'(');
|
||||||
|
|
||||||
if let Some((last, slice)) = calculation.args.split_last() {
|
if let Some((last, slice)) = calculation.args.split_last() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user