mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 12:51:57 +00:00
feat(minifier): minify alternated one child if block (#7231)
This commit is contained in:
parent
2ac9f963df
commit
97af341cac
2 changed files with 69 additions and 48 deletions
|
|
@ -91,14 +91,22 @@ impl<'a> PeepholeMinimizeConditions {
|
||||||
) -> Option<Statement<'a>> {
|
) -> Option<Statement<'a>> {
|
||||||
if let Statement::ExpressionStatement(expr) = &mut if_stmt.consequent {
|
if let Statement::ExpressionStatement(expr) = &mut if_stmt.consequent {
|
||||||
// The rest of things for known boolean are tasks for dce instead of here.
|
// The rest of things for known boolean are tasks for dce instead of here.
|
||||||
(if_stmt.alternate.is_none() && if_stmt.test.to_boolean().is_none()).then(|| {
|
if_stmt
|
||||||
|
.test
|
||||||
|
.to_boolean()
|
||||||
|
.is_none()
|
||||||
|
.then(|| {
|
||||||
|
if !matches!(if_stmt.alternate, None | Some(Statement::ExpressionStatement(_)))
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
// Make if (x) y; => x && y;
|
// Make if (x) y; => x && y;
|
||||||
let (operator, mut test) = match &mut if_stmt.test {
|
let (reverse, mut test) = match &mut if_stmt.test {
|
||||||
Expression::UnaryExpression(unary) if unary.operator.is_not() => {
|
Expression::UnaryExpression(unary) if unary.operator.is_not() => {
|
||||||
let arg = ctx.ast.move_expression(&mut unary.argument);
|
let arg = ctx.ast.move_expression(&mut unary.argument);
|
||||||
(LogicalOperator::Or, arg)
|
(true, arg)
|
||||||
}
|
}
|
||||||
_ => (LogicalOperator::And, ctx.ast.move_expression(&mut if_stmt.test)),
|
_ => (false, ctx.ast.move_expression(&mut if_stmt.test)),
|
||||||
};
|
};
|
||||||
match &mut test {
|
match &mut test {
|
||||||
Expression::BinaryExpression(bin) if bin.operator.is_equality() => {
|
Expression::BinaryExpression(bin) if bin.operator.is_equality() => {
|
||||||
|
|
@ -113,14 +121,28 @@ impl<'a> PeepholeMinimizeConditions {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
if let Some(Statement::ExpressionStatement(alt)) = &mut if_stmt.alternate {
|
||||||
|
let left = ctx.ast.move_expression(&mut expr.expression);
|
||||||
|
let right = ctx.ast.move_expression(&mut alt.expression);
|
||||||
|
let cond = if reverse {
|
||||||
|
ctx.ast.expression_conditional(SPAN, test, right, left)
|
||||||
|
} else {
|
||||||
|
ctx.ast.expression_conditional(SPAN, test, left, right)
|
||||||
|
};
|
||||||
|
Some(ctx.ast.statement_expression(SPAN, cond))
|
||||||
|
} else if if_stmt.alternate.is_none() {
|
||||||
let new_expr = ctx.ast.expression_logical(
|
let new_expr = ctx.ast.expression_logical(
|
||||||
SPAN,
|
SPAN,
|
||||||
test,
|
test,
|
||||||
operator,
|
if reverse { LogicalOperator::Or } else { LogicalOperator::And },
|
||||||
ctx.ast.move_expression(&mut expr.expression),
|
ctx.ast.move_expression(&mut expr.expression),
|
||||||
);
|
);
|
||||||
ctx.ast.statement_expression(SPAN, new_expr)
|
Some(ctx.ast.statement_expression(SPAN, new_expr))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
.unwrap_or(None)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +190,7 @@ mod test {
|
||||||
|
|
||||||
// Try it out with functions
|
// Try it out with functions
|
||||||
fold("function f(){if(x){foo()}}", "function f(){x&&foo()}");
|
fold("function f(){if(x){foo()}}", "function f(){x&&foo()}");
|
||||||
// fold("function f(){if(x){foo()}else{bar()}}", "function f(){x?foo():bar()}");
|
fold("function f(){if(x){foo()}else{bar()}}", "function f(){x?foo():bar()}");
|
||||||
|
|
||||||
// Try it out with properties and methods
|
// Try it out with properties and methods
|
||||||
fold("function f(){if(x){a.b=1}}", "function f(){x&&(a.b=1)}");
|
fold("function f(){if(x){a.b=1}}", "function f(){x&&(a.b=1)}");
|
||||||
|
|
@ -191,12 +213,12 @@ mod test {
|
||||||
|
|
||||||
// Play with nested IFs
|
// Play with nested IFs
|
||||||
fold("function f(){if(x){if(y)foo()}}", "function f(){x && (y && foo())}");
|
fold("function f(){if(x){if(y)foo()}}", "function f(){x && (y && foo())}");
|
||||||
// fold("function f(){if(x){if(y)foo();else bar()}}", "function f(){x&&(y?foo():bar())}");
|
fold("function f(){if(x){if(y)foo();else bar()}}", "function f(){x&&(y?foo():bar())}");
|
||||||
// fold("function f(){if(x){if(y)foo()}else bar()}", "function f(){x?y&&foo():bar()}");
|
fold("function f(){if(x){if(y)foo()}else bar()}", "function f(){x?y&&foo():bar()}");
|
||||||
// fold(
|
fold(
|
||||||
// "function f(){if(x){if(y)foo();else bar()}else{baz()}}",
|
"function f(){if(x){if(y)foo();else bar()}else{baz()}}",
|
||||||
// "function f(){x?y?foo():bar():baz()}",
|
"function f(){x?y?foo():bar():baz()}",
|
||||||
// );
|
);
|
||||||
|
|
||||||
// fold("if(e1){while(e2){if(e3){foo()}}}else{bar()}", "if(e1)while(e2)e3&&foo();else bar()");
|
// fold("if(e1){while(e2){if(e3){foo()}}}else{bar()}", "if(e1)while(e2)e3&&foo();else bar()");
|
||||||
|
|
||||||
|
|
@ -371,11 +393,10 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn test_not_cond() {
|
fn test_not_cond() {
|
||||||
fold("function f(){if(!x)foo()}", "function f(){x||foo()}");
|
fold("function f(){if(!x)foo()}", "function f(){x||foo()}");
|
||||||
fold("function f(){if(!x)b=1}", "function f(){x||(b=1)}");
|
fold("function f(){if(!x)b=1}", "function f(){x||(b=1)}");
|
||||||
fold("if(!x)z=1;else if(y)z=2", "if(x){y&&(z=2);}else{z=1;}");
|
fold("if(!x)z=1;else if(y)z=2", "x ? y&&(z=2) : z=1;");
|
||||||
fold("if(x)y&&(z=2);else z=1;", "x ? y&&(z=2) : z=1");
|
fold("if(x)y&&(z=2);else z=1;", "x ? y&&(z=2) : z=1");
|
||||||
fold("function f(){if(!(x=1))a.b=1}", "function f(){(x=1)||(a.b=1)}");
|
fold("function f(){if(!(x=1))a.b=1}", "function f(){(x=1)||(a.b=1)}");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
Original | Minified | esbuild | Gzip | esbuild
|
Original | Minified | esbuild | Gzip | esbuild
|
||||||
|
|
||||||
72.14 kB | 24.06 kB | 23.70 kB | 8.68 kB | 8.54 kB | react.development.js
|
72.14 kB | 23.98 kB | 23.70 kB | 8.67 kB | 8.54 kB | react.development.js
|
||||||
|
|
||||||
173.90 kB | 61.54 kB | 59.82 kB | 19.64 kB | 19.33 kB | moment.js
|
173.90 kB | 61.16 kB | 59.82 kB | 19.62 kB | 19.33 kB | moment.js
|
||||||
|
|
||||||
287.63 kB | 92.33 kB | 90.07 kB | 32.45 kB | 31.95 kB | jquery.js
|
287.63 kB | 91.70 kB | 90.07 kB | 32.35 kB | 31.95 kB | jquery.js
|
||||||
|
|
||||||
342.15 kB | 121.31 kB | 118.14 kB | 44.85 kB | 44.37 kB | vue.js
|
342.15 kB | 120.23 kB | 118.14 kB | 44.72 kB | 44.37 kB | vue.js
|
||||||
|
|
||||||
544.10 kB | 73.40 kB | 72.48 kB | 26.20 kB | 26.20 kB | lodash.js
|
544.10 kB | 73.03 kB | 72.48 kB | 26.16 kB | 26.20 kB | lodash.js
|
||||||
|
|
||||||
555.77 kB | 276.27 kB | 270.13 kB | 91.49 kB | 90.80 kB | d3.js
|
555.77 kB | 275.23 kB | 270.13 kB | 91.33 kB | 90.80 kB | d3.js
|
||||||
|
|
||||||
1.01 MB | 466.71 kB | 458.89 kB | 127.15 kB | 126.71 kB | bundle.min.js
|
1.01 MB | 464.89 kB | 458.89 kB | 127.05 kB | 126.71 kB | bundle.min.js
|
||||||
|
|
||||||
1.25 MB | 662.18 kB | 646.76 kB | 164.73 kB | 163.73 kB | three.js
|
1.25 MB | 660.45 kB | 646.76 kB | 164.57 kB | 163.73 kB | three.js
|
||||||
|
|
||||||
2.14 MB | 741.23 kB | 724.14 kB | 181.84 kB | 181.07 kB | victory.js
|
2.14 MB | 739.98 kB | 724.14 kB | 181.63 kB | 181.07 kB | victory.js
|
||||||
|
|
||||||
3.20 MB | 1.02 MB | 1.01 MB | 333.40 kB | 331.56 kB | echarts.js
|
3.20 MB | 1.02 MB | 1.01 MB | 333.05 kB | 331.56 kB | echarts.js
|
||||||
|
|
||||||
6.69 MB | 2.39 MB | 2.31 MB | 497.21 kB | 488.28 kB | antd.js
|
6.69 MB | 2.39 MB | 2.31 MB | 496.76 kB | 488.28 kB | antd.js
|
||||||
|
|
||||||
10.95 MB | 3.55 MB | 3.49 MB | 913.93 kB | 915.50 kB | typescript.js
|
10.95 MB | 3.55 MB | 3.49 MB | 913.60 kB | 915.50 kB | typescript.js
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue