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 6459b0367f12b..3c007cbc29d9e 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,5 +1,5 @@ -use oxc_allocator::Vec; -use oxc_ast::ast::*; +use oxc_allocator::{CloneIn, Vec}; +use oxc_ast::{ast::*, NONE}; use oxc_semantic::IsGlobalReference; use oxc_span::{GetSpan, SPAN}; use oxc_syntax::number::ToJsInt32; @@ -321,13 +321,57 @@ impl<'a> PeepholeSubstituteAlternateSyntax { *expr = ctx.ast.expression_object(expr.span(), Vec::new_in(ctx.ast.allocator), None); self.changed = true; - } - // `new Array` -> `[]` - else if new_expr.arguments.is_empty() - && new_expr.callee.is_global_reference_name("Array", ctx.symbols()) - { - *expr = ctx.ast.expression_array(expr.span(), Vec::new_in(ctx.ast.allocator), None); - self.changed = true; + } else if new_expr.callee.is_global_reference_name("Array", ctx.symbols()) { + // `new Array` -> `[]` + if new_expr.arguments.is_empty() { + *expr = + ctx.ast.expression_array(expr.span(), Vec::new_in(ctx.ast.allocator), None); + self.changed = true; + } else if new_expr.arguments.len() == 1 { + let Some(arg) = new_expr.arguments[0].as_expression() else { return }; + // `new Array(0)` -> `[]` + if arg.is_number_0() { + *expr = ctx.ast.expression_array( + expr.span(), + Vec::new_in(ctx.ast.allocator), + None, + ); + self.changed = true; + } + // `new Array(8)` -> `Array(8)` + else if arg.is_number_literal() { + let mut arguments = Vec::new_in(ctx.ast.allocator); + arguments + .push(ctx.ast.argument_expression((*arg).clone_in(ctx.ast.allocator))); + *expr = ctx.ast.expression_call( + new_expr.span, + new_expr.callee.clone_in(ctx.ast.allocator), + NONE, + arguments, + false, + ) + } + // `new Array(literal)` -> `[literal]` + else if arg.is_literal() { + let mut elements = Vec::new_in(ctx.ast.allocator); + let element = ctx.ast.array_expression_element_expression( + (*arg).clone_in(ctx.ast.allocator), + ); + elements.push(element); + *expr = ctx.ast.expression_array(expr.span(), elements, None); + self.changed = true; + } + // `new Array()` -> `Array()` + else { + *expr = ctx.ast.expression_call( + new_expr.span, + new_expr.callee.clone_in(ctx.ast.allocator), + NONE, + new_expr.arguments.clone_in(ctx.ast.allocator), + false, + ) + } + } } } } @@ -434,15 +478,15 @@ mod test { test_same("x = Array?.()"); // One argument - // test("x = new Array(0)", "x = []"); + test("x = new Array(0)", "x = []"); + test("x = new Array(\"a\")", "x = [\"a\"]"); + test("x = new Array(7)", "x = Array(7)"); + test("x = new Array(y)", "x = Array(y)"); + test("x = new Array(foo())", "x = Array(foo())"); // test("x = Array(0)", "x = []"); - // test("x = new Array(\"a\")", "x = [\"a\"]"); // test("x = Array(\"a\")", "x = [\"a\"]"); - // test("x = new Array(7)", "x = Array(7)"); // test_same("x = Array(7)"); - // test("x = new Array(y)", "x = Array(y)"); // test_same("x = Array(y)"); - // test("x = new Array(foo())", "x = Array(foo())"); // test_same("x = Array(foo())"); // // 1+ arguments diff --git a/tasks/minsize/minsize.snap b/tasks/minsize/minsize.snap index f8aea21743240..b05441ccd0f95 100644 --- a/tasks/minsize/minsize.snap +++ b/tasks/minsize/minsize.snap @@ -1,26 +1,26 @@ Original | Minified | esbuild | Gzip | esbuild -72.14 kB | 24.47 kB | 23.70 kB | 8.65 kB | 8.54 kB | react.development.js +72.14 kB | 24.46 kB | 23.70 kB | 8.65 kB | 8.54 kB | react.development.js 173.90 kB | 61.69 kB | 59.82 kB | 19.54 kB | 19.33 kB | moment.js 287.63 kB | 92.83 kB | 90.07 kB | 32.29 kB | 31.95 kB | jquery.js -342.15 kB | 124.14 kB | 118.14 kB | 44.81 kB | 44.37 kB | vue.js +342.15 kB | 124.11 kB | 118.14 kB | 44.80 kB | 44.37 kB | vue.js 544.10 kB | 74.13 kB | 72.48 kB | 26.23 kB | 26.20 kB | lodash.js -555.77 kB | 278.68 kB | 270.13 kB | 91.39 kB | 90.80 kB | d3.js +555.77 kB | 278.24 kB | 270.13 kB | 91.36 kB | 90.80 kB | d3.js 1.01 MB | 470.11 kB | 458.89 kB | 126.97 kB | 126.71 kB | bundle.min.js -1.25 MB | 671.00 kB | 646.76 kB | 164.72 kB | 163.73 kB | three.js +1.25 MB | 670.97 kB | 646.76 kB | 164.72 kB | 163.73 kB | three.js -2.14 MB | 756.69 kB | 724.14 kB | 182.87 kB | 181.07 kB | victory.js +2.14 MB | 756.33 kB | 724.14 kB | 182.74 kB | 181.07 kB | victory.js 3.20 MB | 1.05 MB | 1.01 MB | 334.10 kB | 331.56 kB | echarts.js -4.12 MB | 1.68 MB | 2.31 MB | 484.25 kB | 488.28 kB | antd.js +4.12 MB | 1.68 MB | 2.31 MB | 484.21 kB | 488.28 kB | antd.js -10.95 MB | 3.59 MB | 3.49 MB | 913.96 kB | 915.50 kB | typescript.js +10.95 MB | 3.59 MB | 3.49 MB | 913.92 kB | 915.50 kB | typescript.js