mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(minifier): compress typeof foo == "undefined" into typeof foo > "u" (#4412)
``` > monitor-oxc@ test /home/runner/work/monitor-oxc/monitor-oxc > node src/main.test.mjs /home/runner/work/monitor-oxc/monitor-oxc/node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:2375 if (void 0 === __REACT_DEVTOOLS_GLOBAL_HOOK__) return !1; ^ ReferenceError: __REACT_DEVTOOLS_GLOBAL_HOOK__ is not defined at injectInternals (/home/runner/work/monitor-oxc/monitor-oxc/node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.development.js:2375:3) ```
This commit is contained in:
parent
267f7c4398
commit
e33ec18d78
2 changed files with 30 additions and 32 deletions
|
|
@ -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(());
|
||||
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
|
||||
},
|
||||
|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<A, F, G, RetF: 'a, RetG: 'a>(
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
Loading…
Reference in a new issue