mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(minifier): minify typeof in binary expressions (#8302)
This commit is contained in:
parent
6afc590db8
commit
5ed439bcaf
2 changed files with 60 additions and 5 deletions
|
|
@ -31,7 +31,8 @@ impl<'a> Traverse<'a> for PeepholeFoldConstants {
|
|||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
let ctx = Ctx(ctx);
|
||||
if let Some(folded_expr) = match expr {
|
||||
Expression::BinaryExpression(e) => Self::try_fold_binary_expr(e, ctx),
|
||||
Expression::BinaryExpression(e) => Self::try_fold_binary_expr(e, ctx)
|
||||
.or_else(|| Self::try_fold_binary_typeof_comparison(e, ctx)),
|
||||
Expression::UnaryExpression(e) => Self::try_fold_unary_expr(e, ctx),
|
||||
Expression::StaticMemberExpression(e) => Self::try_fold_static_member_expr(e, ctx),
|
||||
Expression::LogicalExpression(e) => Self::try_fold_logical_expr(e, ctx),
|
||||
|
|
@ -624,6 +625,55 @@ impl<'a, 'b> PeepholeFoldConstants {
|
|||
.to_js_string()
|
||||
.map(|value| ctx.ast.expression_string_literal(object.span(), value, None))
|
||||
}
|
||||
|
||||
// `typeof a === typeof b` -> `typeof a == typeof b`, `typeof a != typeof b` -> `typeof a != typeof b`,
|
||||
// `typeof a == typeof a` -> `true`, `typeof a != typeof a` -> `false`
|
||||
fn try_fold_binary_typeof_comparison(
|
||||
bin_expr: &mut BinaryExpression<'a>,
|
||||
ctx: Ctx<'a, 'b>,
|
||||
) -> Option<Expression<'a>> {
|
||||
if bin_expr.operator.is_equality() {
|
||||
if let (Expression::UnaryExpression(left), Expression::UnaryExpression(right)) =
|
||||
(&bin_expr.left, &bin_expr.right)
|
||||
{
|
||||
if left.operator.is_typeof() && right.operator.is_typeof() {
|
||||
if let (
|
||||
Expression::Identifier(left_ident),
|
||||
Expression::Identifier(right_ident),
|
||||
) = (&left.argument, &right.argument)
|
||||
{
|
||||
if left_ident.name == right_ident.name {
|
||||
return Some(ctx.ast.expression_boolean_literal(
|
||||
bin_expr.span,
|
||||
matches!(
|
||||
bin_expr.operator,
|
||||
BinaryOperator::StrictEquality | BinaryOperator::Equality
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if matches!(
|
||||
bin_expr.operator,
|
||||
BinaryOperator::StrictEquality | BinaryOperator::StrictInequality
|
||||
) {
|
||||
return Some(ctx.ast.expression_binary(
|
||||
bin_expr.span,
|
||||
ctx.ast.move_expression(&mut bin_expr.left),
|
||||
if bin_expr.operator == BinaryOperator::StrictEquality {
|
||||
BinaryOperator::Equality
|
||||
} else {
|
||||
BinaryOperator::Inequality
|
||||
},
|
||||
ctx.ast.move_expression(&mut bin_expr.right),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeFoldConstantsTest.java>
|
||||
|
|
@ -931,11 +981,8 @@ mod test {
|
|||
test("'a' == 'a'", "true");
|
||||
test("'b' != 'a'", "true");
|
||||
test_same("typeof a != 'number'");
|
||||
test_same("typeof a == typeof a");
|
||||
test("'a' === 'a'", "true");
|
||||
test("'b' !== 'a'", "true");
|
||||
test_same("typeof a === typeof a");
|
||||
test_same("typeof a !== typeof a");
|
||||
test_same("'' + x <= '' + y");
|
||||
test_same("'' + x != '' + y");
|
||||
test_same("'' + x === '' + y");
|
||||
|
|
@ -1797,4 +1844,12 @@ mod test {
|
|||
test("typeof foo + ''", "typeof foo");
|
||||
test_same("typeof foo - ''");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold_same_typeof() {
|
||||
test("typeof foo === typeof bar", "typeof foo == typeof bar");
|
||||
test("typeof foo !== typeof bar", "typeof foo != typeof bar");
|
||||
test("typeof foo.bar === typeof foo.bar", "typeof foo.bar == typeof foo.bar");
|
||||
test("typeof foo.bar !== typeof foo.bar", "typeof foo.bar != typeof foo.bar");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Original | minified | minified | gzip | gzip | Fixture
|
|||
|
||||
555.77 kB | 273.15 kB | 270.13 kB | 90.95 kB | 90.80 kB | d3.js
|
||||
|
||||
1.01 MB | 460.32 kB | 458.89 kB | 126.84 kB | 126.71 kB | bundle.min.js
|
||||
1.01 MB | 460.31 kB | 458.89 kB | 126.84 kB | 126.71 kB | bundle.min.js
|
||||
|
||||
1.25 MB | 652.68 kB | 646.76 kB | 163.53 kB | 163.73 kB | three.js
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue