optimize interpolation resolution

This commit is contained in:
Connor Skees 2022-12-28 10:31:46 -05:00
parent 0363134ba3
commit d63f0a54d2

View File

@ -1894,13 +1894,26 @@ impl<'a> Visitor<'a> {
fn perform_interpolation( fn perform_interpolation(
&mut self, &mut self,
interpolation: Interpolation, mut interpolation: Interpolation,
// todo check to emit warning if this is true // todo check to emit warning if this is true
_warn_for_color: bool, _warn_for_color: bool,
) -> SassResult<String> { ) -> SassResult<String> {
// todo: potential optimization for contents len == 1 and no exprs let result = match interpolation.contents.len() {
0 => String::new(),
let result = interpolation.contents.into_iter().map(|part| match part { 1 => match interpolation.contents.pop() {
Some(InterpolationPart::String(s)) => s,
Some(InterpolationPart::Expr(e)) => {
let span = e.span;
let result = self.visit_expr(e.node)?;
// todo: span for specific expr
self.serialize(result, QuoteKind::None, span)?
}
None => unreachable!(),
},
_ => interpolation
.contents
.into_iter()
.map(|part| match part {
InterpolationPart::String(s) => Ok(s), InterpolationPart::String(s) => Ok(s),
InterpolationPart::Expr(e) => { InterpolationPart::Expr(e) => {
let span = e.span; let span = e.span;
@ -1908,9 +1921,11 @@ impl<'a> Visitor<'a> {
// todo: span for specific expr // todo: span for specific expr
self.serialize(result, QuoteKind::None, span) self.serialize(result, QuoteKind::None, span)
} }
}); })
.collect::<SassResult<String>>()?,
};
result.collect() Ok(result)
} }
fn evaluate_to_css( fn evaluate_to_css(
@ -2544,23 +2559,38 @@ impl<'a> Visitor<'a> {
Ok(self.without_slash(value)) Ok(self.without_slash(value))
} }
fn visit_string(&mut self, text: Interpolation, quote: QuoteKind) -> SassResult<Value> { fn visit_string(&mut self, mut text: Interpolation, quote: QuoteKind) -> SassResult<Value> {
// Don't use [performInterpolation] here because we need to get the raw text // Don't use [performInterpolation] here because we need to get the raw text
// from strings, rather than the semantic value. // from strings, rather than the semantic value.
let old_in_supports_declaration = self.flags.in_supports_declaration(); let old_in_supports_declaration = self.flags.in_supports_declaration();
self.flags.set(ContextFlags::IN_SUPPORTS_DECLARATION, false); self.flags.set(ContextFlags::IN_SUPPORTS_DECLARATION, false);
let result = text let result = match text.contents.len() {
0 => String::new(),
1 => match text.contents.pop() {
Some(InterpolationPart::String(s)) => s,
Some(InterpolationPart::Expr(Spanned { node, span })) => {
match self.visit_expr(node)? {
Value::String(s, ..) => s,
e => self.serialize(e, QuoteKind::None, span)?,
}
}
None => unreachable!(),
},
_ => text
.contents .contents
.into_iter() .into_iter()
.map(|part| match part { .map(|part| match part {
InterpolationPart::String(s) => Ok(s), InterpolationPart::String(s) => Ok(s),
InterpolationPart::Expr(Spanned { node, span }) => match self.visit_expr(node)? { InterpolationPart::Expr(Spanned { node, span }) => {
match self.visit_expr(node)? {
Value::String(s, ..) => Ok(s), Value::String(s, ..) => Ok(s),
e => self.serialize(e, QuoteKind::None, span), e => self.serialize(e, QuoteKind::None, span),
}, }
}
}) })
.collect::<SassResult<String>>()?; .collect::<SassResult<String>>()?,
};
self.flags.set( self.flags.set(
ContextFlags::IN_SUPPORTS_DECLARATION, ContextFlags::IN_SUPPORTS_DECLARATION,