Skip to content

Commit

Permalink
feat(minifier): minimize unary expression statements (#8256)
Browse files Browse the repository at this point in the history
`delete` cannot be minified as it may have side effect.
  • Loading branch information
camc314 committed Jan 6, 2025
1 parent b6d16f4 commit 7f19211
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
35 changes: 35 additions & 0 deletions crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,20 @@ impl<'a, 'b> PeepholeRemoveDeadCode {
Expression::FunctionExpression(function_expr) if function_expr.id.is_none() => {
Some(ctx.ast.statement_empty(SPAN))
}
// `typeof x` -> ``
Expression::UnaryExpression(unary_expr)
if unary_expr.operator.is_typeof()
&& unary_expr.argument.is_identifier_reference() =>
{
Some(ctx.ast.statement_empty(SPAN))
}
// `typeof x.y` -> `x`, `!x` -> `x`, `void x` -> `x`...
Expression::UnaryExpression(unary_expr) if !unary_expr.operator.is_delete() => {
Some(ctx.ast.statement_expression(
unary_expr.span,
ctx.ast.move_expression(&mut unary_expr.argument),
))
}
_ => None,
})
}
Expand Down Expand Up @@ -548,4 +562,25 @@ mod test {
fold("([...a, b, ...c])", "([...a, ...c])");
fold_same("([...b, ...c])"); // It would also be fine if the spreads were split apart.
}

#[test]
fn test_fold_unary_expression_statement() {
fold("typeof x", "");
fold("typeof x?.y", "x?.y");
fold("typeof x.y", "x.y");
fold("typeof x.y.z()", "x.y.z()");
fold("void x", "x");
fold("void x?.y", "x?.y");
fold("void x.y", "x.y");
fold("void x.y.z()", "x.y.z()");
fold("!x", "x");
fold("!x?.y", "x?.y");
fold("!x.y", "x.y");
fold("!x.y.z()", "x.y.z()");
fold("-x.y.z()", "x.y.z()");

fold_same("delete x");
fold_same("delete x.y");
fold_same("delete x.y.z()");
}
}
5 changes: 5 additions & 0 deletions crates/oxc_syntax/src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,11 @@ impl UnaryOperator {
self == Self::Void
}

/// Returns `true` if this is the [`delete`](UnaryOperator::Delete) operator.
pub fn is_delete(self) -> bool {
self == Self::Delete
}

/// Returns `true` if this operator is a keyword instead of punctuation.
pub fn is_keyword(self) -> bool {
matches!(self, Self::Typeof | Self::Void | Self::Delete)
Expand Down
4 changes: 2 additions & 2 deletions tasks/minsize/minsize.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Original | minified | minified | gzip | gzip | Fixture

3.20 MB | 1.01 MB | 1.01 MB | 331.90 kB | 331.56 kB | echarts.js

6.69 MB | 2.32 MB | 2.31 MB | 492.86 kB | 488.28 kB | antd.js
6.69 MB | 2.32 MB | 2.31 MB | 492.87 kB | 488.28 kB | antd.js

10.95 MB | 3.50 MB | 3.49 MB | 909.32 kB | 915.50 kB | typescript.js
10.95 MB | 3.50 MB | 3.49 MB | 909.30 kB | 915.50 kB | typescript.js

0 comments on commit 7f19211

Please sign in to comment.