diff --git a/crates/swc_ecma_transforms_optimization/src/simplify/dce/mod.rs b/crates/swc_ecma_transforms_optimization/src/simplify/dce/mod.rs index d3132804829f..b245411e6d15 100644 --- a/crates/swc_ecma_transforms_optimization/src/simplify/dce/mod.rs +++ b/crates/swc_ecma_transforms_optimization/src/simplify/dce/mod.rs @@ -211,6 +211,7 @@ struct Analyzer<'a> { #[allow(dead_code)] config: &'a Config, in_var_decl: bool, + in_param: bool, scope: Scope<'a>, data: &'a mut Data, cur_class_id: Option, @@ -518,10 +519,17 @@ impl Visit for Analyzer<'_> { } } + fn visit_param(&mut self, param: &Param) { + let old_in_param = self.in_param; + self.in_param = true; + param.visit_children_with(self); + self.in_param = old_in_param; + } + fn visit_pat(&mut self, p: &Pat) { p.visit_children_with(self); - if !self.in_var_decl { + if !self.in_var_decl && !self.in_param { if let Pat::Ident(i) = p { self.add(i.to_id(), true); } @@ -844,6 +852,35 @@ impl VisitMut for TreeShaker { self.in_fn = old_in_fn; } + fn visit_mut_params(&mut self, params: &mut Vec) { + self.visit_mut_par(cpu_count() * 8, params); + + // We iterate through trailing parameters until we either find a + // non-identifier parameter, or a parameter that can't be dropped. + let invalid_param_index = params.iter().rev().position(|param| { + let Some(id) = param.pat.as_ident() else { + // Non-identifier parameter + return true; + }; + + !self.can_drop_binding(id.to_id(), false) + }); + + match invalid_param_index { + None => { + // No invalid parameter found, we can remove all parameters. + params.clear(); + } + + Some(idx) if idx < params.len() - 1 => { + // Remove every parameter up to the invalid parameter. + params.truncate(params.len() - idx); + } + + _ => {} // No change + } + } + fn visit_mut_import_specifiers(&mut self, ss: &mut Vec) { ss.retain(|s| { let local = match s { @@ -880,6 +917,7 @@ impl VisitMut for TreeShaker { let mut analyzer = Analyzer { config: &self.config, in_var_decl: false, + in_param: false, scope: Default::default(), data: &mut data, cur_class_id: Default::default(), @@ -943,6 +981,7 @@ impl VisitMut for TreeShaker { let mut analyzer = Analyzer { config: &self.config, in_var_decl: false, + in_param: false, scope: Default::default(), data: &mut data, cur_class_id: Default::default(), diff --git a/crates/swc_ecma_transforms_optimization/tests/__swc_snapshots__/tests/simplify_dce.rs/issue_763_4.js b/crates/swc_ecma_transforms_optimization/tests/__swc_snapshots__/tests/simplify_dce.rs/issue_763_4.js index 4668de1a2296..caaeb35cc011 100644 --- a/crates/swc_ecma_transforms_optimization/tests/__swc_snapshots__/tests/simplify_dce.rs/issue_763_4.js +++ b/crates/swc_ecma_transforms_optimization/tests/__swc_snapshots__/tests/simplify_dce.rs/issue_763_4.js @@ -13,7 +13,7 @@ const resources = [ label: 'Instagram' } ]; -export function foo(websites) { +export function foo() { const a = resources.map((resource)=>({ value: resource.value })); diff --git a/crates/swc_ecma_transforms_optimization/tests/simplify.rs b/crates/swc_ecma_transforms_optimization/tests/simplify.rs index 3a8ee1291d3c..f5150198ed7e 100644 --- a/crates/swc_ecma_transforms_optimization/tests/simplify.rs +++ b/crates/swc_ecma_transforms_optimization/tests/simplify.rs @@ -489,6 +489,24 @@ fn test_template_strings_known_methods() { test("x = parseFloat(`1.23`)", "x = 1.23"); } +#[test] +fn test_redundant_params() { + // One or more parameters can be dropped + test("x = function(a, b) {}", "x = function() {}"); + test( + "x = function(a, b, c, d) {f(b);}", + "x = function(a, b) {f(b);}", + ); + test( + "x = function(a, b, c, d) {f(c);}", + "x = function(a, b, c) {f(c);}", + ); + + // No parameters can be dropped + test_same("x = function(a, b) {f(b);}"); + test_same("x = function(a) {f(a);}"); +} + test!( Syntax::Typescript(TsSyntax { decorators: true, diff --git a/crates/swc_node_bundler/tests/pass/cjs/conditional/output/entry.js b/crates/swc_node_bundler/tests/pass/cjs/conditional/output/entry.js index cac06794599f..ea34c8b5a388 100644 --- a/crates/swc_node_bundler/tests/pass/cjs/conditional/output/entry.js +++ b/crates/swc_node_bundler/tests/pass/cjs/conditional/output/entry.js @@ -31,7 +31,7 @@ function __swcpack_require__(mod) { cache = interop(module.exports); return cache; } -var load = __swcpack_require__.bind(void 0, function(module, exports) { +var load = __swcpack_require__.bind(void 0, function() { console.log("foo"); console.log("bar"); }); diff --git a/crates/swc_node_bundler/tests/pass/cjs/issue-967-no-recursive-require/output/entry.js b/crates/swc_node_bundler/tests/pass/cjs/issue-967-no-recursive-require/output/entry.js index 87edd8f49412..c2fd9d813897 100644 --- a/crates/swc_node_bundler/tests/pass/cjs/issue-967-no-recursive-require/output/entry.js +++ b/crates/swc_node_bundler/tests/pass/cjs/issue-967-no-recursive-require/output/entry.js @@ -31,13 +31,13 @@ function __swcpack_require__(mod) { cache = interop(module.exports); return cache; } -var load = __swcpack_require__.bind(void 0, function(module, exports) { +var load = __swcpack_require__.bind(void 0, function() { console.log("a"); }); -var load1 = __swcpack_require__.bind(void 0, function(module, exports) { +var load1 = __swcpack_require__.bind(void 0, function() { console.log("b"); }); -var load2 = __swcpack_require__.bind(void 0, function(module, exports) { +var load2 = __swcpack_require__.bind(void 0, function() { console.log("c"); }); load(); diff --git a/crates/swc_node_bundler/tests/pass/cjs/issue-967-recursive-require/output/entry.js b/crates/swc_node_bundler/tests/pass/cjs/issue-967-recursive-require/output/entry.js index 265ca8b333ab..7565ce940d13 100644 --- a/crates/swc_node_bundler/tests/pass/cjs/issue-967-recursive-require/output/entry.js +++ b/crates/swc_node_bundler/tests/pass/cjs/issue-967-recursive-require/output/entry.js @@ -56,7 +56,7 @@ var load4 = __swcpack_require__.bind(void 0, function(module, exports) { bb: bb }; }); -var load5 = __swcpack_require__.bind(void 0, function(module, exports) { +var load5 = __swcpack_require__.bind(void 0, function() { console.log("c"); }); load4(); diff --git a/crates/swc_node_bundler/tests/pass/deno-001/full/output/entry.js b/crates/swc_node_bundler/tests/pass/deno-001/full/output/entry.js index de44e9e8c6da..cbec08ad39e9 100644 --- a/crates/swc_node_bundler/tests/pass/deno-001/full/output/entry.js +++ b/crates/swc_node_bundler/tests/pass/deno-001/full/output/entry.js @@ -421,7 +421,7 @@ class MuxAsyncIterator { } function emptyReader() { return { - read (_) { + read () { return Promise.resolve(null); } }; diff --git a/crates/swc_node_bundler/tests/pass/deno-001/simple-1/output/entry.js b/crates/swc_node_bundler/tests/pass/deno-001/simple-1/output/entry.js index fd6357cf2718..c4ca42f4e3ba 100644 --- a/crates/swc_node_bundler/tests/pass/deno-001/simple-1/output/entry.js +++ b/crates/swc_node_bundler/tests/pass/deno-001/simple-1/output/entry.js @@ -52,7 +52,7 @@ class MuxAsyncIterator { } function emptyReader() { return { - read (_) { + read () { return Promise.resolve(null); } }; diff --git a/crates/swc_node_bundler/tests/pass/deno-001/simple-2/output/entry.js b/crates/swc_node_bundler/tests/pass/deno-001/simple-2/output/entry.js index 0548a9e77a9f..cd036f0536c9 100644 --- a/crates/swc_node_bundler/tests/pass/deno-001/simple-2/output/entry.js +++ b/crates/swc_node_bundler/tests/pass/deno-001/simple-2/output/entry.js @@ -23,10 +23,10 @@ class ServerRequest { } } console.log(ServerRequest); -async function writeResponse(w, r) {} -async function readRequest(conn, bufr) {} +async function writeResponse() {} +async function readRequest() {} console.log(deferred, writeResponse, readRequest, MuxAsyncIterator); -async function listenAndServe(addr, handler) {} +async function listenAndServe() {} listenAndServe({ port: 8080 }, async (req)=>{}); diff --git a/crates/swc_node_bundler/tests/pass/issue-1328/case1/output/entry.js b/crates/swc_node_bundler/tests/pass/issue-1328/case1/output/entry.js index ab7ec169fc52..55810d44b209 100644 --- a/crates/swc_node_bundler/tests/pass/issue-1328/case1/output/entry.js +++ b/crates/swc_node_bundler/tests/pass/issue-1328/case1/output/entry.js @@ -127,7 +127,7 @@ function foo() { } function _foo() { _foo = _async_to_generator(function() { - return _ts_generator(this, function(_state) { + return _ts_generator(this, function() { return [ 2 ]; diff --git a/crates/swc_node_bundler/tests/pass/issue-2124/named-export/output/entry.js b/crates/swc_node_bundler/tests/pass/issue-2124/named-export/output/entry.js index 994c850f41f0..77db5324cb9d 100644 --- a/crates/swc_node_bundler/tests/pass/issue-2124/named-export/output/entry.js +++ b/crates/swc_node_bundler/tests/pass/issue-2124/named-export/output/entry.js @@ -32,7 +32,7 @@ function __swcpack_require__(mod) { return cache; } var load = __swcpack_require__.bind(void 0, function(module, exports) { - function lodash(value) { + function lodash() { console.log("lodash"); } function memoize() { diff --git a/crates/swc_node_bundler/tests/pass/regenerator/1/output/entry.js b/crates/swc_node_bundler/tests/pass/regenerator/1/output/entry.js index 55e9794ac9a9..2acc7eb0880e 100644 --- a/crates/swc_node_bundler/tests/pass/regenerator/1/output/entry.js +++ b/crates/swc_node_bundler/tests/pass/regenerator/1/output/entry.js @@ -127,7 +127,7 @@ function foo() { } function _foo() { _foo = _async_to_generator(function() { - return _ts_generator(this, function(_state) { + return _ts_generator(this, function() { return [ 2 ];