Skip to content

Commit ba201a6

Browse files
committed
fix(minifier): remove "non esbuild optimizations" which is incorrect (#8668)
1 parent 4ae568e commit ba201a6

File tree

3 files changed

+34
-83
lines changed

3 files changed

+34
-83
lines changed

crates/oxc_minifier/src/peephole/minimize_conditions.rs

+26-76
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,16 @@ impl<'a> PeepholeOptimizations {
218218
let consequent = Self::get_block_expression(&mut if_stmt.consequent, ctx);
219219
let else_branch = if_stmt.alternate.as_mut().unwrap();
220220
let alternate = Self::get_block_expression(else_branch, ctx);
221-
let expr = ctx.ast.expression_conditional(
221+
let mut cond_expr = ctx.ast.conditional_expression(
222222
if_stmt.span,
223223
test,
224224
consequent,
225225
alternate,
226226
);
227+
let expr = Self::try_minimize_conditional(&mut cond_expr, ctx)
228+
.unwrap_or_else(|| {
229+
Expression::ConditionalExpression(ctx.ast.alloc(cond_expr))
230+
});
227231
return Some(ctx.ast.statement_expression(if_stmt.span, expr));
228232
}
229233
}
@@ -281,12 +285,14 @@ impl<'a> PeepholeOptimizations {
281285
let mut if_stmt = if_stmt.unbox();
282286
let consequent = Self::get_block_return_expression(&mut if_stmt.consequent, ctx);
283287
let alternate = Self::take_return_argument(&mut stmts[i + 1], ctx);
284-
let argument = ctx.ast.expression_conditional(
288+
let mut cond_expr = ctx.ast.conditional_expression(
285289
if_stmt.span,
286290
if_stmt.test,
287291
consequent,
288292
alternate,
289293
);
294+
let argument = Self::try_minimize_conditional(&mut cond_expr, ctx)
295+
.unwrap_or_else(|| Expression::ConditionalExpression(ctx.ast.alloc(cond_expr)));
290296
stmts[i] = ctx.ast.statement_return(if_stmt.span, Some(argument));
291297
*changed = true;
292298
break;
@@ -359,21 +365,6 @@ impl<'a> PeepholeOptimizations {
359365
ctx: &mut TraverseCtx<'a>,
360366
) -> Option<Expression<'a>> {
361367
match &mut expr.test {
362-
// `x != y ? b : c` -> `x == y ? c : b`
363-
Expression::BinaryExpression(test_expr) => {
364-
if matches!(
365-
test_expr.operator,
366-
BinaryOperator::Inequality | BinaryOperator::StrictInequality
367-
) {
368-
test_expr.operator = test_expr.operator.equality_inverse_operator().unwrap();
369-
let test = ctx.ast.move_expression(&mut expr.test);
370-
let consequent = ctx.ast.move_expression(&mut expr.consequent);
371-
let alternate = ctx.ast.move_expression(&mut expr.alternate);
372-
return Some(
373-
ctx.ast.expression_conditional(expr.span, test, alternate, consequent),
374-
);
375-
}
376-
}
377368
// "(a, b) ? c : d" => "a, b ? c : d"
378369
Expression::SequenceExpression(sequence_expr) => {
379370
if sequence_expr.expressions.len() > 1 {
@@ -431,6 +422,21 @@ impl<'a> PeepholeOptimizations {
431422
}
432423
}
433424
}
425+
// `x != y ? b : c` -> `x == y ? c : b`
426+
Expression::BinaryExpression(test_expr) => {
427+
if matches!(
428+
test_expr.operator,
429+
BinaryOperator::Inequality | BinaryOperator::StrictInequality
430+
) {
431+
test_expr.operator = test_expr.operator.equality_inverse_operator().unwrap();
432+
let test = ctx.ast.move_expression(&mut expr.test);
433+
let consequent = ctx.ast.move_expression(&mut expr.consequent);
434+
let alternate = ctx.ast.move_expression(&mut expr.alternate);
435+
return Some(
436+
ctx.ast.expression_conditional(expr.span, test, alternate, consequent),
437+
);
438+
}
439+
}
434440
_ => {}
435441
}
436442

@@ -637,62 +643,6 @@ impl<'a> PeepholeOptimizations {
637643

638644
// TODO: Try using the "??" or "?." operators
639645

640-
// Non esbuild optimizations
641-
642-
// `x ? true : y` -> `x || y`
643-
// `x ? false : y` -> `!x && y`
644-
if let (Expression::Identifier(_), Expression::BooleanLiteral(consequent_lit), _) =
645-
(&expr.test, &expr.consequent, &expr.alternate)
646-
{
647-
if consequent_lit.value {
648-
let ident = ctx.ast.move_expression(&mut expr.test);
649-
return Some(ctx.ast.expression_logical(
650-
expr.span,
651-
ctx.ast.expression_unary(
652-
ident.span(),
653-
UnaryOperator::LogicalNot,
654-
ctx.ast.expression_unary(ident.span(), UnaryOperator::LogicalNot, ident),
655-
),
656-
LogicalOperator::Or,
657-
ctx.ast.move_expression(&mut expr.alternate),
658-
));
659-
}
660-
let ident = ctx.ast.move_expression(&mut expr.test);
661-
return Some(ctx.ast.expression_logical(
662-
expr.span,
663-
ctx.ast.expression_unary(expr.span, UnaryOperator::LogicalNot, ident),
664-
LogicalOperator::And,
665-
ctx.ast.move_expression(&mut expr.alternate),
666-
));
667-
}
668-
669-
// `x ? y : true` -> `!x || y`
670-
// `x ? y : false` -> `x && y`
671-
if let (Expression::Identifier(_), _, Expression::BooleanLiteral(alternate_lit)) =
672-
(&expr.test, &expr.consequent, &expr.alternate)
673-
{
674-
if alternate_lit.value {
675-
let ident = ctx.ast.move_expression(&mut expr.test);
676-
return Some(ctx.ast.expression_logical(
677-
expr.span,
678-
ctx.ast.expression_unary(expr.span, UnaryOperator::LogicalNot, ident),
679-
LogicalOperator::Or,
680-
ctx.ast.move_expression(&mut expr.consequent),
681-
));
682-
}
683-
let ident = ctx.ast.move_expression(&mut expr.test);
684-
return Some(ctx.ast.expression_logical(
685-
expr.span,
686-
ctx.ast.expression_unary(
687-
expr.span,
688-
UnaryOperator::LogicalNot,
689-
ctx.ast.expression_unary(ident.span(), UnaryOperator::LogicalNot, ident),
690-
),
691-
LogicalOperator::And,
692-
ctx.ast.move_expression(&mut expr.consequent),
693-
));
694-
}
695-
696646
if expr.alternate.content_eq(&expr.consequent) {
697647
// TODO:
698648
// "/* @__PURE__ */ a() ? b : b" => "b"
@@ -1163,11 +1113,11 @@ mod test {
11631113
test("(x || false) && y()", "x && y()");
11641114

11651115
test("let x = foo ? true : false", "let x = !!foo");
1166-
test("let x = foo ? true : bar", "let x = !!foo || bar");
1167-
test("let x = foo ? bar : false", "let x = !!foo && bar");
1116+
test("let x = foo ? true : bar", "let x = foo ? !0 : bar");
1117+
test("let x = foo ? bar : false", "let x = foo ? bar : !1");
11681118
test("function x () { return a ? true : false }", "function x() { return !!a }");
11691119
test("function x () { return a ? false : true }", "function x() { return !a }");
1170-
test("function x () { return a ? true : b }", "function x() { return !!a || b }");
1120+
test("function x () { return a ? true : b }", "function x() { return a ? !0 : b }");
11711121
// can't be minified e.g. `a = ''` would return `''`
11721122
test("function x() { return a && true }", "function x() { return a && !0 }");
11731123

crates/oxc_minifier/src/peephole/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ impl<'a> PeepholeOptimizations {
7474
*current_changed
7575
}
7676

77+
#[inline]
7778
fn is_prev_function_changed(&self) -> bool {
7879
let (_, prev_changed, _) = self.current_function.last();
7980
*prev_changed

tasks/minsize/minsize.snap

+7-7
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,23 @@ Original | minified | minified | gzip | gzip | Fixture
55

66
173.90 kB | 59.79 kB | 59.82 kB | 19.41 kB | 19.33 kB | moment.js
77

8-
287.63 kB | 90.08 kB | 90.07 kB | 32.02 kB | 31.95 kB | jquery.js
8+
287.63 kB | 90.08 kB | 90.07 kB | 32.03 kB | 31.95 kB | jquery.js
99

1010
342.15 kB | 118.19 kB | 118.14 kB | 44.45 kB | 44.37 kB | vue.js
1111

12-
544.10 kB | 71.73 kB | 72.48 kB | 26.15 kB | 26.20 kB | lodash.js
12+
544.10 kB | 71.73 kB | 72.48 kB | 26.14 kB | 26.20 kB | lodash.js
1313

1414
555.77 kB | 272.89 kB | 270.13 kB | 90.90 kB | 90.80 kB | d3.js
1515

16-
1.01 MB | 460.17 kB | 458.89 kB | 126.78 kB | 126.71 kB | bundle.min.js
16+
1.01 MB | 460.16 kB | 458.89 kB | 126.78 kB | 126.71 kB | bundle.min.js
1717

1818
1.25 MB | 652.85 kB | 646.76 kB | 163.53 kB | 163.73 kB | three.js
1919

20-
2.14 MB | 724.00 kB | 724.14 kB | 179.93 kB | 181.07 kB | victory.js
20+
2.14 MB | 724 kB | 724.14 kB | 179.93 kB | 181.07 kB | victory.js
2121

22-
3.20 MB | 1.01 MB | 1.01 MB | 332.00 kB | 331.56 kB | echarts.js
22+
3.20 MB | 1.01 MB | 1.01 MB | 332.02 kB | 331.56 kB | echarts.js
2323

24-
6.69 MB | 2.31 MB | 2.31 MB | 491.95 kB | 488.28 kB | antd.js
24+
6.69 MB | 2.31 MB | 2.31 MB | 491.94 kB | 488.28 kB | antd.js
2525

26-
10.95 MB | 3.48 MB | 3.49 MB | 905.35 kB | 915.50 kB | typescript.js
26+
10.95 MB | 3.48 MB | 3.49 MB | 905.33 kB | 915.50 kB | typescript.js
2727

0 commit comments

Comments
 (0)