From 0fb2c1d5a539d656f337d0ef4c9392f01817986d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Tue, 27 Sep 2022 17:38:14 +0900 Subject: [PATCH] fix(es/minifier): Fix analysis of nested function-like properties (#5963) **Related issue:** - Closes https://github.com/swc-project/swc/issues/5950. --- .../swc/tests/exec/issues-5xxx/5950/1/.swcrc | 69 +++++++++++++++++++ .../swc/tests/exec/issues-5xxx/5950/1/exec.js | 14 ++++ crates/swc_ecma_minifier/src/analyzer/mod.rs | 63 +++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 crates/swc/tests/exec/issues-5xxx/5950/1/.swcrc create mode 100644 crates/swc/tests/exec/issues-5xxx/5950/1/exec.js diff --git a/crates/swc/tests/exec/issues-5xxx/5950/1/.swcrc b/crates/swc/tests/exec/issues-5xxx/5950/1/.swcrc new file mode 100644 index 00000000000..6dc6005ce02 --- /dev/null +++ b/crates/swc/tests/exec/issues-5xxx/5950/1/.swcrc @@ -0,0 +1,69 @@ +{ + "jsc": { + "target": "es5", + "minify": { + "compress": { + "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 + }, + "mangle": { + "toplevel": false, + "keep_classnames": false, + "keep_fnames": false, + "keep_private_props": false, + "ie8": false, + "safari10": false + } + } + }, + "module": { + "type": "es6" + }, + "minify": true, + "isModule": true, + "env": { + "targets": "" + } +} \ No newline at end of file diff --git a/crates/swc/tests/exec/issues-5xxx/5950/1/exec.js b/crates/swc/tests/exec/issues-5xxx/5950/1/exec.js new file mode 100644 index 00000000000..13b4c96c75d --- /dev/null +++ b/crates/swc/tests/exec/issues-5xxx/5950/1/exec.js @@ -0,0 +1,14 @@ +class Test { + constructor(config) { + const that = this; + this.config = config; + this.options = { + get config() { + return that.config; + }, + }; + } +} + +const instance = new Test(42); +console.log(instance.options.config); // should log 42 \ No newline at end of file diff --git a/crates/swc_ecma_minifier/src/analyzer/mod.rs b/crates/swc_ecma_minifier/src/analyzer/mod.rs index 3913afa0df0..fa3aa94e185 100644 --- a/crates/swc_ecma_minifier/src/analyzer/mod.rs +++ b/crates/swc_ecma_minifier/src/analyzer/mod.rs @@ -1143,6 +1143,69 @@ where }); } + #[cfg_attr(feature = "debug", tracing::instrument(skip(self, n)))] + fn visit_method_prop(&mut self, n: &MethodProp) { + n.function.decorators.visit_with(self); + + self.with_child(n.function.span.ctxt, ScopeKind::Fn, |a| { + n.key.visit_with(a); + { + let ctx = Ctx { + in_pat_of_param: true, + ..a.ctx + }; + n.function.params.visit_with(&mut *a.with_ctx(ctx)); + } + + n.function.visit_with(a); + }); + } + + #[cfg_attr(feature = "debug", tracing::instrument(skip(self, n)))] + fn visit_getter_prop(&mut self, n: &GetterProp) { + self.with_child(n.span.ctxt, ScopeKind::Fn, |a| { + n.key.visit_with(a); + + n.body.visit_with(a); + }); + } + + #[cfg_attr(feature = "debug", tracing::instrument(skip(self, n)))] + fn visit_class_method(&mut self, n: &ClassMethod) { + n.function.decorators.visit_with(self); + + self.with_child(n.function.span.ctxt, ScopeKind::Fn, |a| { + n.key.visit_with(a); + { + let ctx = Ctx { + in_pat_of_param: true, + ..a.ctx + }; + n.function.params.visit_with(&mut *a.with_ctx(ctx)); + } + + n.function.visit_with(a); + }); + } + + #[cfg_attr(feature = "debug", tracing::instrument(skip(self, n)))] + fn visit_private_method(&mut self, n: &PrivateMethod) { + n.function.decorators.visit_with(self); + + self.with_child(n.function.span.ctxt, ScopeKind::Fn, |a| { + n.key.visit_with(a); + { + let ctx = Ctx { + in_pat_of_param: true, + ..a.ctx + }; + n.function.params.visit_with(&mut *a.with_ctx(ctx)); + } + + n.function.visit_with(a); + }); + } + #[cfg_attr(feature = "debug", tracing::instrument(skip(self, n)))] fn visit_stmt(&mut self, n: &Stmt) { let ctx = Ctx {