From 41d8d1fa2677b13ad5ca77d117c11584f03235c2 Mon Sep 17 00:00:00 2001 From: Cameron McHenry Date: Tue, 1 Oct 2024 18:46:16 -0400 Subject: [PATCH] feat(minifier): fold object constructor --- .../peephole_substitute_alternate_syntax.rs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs b/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs index e925b0b85b4e72..e3e2dadc067bc8 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_substitute_alternate_syntax.rs @@ -1,4 +1,6 @@ +use oxc_allocator::Vec; use oxc_ast::ast::*; +use oxc_semantic::IsGlobalReference; use oxc_span::{GetSpan, SPAN}; use oxc_syntax::{ number::NumberBase, @@ -80,6 +82,9 @@ impl<'a> Traverse<'a> for PeepholeSubstituteAlternateSyntax { if !self.compress_undefined(expr, ctx) { self.compress_boolean(expr, ctx); } + + self.compress_new_expression(expr, ctx); + self.compress_call_expression(expr, ctx); } fn exit_binary_expression( @@ -260,6 +265,32 @@ impl<'a> PeepholeSubstituteAlternateSyntax { self.changed = true; } } + + fn compress_new_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) { + if let Expression::NewExpression(new_expr) = expr { + // `new Object` -> `{}` + if new_expr.callee.is_global_reference_name("Object", ctx.symbols()) + && new_expr.arguments.is_empty() + { + *expr = + ctx.ast.expression_object(expr.span(), Vec::new_in(ctx.ast.allocator), None); + self.changed = true; + } + } + } + + fn compress_call_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) { + if let Expression::CallExpression(call_expr) = expr { + // `Object()` -> `{}` + if call_expr.callee.is_global_reference_name("Object", ctx.symbols()) + && call_expr.arguments.is_empty() + { + *expr = + ctx.ast.expression_object(expr.span(), Vec::new_in(ctx.ast.allocator), None); + self.changed = true; + } + } + } } /// @@ -302,4 +333,13 @@ mod test { // shadowd test_same("(function(undefined) { let x = typeof undefined; })()"); } + + #[test] + fn fold_literal_object_constructors() { + test("x = new Object", "x = ({})"); + test("x = new Object()", "x = ({})"); + test("x = Object()", "x = ({})"); + + test_same("x = (function f(){function Object(){this.x=4}return new Object();})();"); + } }