diff --git a/crates/swc_ecma_minifier/scripts/reduce/reduce.sh b/crates/swc_ecma_minifier/scripts/reduce/reduce.sh index 722d23390969..1ad58efc96ed 100755 --- a/crates/swc_ecma_minifier/scripts/reduce/reduce.sh +++ b/crates/swc_ecma_minifier/scripts/reduce/reduce.sh @@ -9,12 +9,15 @@ then fi SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +TARGET_DIR="$(cargo metadata --format-version 1 --no-deps | jq -r '.target_directory')" echo "Reducing $1" ls -al $1 + # Build swc minifier -export MINIFY=$(cargo profile bin-path --release --example compress) +cargo build --release --example compress +export MINIFY="$TARGET_DIR/release/examples/compress" wd="$(mktemp -d)" echo "Using $MINIFY; dir = $wd" diff --git a/crates/swc_ecma_minifier/scripts/test.sh b/crates/swc_ecma_minifier/scripts/test.sh index 249ea55eb6d2..ffe66f937f8f 100755 --- a/crates/swc_ecma_minifier/scripts/test.sh +++ b/crates/swc_ecma_minifier/scripts/test.sh @@ -8,6 +8,6 @@ export SWC_RUN=0 touch tests/compress.rs -cargo test -q -p swc_ecma_minifier -p swc --no-fail-fast --test projects --test tsc --test compress --test mangle --features concurrent $@ +cargo test -p swc_ecma_minifier -p swc --no-fail-fast --test projects --test tsc --test compress --test mangle --features concurrent $@ # find ../swc/tests/ -type f -empty -delete \ No newline at end of file diff --git a/crates/swc_ecma_minifier/src/compress/optimize/iife.rs b/crates/swc_ecma_minifier/src/compress/optimize/iife.rs index 6d8200c5d52f..200278abf23f 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/iife.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/iife.rs @@ -480,6 +480,11 @@ impl Optimizer<'_> { return; } + if self.ctx.in_param && !f.params.is_empty() { + log_abort!("iife: We don't invoke IIFE with params in function params"); + return; + } + if !self.may_add_ident() { match &*f.body { BlockStmtOrExpr::BlockStmt(body) => { @@ -595,6 +600,11 @@ impl Optimizer<'_> { return; } + if self.ctx.in_param && !f.function.params.is_empty() { + log_abort!("iife: We don't invoke IIFE with params in function params"); + return; + } + // Abort if a parameter is complex if f.function.params.iter().any(|param| { matches!( diff --git a/crates/swc_ecma_minifier/src/compress/optimize/mod.rs b/crates/swc_ecma_minifier/src/compress/optimize/mod.rs index 770d14ecf4e5..062c16944ff2 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/mod.rs @@ -172,6 +172,8 @@ struct Ctx { in_with_stmt: bool, + in_param: bool, + /// Current scope. scope: SyntaxContext, } @@ -1459,9 +1461,16 @@ impl VisitMut for Optimizer<'_> { let prepend = self.prepend_stmts.take(); - let ctx = self.ctx; + { + let ctx = Ctx { + in_param: true, + ..self.ctx + }; + + n.params.visit_mut_with(&mut *self.with_ctx(ctx)); + } - n.visit_mut_children_with(&mut *self.with_ctx(ctx)); + n.body.visit_mut_with(self); if !self.prepend_stmts.is_empty() { let mut stmts = self.prepend_stmts.take().take_stmts(); @@ -1561,6 +1570,7 @@ impl VisitMut for Optimizer<'_> { top_level: false, in_block: true, scope: n.span.ctxt, + in_param: false, ..self.ctx }; n.visit_mut_children_with(&mut *self.with_ctx(ctx)); @@ -2360,6 +2370,7 @@ impl VisitMut for Optimizer<'_> { fn visit_mut_param(&mut self, n: &mut Param) { let ctx = Ctx { var_kind: None, + in_param: true, ..self.ctx }; let mut o = self.with_ctx(ctx); diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8826/config.json b/crates/swc_ecma_minifier/tests/fixture/issues/8826/config.json new file mode 100644 index 000000000000..7e144b291fa7 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/8826/config.json @@ -0,0 +1,47 @@ +{ + "defaults": true, + "arguments": false, + "arrows": true, + "booleans": true, + "booleans_as_integers": false, + "collapse_vars": true, + "comparisons": true, + "computed_props": true, + "conditionals": true, + "dead_code": true, + "directives": true, + "drop_console": false, + "drop_debugger": true, + "evaluate": true, + "expression": false, + "hoist_funs": false, + "hoist_props": true, + "hoist_vars": false, + "if_return": true, + "join_vars": true, + "keep_classnames": false, + "keep_fargs": true, + "keep_fnames": false, + "keep_infinity": false, + "loops": true, + "negate_iife": true, + "properties": true, + "reduce_funcs": false, + "reduce_vars": false, + "side_effects": true, + "switches": true, + "typeofs": true, + "unsafe": false, + "unsafe_arrows": false, + "unsafe_comps": false, + "unsafe_Function": false, + "unsafe_math": false, + "unsafe_symbols": false, + "unsafe_methods": false, + "unsafe_proto": false, + "unsafe_regexp": false, + "unsafe_undefined": false, + "unused": true, + "const_to_let": true, + "pristine_globals": true +} diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8826/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/8826/input.js new file mode 100644 index 000000000000..c1b9d7865f7e --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/8826/input.js @@ -0,0 +1,12 @@ + +export function createTypeChecker(host) { + + return { + getFlowTypeOfReference + } + + function getFlowTypeOfReference(reference, declaredType, initialType = declaredType, flowContainer, flowNode = (_a2 => (_a2 = tryCast(reference, canHaveFlowNode)) == null ? void 0 : _a2.flowNode)()) { + + + } +} \ No newline at end of file diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8826/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/8826/output.js new file mode 100644 index 000000000000..c75f1bda7604 --- /dev/null +++ b/crates/swc_ecma_minifier/tests/fixture/issues/8826/output.js @@ -0,0 +1,5 @@ +export function createTypeChecker(host) { + return { + getFlowTypeOfReference: function(reference, declaredType, initialType = declaredType, flowContainer, flowNode = ((_a2)=>null == (_a2 = tryCast(reference, canHaveFlowNode)) ? void 0 : _a2.flowNode)()) {} + }; +}