Skip to content

Commit

Permalink
feat(minifier): dce pure expressions such as new Map()
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Jan 26, 2025
1 parent 03229c5 commit a31383b
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 2 deletions.
84 changes: 83 additions & 1 deletion crates/oxc_minifier/src/peephole/remove_dead_code.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use oxc_allocator::Vec;
use oxc_ast::{ast::*, Visit};
use oxc_ecmascript::{
constant_evaluation::{ConstantEvaluation, IsLiteralValue},
constant_evaluation::{ConstantEvaluation, IsLiteralValue, ValueType},
side_effects::MayHaveSideEffects,
};
use oxc_span::GetSpan;
Expand Down Expand Up @@ -358,6 +358,51 @@ impl<'a, 'b> PeepholeOptimizations {
ctx.ast.move_expression(&mut unary_expr.argument),
))
}
Expression::NewExpression(e) => {
let Expression::Identifier(ident) = &e.callee else { return None };
let len = e.arguments.len();
if match ident.name.as_str() {
"WeakSet" | "WeakMap" if ctx.is_global_reference(ident) => match len {
0 => true,
1 => match e.arguments[0].as_expression()? {
Expression::NullLiteral(_) => true,
Expression::ArrayExpression(e) => e.elements.is_empty(),
e if ctx.is_expression_undefined(e) => true,
_ => false,
},
_ => false,
},
"Date" if ctx.is_global_reference(ident) => match len {
0 => true,
1 => {
let arg = e.arguments[0].as_expression()?;
let ty = ValueType::from(arg);
matches!(
ty,
ValueType::Null
| ValueType::Undefined
| ValueType::Boolean
| ValueType::Number
| ValueType::String
) && !ctx.expression_may_have_side_efffects(arg)
}
_ => false,
},
"Set" | "Map" if ctx.is_global_reference(ident) => match len {
0 => true,
1 => match e.arguments[0].as_expression()? {
Expression::NullLiteral(_) => true,
e if ctx.is_expression_undefined(e) => true,
_ => false,
},
_ => false,
},
_ => false,
} {
return Some(ctx.ast.statement_empty(e.span));
}
None
}
_ => None,
}
}
Expand Down Expand Up @@ -811,6 +856,43 @@ mod test {
test("1", "");
}

#[test]
fn test_new_constructor_side_effect() {
test("new WeakSet()", "");
test("new WeakSet(null)", "");
test("new WeakSet(void 0)", "");
test("new WeakSet([])", "");
test_same("new WeakSet([x])");
test_same("new WeakSet(x)");
test("new WeakMap()", "");
test("new WeakMap(null)", "");
test("new WeakMap(void 0)", "");
test("new WeakMap([])", "");
test_same("new WeakMap([x])");
test_same("new WeakMap(x)");
test("new Date()", "");
test("new Date('')", "");
test("new Date(0)", "");
test("new Date(null)", "");
test("new Date(true)", "");
test("new Date(false)", "");
test("new Date(undefined)", "");
test_same("new Date(x)");
test("new Set()", "");
// test("new Set([a, b, c])", "");
test("new Set(null)", "");
test("new Set(undefined)", "");
test("new Set(void 0)", "");
test_same("new Set(x)");
test("new Map()", "");
test("new Map(null)", "");
test("new Map(undefined)", "");
test("new Map(void 0)", "");
// test_same("new Map([x])");
test_same("new Map(x)");
// test("new Map([[a, b], [c, d]])", "");
}

#[test]
fn keep_module_syntax() {
test_same("throw foo; export let bar");
Expand Down
2 changes: 1 addition & 1 deletion tasks/minsize/minsize.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Original | minified | minified | gzip | gzip | Fixture
-------------------------------------------------------------------------------------
72.14 kB | 23.61 kB | 23.70 kB | 8.55 kB | 8.54 kB | react.development.js

173.90 kB | 59.69 kB | 59.82 kB | 19.26 kB | 19.33 kB | moment.js
173.90 kB | 59.71 kB | 59.82 kB | 19.26 kB | 19.33 kB | moment.js

287.63 kB | 89.58 kB | 90.07 kB | 31.08 kB | 31.95 kB | jquery.js

Expand Down

0 comments on commit a31383b

Please sign in to comment.