From cb2d87b95d3af31add2749bb4db62b83fd336310 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Sat, 21 May 2022 17:34:27 +0200 Subject: [PATCH 1/3] Add test --- .../scope-hoisting/es6/rename-member-prop/a.js | 5 +++++ .../core/integration-tests/test/scope-hoisting.js | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/rename-member-prop/a.js diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/rename-member-prop/a.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/rename-member-prop/a.js new file mode 100644 index 00000000000..a6b6db35cac --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/rename-member-prop/a.js @@ -0,0 +1,5 @@ +export function foo(x) { + return [x.foo, x?.foo]; +} + +output = foo; diff --git a/packages/core/integration-tests/test/scope-hoisting.js b/packages/core/integration-tests/test/scope-hoisting.js index cb669087c7a..33144b862e4 100644 --- a/packages/core/integration-tests/test/scope-hoisting.js +++ b/packages/core/integration-tests/test/scope-hoisting.js @@ -186,6 +186,18 @@ describe('scope hoisting', function () { assert.deepEqual(output, ['1', '2']); }); + it("doesn't rename member expression properties", async function () { + let b = await bundle( + path.join( + __dirname, + '/integration/scope-hoisting/es6/rename-member-prop/a.js', + ), + ); + + let output = await run(b); + assert.deepEqual(output({foo: 12}), [12, 12]); + }); + it('supports renaming imports', async function () { let b = await bundle( path.join( From 6138ad9787ed367e711f86fe95e1749100854f1e Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Sat, 21 May 2022 17:21:26 +0200 Subject: [PATCH 2/3] Key exports_locals by Id instead of JsWord --- packages/transformers/js/core/src/hoist.rs | 25 ++++++++++------------ 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/packages/transformers/js/core/src/hoist.rs b/packages/transformers/js/core/src/hoist.rs index e1142574249..5145d6bf3d1 100644 --- a/packages/transformers/js/core/src/hoist.rs +++ b/packages/transformers/js/core/src/hoist.rs @@ -254,10 +254,7 @@ impl<'a> Fold for Hoist<'a> { id.0 } else { self - .get_export_ident( - DUMMY_SP, - self.collect.exports_locals.get(&id.0).unwrap(), - ) + .get_export_ident(DUMMY_SP, self.collect.exports_locals.get(&id).unwrap()) .sym }; self.exported_symbols.push(ExportedSymbol { @@ -770,7 +767,7 @@ impl<'a> Fold for Hoist<'a> { } } - if let Some(exported) = self.collect.exports_locals.get(&node.sym) { + if let Some(exported) = self.collect.exports_locals.get(&id!(node)) { // If wrapped, mark the original symbol as exported. // Otherwise replace with an export identifier. if self.collect.should_wrap { @@ -1094,7 +1091,7 @@ pub struct Collect { // exported name -> descriptor pub exports: HashMap, // local name -> exported name - pub exports_locals: HashMap, + pub exports_locals: HashMap, pub exports_all: HashMap, pub non_static_access: HashMap>, pub non_const_bindings: HashMap>, @@ -1373,7 +1370,7 @@ impl Visit for Collect { if node.src.is_none() { self .exports_locals - .entry(match_export_name_ident(&named.orig).sym.clone()) + .entry(id!(match_export_name_ident(&named.orig))) .or_insert_with(|| exported.0.clone()); } } @@ -1389,7 +1386,7 @@ impl Visit for Collect { if node.src.is_none() { self .exports_locals - .entry(default.exported.sym.clone()) + .entry(id!(default.exported)) .or_insert_with(|| js_word!("default")); } } @@ -1422,7 +1419,7 @@ impl Visit for Collect { ); self .exports_locals - .entry(class.ident.sym.clone()) + .entry(id!(class.ident)) .or_insert_with(|| class.ident.sym.clone()); } Decl::Fn(func) => { @@ -1436,7 +1433,7 @@ impl Visit for Collect { ); self .exports_locals - .entry(func.ident.sym.clone()) + .entry(id!(func.ident)) .or_insert_with(|| func.ident.sym.clone()); } Decl::Var(var) => { @@ -1468,7 +1465,7 @@ impl Visit for Collect { ); self .exports_locals - .entry(ident.sym.clone()) + .entry(id!(ident)) .or_insert_with(|| js_word!("default")); } else { self.exports.insert( @@ -1493,7 +1490,7 @@ impl Visit for Collect { ); self .exports_locals - .entry(ident.sym.clone()) + .entry(id!(ident)) .or_insert_with(|| js_word!("default")); } else { self.exports.insert( @@ -1555,7 +1552,7 @@ impl Visit for Collect { ); self .exports_locals - .entry(node.id.sym.clone()) + .entry(id!(node.id)) .or_insert_with(|| node.id.sym.clone()); } @@ -1580,7 +1577,7 @@ impl Visit for Collect { ); self .exports_locals - .entry(node.key.sym.clone()) + .entry(id!(node.key)) .or_insert_with(|| node.key.sym.clone()); } From d2cbe48f519b9d416845e23b61d74e8f9390d857 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Sat, 21 May 2022 17:28:42 +0200 Subject: [PATCH 3/3] Handle optional chaining wrapper in hoist --- packages/transformers/js/core/src/hoist.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/transformers/js/core/src/hoist.rs b/packages/transformers/js/core/src/hoist.rs index 5145d6bf3d1..c374b926ec8 100644 --- a/packages/transformers/js/core/src/hoist.rs +++ b/packages/transformers/js/core/src/hoist.rs @@ -511,6 +511,21 @@ impl<'a> Fold for Hoist<'a> { fn fold_expr(&mut self, node: Expr) -> Expr { match node { + Expr::OptChain(opt) => { + return Expr::OptChain(OptChainExpr { + span: opt.span, + question_dot_token: opt.question_dot_token, + base: match opt.base { + OptChainBase::Call(call) => OptChainBase::Call(call.fold_with(self)), + OptChainBase::Member(member) => OptChainBase::Member(MemberExpr { + span: member.span, + obj: member.obj.fold_with(self), + // Don't visit member.prop so we avoid the ident visitor. + prop: member.prop, + }), + }, + }); + } Expr::Member(member) => { if !self.collect.should_wrap { if match_member_expr(&member, vec!["module", "exports"], &self.collect.decls) { @@ -582,7 +597,7 @@ impl<'a> Fold for Hoist<'a> { return Expr::Ident(self.get_export_ident(member.span, &key)); } } - Expr::Call(_call) => { + Expr::Call(_) => { // require('foo').bar -> $id$import$foo$bar if let Some(source) = match_require(&member.obj, &self.collect.decls, self.collect.ignore_mark)