Skip to content

Commit

Permalink
perf(css/parser): Don't allocate for comparisons (#6593)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 committed Dec 7, 2022
1 parent 31630ba commit 08b6eab
Show file tree
Hide file tree
Showing 21 changed files with 269 additions and 229 deletions.
23 changes: 23 additions & 0 deletions crates/swc_css_ast/src/lib.rs
Expand Up @@ -9,3 +9,26 @@ mod base;
mod selector;
mod token;
mod value;

/// Returns true if the given value matches one of the given patterns.
///
/// The type of value and patterns should be identical.
///
/// # Exmaples
///
/// ```
/// use swc_atoms::JsWord;
/// use swc_atoms::js_word;
/// use swc_css_ast::*;
///
/// assert!(matches_eq_ignore_ascii_case!(JsWord::from("A"), js_word!("a")));
/// assert!(matches_eq_ignore_ascii_case!("A", "a"));
/// ```
#[macro_export]
macro_rules! matches_eq_ignore_ascii_case {
($value:expr, $($pat:expr),*) => {{
$(
$value.eq_ignore_ascii_case(&$pat) ||
)* false
}};
}
2 changes: 1 addition & 1 deletion crates/swc_css_codegen/src/lib.rs
Expand Up @@ -1565,7 +1565,7 @@ where
fn emit_ident(&mut self, n: &Ident) -> Result {
if self.config.minify {
let value = if self.ctx.allow_to_lowercase && self.config.minify {
n.value.to_lowercase()
n.value.to_ascii_lowercase().to_string()
} else {
n.value.to_string()
};
Expand Down
8 changes: 4 additions & 4 deletions crates/swc_css_minifier/src/compressor/color.rs
Expand Up @@ -284,7 +284,7 @@ impl Compressor {
Some(*value / 100.0)
}
Some(ComponentValue::Ident(box Ident { value, .. }))
if value.to_ascii_lowercase() == js_word!("none") =>
if value.eq_ignore_ascii_case(&js_word!("none")) =>
{
Some(0.0)
}
Expand Down Expand Up @@ -321,7 +321,7 @@ impl Compressor {
Some(value)
}
Some(ComponentValue::Ident(box Ident { value, .. }))
if value.to_ascii_lowercase() == js_word!("none") =>
if value.eq_ignore_ascii_case(&js_word!("none")) =>
{
Some(0.0)
}
Expand All @@ -344,7 +344,7 @@ impl Compressor {
Some(*value / 100.0)
}
Some(ComponentValue::Ident(box Ident { value, .. }))
if value.to_ascii_lowercase() == js_word!("none") =>
if value.eq_ignore_ascii_case(&js_word!("none")) =>
{
Some(0.0)
}
Expand Down Expand Up @@ -379,7 +379,7 @@ impl Compressor {
Some((2.55 * *value).round())
}
Some(ComponentValue::Ident(box Ident { value, .. }))
if value.to_ascii_lowercase() == js_word!("none") =>
if value.eq_ignore_ascii_case(&js_word!("none")) =>
{
Some(0.0)
}
Expand Down
81 changes: 43 additions & 38 deletions crates/swc_css_minifier/src/compressor/declaration.rs
Expand Up @@ -16,34 +16,37 @@ impl Compressor {
for value in declaration.value.iter() {
match value {
outside_node @ ComponentValue::Ident(box Ident { value, .. })
if matches!(
value.to_ascii_lowercase(),
js_word!("block") | js_word!("inline") | js_word!("run-in")
if matches_eq_ignore_ascii_case!(
value,
js_word!("block"),
js_word!("inline"),
js_word!("run-in")
) =>
{
outside = Some(outside_node);
}
inside_node @ ComponentValue::Ident(box Ident { value, .. })
if matches!(
value.to_ascii_lowercase(),
js_word!("flow")
| js_word!("flow-root")
| js_word!("table")
| js_word!("flex")
| js_word!("grid")
| js_word!("ruby")
if matches_eq_ignore_ascii_case!(
value,
js_word!("flow"),
js_word!("flow-root"),
js_word!("table"),
js_word!("flex"),
js_word!("grid"),
js_word!("ruby")
) =>
{
inside = Some(inside_node);
}
list_item_node @ ComponentValue::Ident(box Ident { value, .. })
if value.to_ascii_lowercase() == js_word!("list-item") =>
if value.eq_ignore_ascii_case(&js_word!("list-item")) =>
{
if let Some(ComponentValue::Ident(box Ident { value, .. })) = inside
{
if !matches!(
value.to_ascii_lowercase(),
js_word!("flow") | js_word!("flow-root")
if !matches_eq_ignore_ascii_case!(
value,
js_word!("flow"),
js_word!("flow-root")
) {
continue;
}
Expand All @@ -66,7 +69,7 @@ impl Compressor {
..
})),
None,
) if inside_value.to_ascii_lowercase() == js_word!("flow") => {
) if inside_value.eq_ignore_ascii_case(&js_word!("flow")) => {
declaration.value = vec![outside.clone()];
}
// `block flow-root` -> `flow-root`
Expand All @@ -82,8 +85,8 @@ impl Compressor {
}),
),
None,
) if outside_value.to_ascii_lowercase() == js_word!("block")
&& inside_value.to_ascii_lowercase() == js_word!("flow-root") =>
) if outside_value.eq_ignore_ascii_case(&js_word!("block"))
&& inside_value.eq_ignore_ascii_case(&js_word!("flow-root")) =>
{
declaration.value = vec![inside.clone()];
}
Expand All @@ -99,8 +102,8 @@ impl Compressor {
..
})),
None,
) if outside_value.to_ascii_lowercase() == js_word!("inline")
&& inside_value.to_ascii_lowercase() == js_word!("flow-root") =>
) if outside_value.eq_ignore_ascii_case(&js_word!("inline"))
&& inside_value.eq_ignore_ascii_case(&js_word!("flow-root")) =>
{
declaration.value = vec![ComponentValue::Ident(Box::new(Ident {
span: *span,
Expand All @@ -119,8 +122,8 @@ impl Compressor {
..
})),
Some(list_item),
) if outside_value.to_ascii_lowercase() == js_word!("block")
&& inside_value.to_ascii_lowercase() == js_word!("flow") =>
) if outside_value.eq_ignore_ascii_case(&js_word!("block"))
&& inside_value.eq_ignore_ascii_case(&js_word!("flow")) =>
{
declaration.value = vec![list_item.clone()];
}
Expand All @@ -132,7 +135,7 @@ impl Compressor {
})),
None,
Some(list_item),
) if outside_value.to_ascii_lowercase() == js_word!("block") => {
) if outside_value.eq_ignore_ascii_case(&js_word!("block")) => {
declaration.value = vec![list_item.clone()];
}
// `flow list-item` -> `list-item`
Expand All @@ -143,7 +146,7 @@ impl Compressor {
..
})),
Some(list_item),
) if inside_value.to_ascii_lowercase() == js_word!("flow") => {
) if inside_value.eq_ignore_ascii_case(&js_word!("flow")) => {
declaration.value = vec![list_item.clone()];
}
// `inline flow list-item` -> `inline list-item`
Expand All @@ -159,8 +162,8 @@ impl Compressor {
..
})),
Some(list_item),
) if outside_value.to_ascii_lowercase() == js_word!("inline")
&& inside_value.to_ascii_lowercase() == js_word!("flow") =>
) if outside_value.eq_ignore_ascii_case(&js_word!("inline"))
&& inside_value.eq_ignore_ascii_case(&js_word!("flow")) =>
{
declaration.value = vec![outside.clone(), list_item.clone()];
}
Expand All @@ -179,10 +182,12 @@ impl Compressor {
}),
),
None,
) if outside_value.to_ascii_lowercase() == js_word!("block")
&& matches!(
inside_value.to_ascii_lowercase(),
js_word!("flex") | js_word!("grid") | js_word!("table")
) if outside_value.eq_ignore_ascii_case(&js_word!("block"))
&& matches_eq_ignore_ascii_case!(
inside_value,
js_word!("flex"),
js_word!("grid"),
js_word!("table")
) =>
{
declaration.value = vec![inside.clone()];
Expand All @@ -200,8 +205,8 @@ impl Compressor {
}),
),
None,
) if outside_value.to_ascii_lowercase() == js_word!("inline")
&& inside_value.to_ascii_lowercase() == js_word!("ruby") =>
) if outside_value.eq_ignore_ascii_case(&js_word!("inline"))
&& inside_value.eq_ignore_ascii_case(&js_word!("ruby")) =>
{
declaration.value = vec![inside.clone()];
}
Expand Down Expand Up @@ -336,7 +341,7 @@ impl Compressor {
.into_iter()
.map(|node| match node {
ComponentValue::Ident(box Ident { value, span, .. })
if value.to_ascii_lowercase() == js_word!("normal") =>
if value.eq_ignore_ascii_case(&js_word!("normal")) =>
{
ComponentValue::Number(Box::new(Number {
span,
Expand All @@ -345,7 +350,7 @@ impl Compressor {
}))
}
ComponentValue::Ident(box Ident { value, span, .. })
if value.to_ascii_lowercase() == js_word!("bold") =>
if value.eq_ignore_ascii_case(&js_word!("bold")) =>
{
ComponentValue::Number(Box::new(Number {
span,
Expand Down Expand Up @@ -464,7 +469,7 @@ impl Compressor {
let value = ident.value.to_ascii_lowercase();
match &*value {
_ if crate::is_css_wide_keyword(&ident.value)
|| ident.value.to_ascii_lowercase() == js_word!("none") =>
|| ident.value.eq_ignore_ascii_case(&js_word!("none")) =>
{
node
}
Expand Down Expand Up @@ -512,7 +517,7 @@ impl Compressor {
..
}))),
) if value_1.value == value_2.value
&& unit_1.value.to_ascii_lowercase() == unit_2.value.to_ascii_lowercase() =>
&& unit_1.value.eq_ignore_ascii_case(&unit_2.value) =>
{
true
}
Expand Down Expand Up @@ -552,7 +557,7 @@ impl Compressor {
..
}))),
) if value_1.value == value_2.value
&& unit_1.value.to_ascii_lowercase() == unit_2.value.to_ascii_lowercase() =>
&& unit_1.value.eq_ignore_ascii_case(&unit_2.value) =>
{
true
}
Expand Down Expand Up @@ -586,6 +591,6 @@ impl Compressor {
matches!((node_1, node_2), (
Some(ComponentValue::Ident(box Ident { value: value_1, .. })),
Some(ComponentValue::Ident(box Ident { value: value_2, .. })),
) if value_1.to_ascii_lowercase() == value_2.to_ascii_lowercase())
) if value_1.eq_ignore_ascii_case(value_2))
}
}
6 changes: 3 additions & 3 deletions crates/swc_css_minifier/src/compressor/easing_function.rs
Expand Up @@ -10,7 +10,7 @@ impl Compressor {
name,
value: function_value,
span,
}) if name.value.to_ascii_lowercase() == js_word!("cubic-bezier")
}) if name.value.eq_ignore_ascii_case(&js_word!("cubic-bezier"))
&& function_value.len() == 7 =>
{
if let (
Expand Down Expand Up @@ -61,7 +61,7 @@ impl Compressor {
name,
value: function_value,
span,
}) if name.value.to_ascii_lowercase() == js_word!("steps")
}) if name.value.eq_ignore_ascii_case(&js_word!("steps"))
&& function_value.len() == 3 =>
{
match (&function_value[0], &function_value[2]) {
Expand Down Expand Up @@ -95,7 +95,7 @@ impl Compressor {
ComponentValue::Ident(box Ident {
value: ident_value, ..
}),
) if ident_value.to_ascii_lowercase() == js_word!("jump-start") => {
) if ident_value.eq_ignore_ascii_case(&js_word!("jump-start")) => {
function_value[2] = ComponentValue::Ident(Box::new(Ident {
span: *span,
value: js_word!("start"),
Expand Down
4 changes: 2 additions & 2 deletions crates/swc_css_minifier/src/compressor/keyframes.rs
Expand Up @@ -10,7 +10,7 @@ impl Compressor {
match at_rule.prelude.as_deref() {
Some(AtRulePrelude::KeyframesPrelude(KeyframesName::Str(string)))
if !is_css_wide_keyword(&string.value)
&& string.value.to_ascii_lowercase() != js_word!("none") =>
&& !string.value.eq_ignore_ascii_case(&js_word!("none")) =>
{
at_rule.prelude = Some(Box::new(AtRulePrelude::KeyframesPrelude(
if self.is_ident_shorter_than_str(&string.value) {
Expand All @@ -34,7 +34,7 @@ impl Compressor {

pub(super) fn compress_keyframe_selector(&mut self, keyframe_selector: &mut KeyframeSelector) {
match keyframe_selector {
KeyframeSelector::Ident(i) if i.value.to_ascii_lowercase() == js_word!("from") => {
KeyframeSelector::Ident(i) if i.value.eq_ignore_ascii_case(&js_word!("from")) => {
*keyframe_selector = KeyframeSelector::Percentage(Percentage {
span: i.span,
value: Number {
Expand Down
9 changes: 6 additions & 3 deletions crates/swc_css_minifier/src/compressor/math/mod.rs
Expand Up @@ -2,9 +2,12 @@ use swc_atoms::js_word;
use swc_css_ast::*;

pub fn is_calc_function_name(ident: &Ident) -> bool {
ident.value.to_ascii_lowercase() == js_word!("calc")
|| ident.value.to_ascii_lowercase() == js_word!("-webkit-calc")
|| ident.value.to_ascii_lowercase() == js_word!("-moz-calc")
matches_eq_ignore_ascii_case!(
ident.value,
js_word!("calc"),
js_word!("-webkit-calc"),
js_word!("-moz-calc")
)
}

pub fn transform_calc_value_into_component_value(calc_value: &CalcValue) -> Option<ComponentValue> {
Expand Down

0 comments on commit 08b6eab

Please sign in to comment.