Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(css/parser): Don't allocate for comparisons #6593

Merged
merged 36 commits into from Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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