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 b954baf98071c..18c6c2e35efba 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 @@ -96,7 +96,13 @@ impl<'a> Traverse<'a> for PeepholeSubstituteAlternateSyntax { } } Expression::CallExpression(call_expr) => { - if let Some(call_expr) = Self::try_fold_call_expression(call_expr, ctx) { + if let Some(call_expr) = + Self::try_fold_literal_constructor_call_expression(call_expr, ctx) + { + *expr = call_expr; + self.changed = true; + } else if let Some(call_expr) = Self::try_fold_simple_function_call(call_expr, ctx) + { *expr = call_expr; self.changed = true; } @@ -398,7 +404,7 @@ impl<'a> PeepholeSubstituteAlternateSyntax { } } - fn try_fold_call_expression( + fn try_fold_literal_constructor_call_expression( call_expr: &mut CallExpression<'a>, ctx: &mut TraverseCtx<'a>, ) -> Option> { @@ -452,6 +458,37 @@ impl<'a> PeepholeSubstituteAlternateSyntax { } } + fn try_fold_simple_function_call( + call_expr: &mut CallExpression<'a>, + ctx: &mut TraverseCtx<'a>, + ) -> Option> { + if call_expr.optional || call_expr.arguments.len() != 1 { + return None; + } + if call_expr.callee.is_global_reference_name("Boolean", ctx.symbols()) { + // TODO + None + } else if call_expr.callee.is_global_reference_name("String", ctx.symbols()) { + // `String(a)` -> `'' + (a)` + let arg = call_expr.arguments.get_mut(0).and_then(|arg| arg.as_expression_mut())?; + + if !matches!(arg, Expression::Identifier(_) | Expression::CallExpression(_)) + && !arg.is_literal() + { + return None; + } + + Some(ctx.ast.expression_binary( + call_expr.span, + ctx.ast.expression_from_string_literal(ctx.ast.string_literal(SPAN, "")), + BinaryOperator::Addition, + ctx.ast.move_expression(arg), + )) + } else { + None + } + } + fn try_fold_chain_call_expression( &mut self, call_expr: &mut CallExpression<'a>, @@ -830,7 +867,6 @@ mod test { } #[test] - #[ignore] fn test_simple_function_call1() { test("var a = String(23)", "var a = '' + 23"); // Don't fold the existence check to preserve behavior diff --git a/tasks/minsize/minsize.snap b/tasks/minsize/minsize.snap index 1229296e2990f..66e16e5f5fe4c 100644 --- a/tasks/minsize/minsize.snap +++ b/tasks/minsize/minsize.snap @@ -6,15 +6,15 @@ Original | Minified | esbuild | Gzip | esbuild 287.63 kB | 92.83 kB | 90.07 kB | 32.29 kB | 31.95 kB | jquery.js -342.15 kB | 124.11 kB | 118.14 kB | 44.80 kB | 44.37 kB | vue.js +342.15 kB | 124.06 kB | 118.14 kB | 44.79 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.22 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.01 MB | 470.08 kB | 458.89 kB | 126.96 kB | 126.71 kB | bundle.min.js -1.25 MB | 670.96 kB | 646.76 kB | 164.72 kB | 163.73 kB | three.js +1.25 MB | 670.94 kB | 646.76 kB | 164.72 kB | 163.73 kB | three.js 2.14 MB | 756.32 kB | 724.14 kB | 182.74 kB | 181.07 kB | victory.js