From 4224dd146941e7bde7751ef67b457d467cd22053 Mon Sep 17 00:00:00 2001 From: Boshen Date: Mon, 22 Jul 2024 20:33:52 +0800 Subject: [PATCH] feat(minifier): compress `typeof foo == "undefined"` into `typeof foo > "u"` --- crates/oxc_minifier/src/compressor/mod.rs | 58 +++++++++++------------ crates/oxc_minifier/tests/oxc/folding.rs | 4 +- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/crates/oxc_minifier/src/compressor/mod.rs b/crates/oxc_minifier/src/compressor/mod.rs index f5b1d5c82167cb..ebb6f6d14652bf 100644 --- a/crates/oxc_minifier/src/compressor/mod.rs +++ b/crates/oxc_minifier/src/compressor/mod.rs @@ -208,44 +208,42 @@ impl<'a> Compressor<'a> { false } - /// Transforms `typeof foo == "undefined"` into `foo === void 0` + /// Compress `typeof foo == "undefined"` into `typeof foo > "u"` /// Enabled by `compress.typeofs` fn compress_typeof_undefined(&self, expr: &mut BinaryExpression<'a>) { if !self.options.typeofs { return; } - match expr.operator { - BinaryOperator::Equality | BinaryOperator::StrictEquality => { - let pair = self.commutative_pair( - (&expr.left, &expr.right), - |a| { - if a.is_specific_string_literal("undefined") { - return Some(()); - } - None - }, - |b| { - if let Expression::UnaryExpression(op) = b { - if op.operator == UnaryOperator::Typeof { - if let Expression::Identifier(id) = &op.argument { - return Some((*id).clone()); - } - } + if !matches!(expr.operator, BinaryOperator::Equality | BinaryOperator::StrictEquality) { + return; + } + let pair = self.commutative_pair( + (&expr.left, &expr.right), + |a| a.is_specific_string_literal("undefined").then_some(()), + |b| { + if let Expression::UnaryExpression(op) = b { + if op.operator == UnaryOperator::Typeof { + if let Expression::Identifier(id) = &op.argument { + return Some((*id).clone()); } - None - }, - ); - if let Some((_void_exp, id_ref)) = pair { - let span = expr.span; - let left = self.ast.void_0(); - let operator = BinaryOperator::StrictEquality; - let right = self.ast.expression_from_identifier_reference(id_ref); - let cmp = BinaryExpression { span, left, operator, right }; - *expr = cmp; + } } - } - _ => {} + None + }, + ); + let Some((_void_exp, id_ref)) = pair else { + return; }; + let argument = self.ast.expression_from_identifier_reference(id_ref); + let left = self.ast.unary_expression(SPAN, UnaryOperator::Typeof, argument); + let right = self.ast.string_literal(SPAN, "u"); + let binary_expr = self.ast.binary_expression( + expr.span, + self.ast.expression_from_unary(left), + BinaryOperator::GreaterThan, + self.ast.expression_from_string_literal(right), + ); + *expr = binary_expr; } fn commutative_pair( diff --git a/crates/oxc_minifier/tests/oxc/folding.rs b/crates/oxc_minifier/tests/oxc/folding.rs index 58a7ba3a276008..67e03feb6673f9 100644 --- a/crates/oxc_minifier/tests/oxc/folding.rs +++ b/crates/oxc_minifier/tests/oxc/folding.rs @@ -12,8 +12,8 @@ fn addition_folding() { #[test] fn typeof_folding() { - test("typeof x === 'undefined'", "void 0===x"); - test("'undefined' === typeof x", "void 0===x"); + test("typeof x === 'undefined'", "typeof x>'u'"); + test("'undefined' === typeof x", "typeof x>'u'"); } #[test]