mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(minifier): try collapse conditional to logical or expr (#8197)
This commit is contained in:
parent
3eaff2a51c
commit
bf266e13b0
2 changed files with 33 additions and 11 deletions
|
|
@ -57,6 +57,9 @@ impl<'a> Traverse<'a> for PeepholeMinimizeConditions {
|
|||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if let Some(folded_expr) = match expr {
|
||||
Expression::UnaryExpression(e) => Self::try_minimize_not(e, ctx),
|
||||
Expression::ConditionalExpression(conditional_expr) => {
|
||||
Self::try_minimize_conditional(conditional_expr, ctx)
|
||||
}
|
||||
_ => None,
|
||||
} {
|
||||
*expr = folded_expr;
|
||||
|
|
@ -253,6 +256,28 @@ impl<'a> PeepholeMinimizeConditions {
|
|||
None => ctx.ast.void_0(return_stmt.span),
|
||||
}
|
||||
}
|
||||
|
||||
/// `a ? a : b` -> `a || b`
|
||||
fn try_minimize_conditional(
|
||||
expr: &mut ConditionalExpression<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) -> Option<Expression<'a>> {
|
||||
let Expression::Identifier(test_ident) = &expr.test else { return None };
|
||||
let Expression::Identifier(consequent_ident) = &expr.consequent else { return None };
|
||||
|
||||
if test_ident.name != consequent_ident.name {
|
||||
return None;
|
||||
}
|
||||
|
||||
let ident = ctx.ast.move_expression(&mut expr.test);
|
||||
|
||||
Some(ctx.ast.expression_logical(
|
||||
expr.span,
|
||||
ident,
|
||||
LogicalOperator::Or,
|
||||
ctx.ast.move_expression(&mut expr.alternate),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://github.com/google/closure-compiler/blob/v20240609/test/com/google/javascript/jscomp/PeepholeMinimizeConditionsTest.java>
|
||||
|
|
@ -662,21 +687,18 @@ mod test {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_minimize_hook() {
|
||||
fold("x ? x : y", "x || y");
|
||||
// We assume GETPROPs don't have side effects.
|
||||
fold("x.y ? x.y : x.z", "x.y || x.z");
|
||||
fold("x?.y ? x?.y : x.z", "x?.y || x.z");
|
||||
fold("x?.y ? x?.y : x?.z", "x?.y || x?.z");
|
||||
fold_same("x.y ? x.y : x.z");
|
||||
fold_same("x?.y ? x?.y : x.z");
|
||||
fold_same("x?.y ? x?.y : x?.z");
|
||||
|
||||
// This can be folded if x() does not have side effects.
|
||||
fold_same("x() ? x() : y()");
|
||||
fold_same("x?.() ? x?.() : y()");
|
||||
|
||||
fold("!x ? foo() : bar()", "x ? bar() : foo()");
|
||||
fold("while(!(x ? y : z)) foo();", "while(x ? !y : !z) foo();");
|
||||
fold("(x ? !y : !z) ? foo() : bar()", "(x ? y : z) ? bar() : foo()");
|
||||
// fold("!x ? foo() : bar()", "x ? bar() : foo()");
|
||||
// fold("while(!(x ? y : z)) foo();", "while(x ? !y : !z) foo();");
|
||||
// fold("(x ? !y : !z) ? foo() : bar()", "(x ? y : z) ? bar() : foo()");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Original | minified | minified | gzip | gzip | Fixture
|
|||
|
||||
3.20 MB | 1.01 MB | 1.01 MB | 332.21 kB | 331.56 kB | echarts.js
|
||||
|
||||
6.69 MB | 2.32 MB | 2.31 MB | 493.08 kB | 488.28 kB | antd.js
|
||||
6.69 MB | 2.32 MB | 2.31 MB | 493.07 kB | 488.28 kB | antd.js
|
||||
|
||||
10.95 MB | 3.51 MB | 3.49 MB | 910.42 kB | 915.50 kB | typescript.js
|
||||
10.95 MB | 3.51 MB | 3.49 MB | 910.37 kB | 915.50 kB | typescript.js
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue