diff --git a/crates/swc_ecma_transforms_module/src/util.rs b/crates/swc_ecma_transforms_module/src/util.rs index 513fa986796..867e81ac96e 100644 --- a/crates/swc_ecma_transforms_module/src/util.rs +++ b/crates/swc_ecma_transforms_module/src/util.rs @@ -672,7 +672,13 @@ impl Scope { let mut found: Vec<(JsWord, Span)> = vec![]; let mut v = DestructuringFinder { found: &mut found }; - expr.left.visit_with(&mut v); + + if let PatOrExpr::Expr(e) = &expr.left { + e.visit_children_with(&mut v); + } else { + expr.left.visit_with(&mut v); + } + if v.found.is_empty() { return Expr::Assign(AssignExpr { left: expr.left, @@ -759,63 +765,52 @@ impl Scope { } } - match expr.left { - PatOrExpr::Pat(pat) if pat.is_ident() => { - let i = pat.expect_ident(); - let mut scope = folder.scope_mut(); - let entry = scope - .exported_bindings - .entry((i.id.sym.clone(), i.id.span.ctxt())); + if let Some(ident) = expr.left.as_ident() { + let mut scope = folder.scope_mut(); + let entry = scope + .exported_bindings + .entry((ident.sym.clone(), ident.span.ctxt())); - match entry { - Entry::Occupied(entry) => { - let expr = Expr::Assign(AssignExpr { - left: PatOrExpr::Pat(i.into()), - ..expr - }); - let e = chain_assign!(entry, Box::new(expr)); + match entry { + Entry::Occupied(entry) => { + let expr = Expr::Assign(expr); - *e - } - _ => Expr::Assign(AssignExpr { - left: PatOrExpr::Pat(i.into()), - ..expr - }), + *chain_assign!(entry, Box::new(expr)) } + _ => expr.into(), } - _ => { - let mut exprs = iter::once(Box::new(Expr::Assign(expr))) - .chain( - found - .into_iter() - .map(|var| Ident::new(var.0, var.1)) - .filter_map(|i| { - let mut scope = folder.scope_mut(); - let entry = match scope - .exported_bindings - .entry((i.sym.clone(), i.span.ctxt())) - { - Entry::Occupied(entry) => entry, - _ => { - return None; - } - }; - let e = chain_assign!(entry, Box::new(Expr::Ident(i))); + } else { + let mut exprs = iter::once(Box::new(Expr::Assign(expr))) + .chain( + found + .into_iter() + .map(|var| Ident::new(var.0, var.1)) + .filter_map(|i| { + let mut scope = folder.scope_mut(); + let entry = match scope + .exported_bindings + .entry((i.sym.clone(), i.span.ctxt())) + { + Entry::Occupied(entry) => entry, + _ => { + return None; + } + }; + let e = chain_assign!(entry, Box::new(Expr::Ident(i))); - // exports.name = x - Some(e) - }), - ) - .collect::>(); - if exprs.len() == 1 { - return *exprs.pop().unwrap(); - } - - Expr::Seq(SeqExpr { - span: DUMMY_SP, - exprs, - }) + // exports.name = x + Some(e) + }), + ) + .collect::>(); + if exprs.len() == 1 { + return *exprs.pop().unwrap(); } + + Expr::Seq(SeqExpr { + span: DUMMY_SP, + exprs, + }) } } _ => expr.fold_children_with(folder), diff --git a/crates/swc_ecma_transforms_module/tests/fixture/commonjs/issue-3898/1/input.js b/crates/swc_ecma_transforms_module/tests/fixture/commonjs/issue-3898/1/input.js new file mode 100644 index 00000000000..5b9eaec4a18 --- /dev/null +++ b/crates/swc_ecma_transforms_module/tests/fixture/commonjs/issue-3898/1/input.js @@ -0,0 +1,21 @@ +export let foo = 1; +foo = 2; +foo += 2; +foo -= 2; +foo *= 2; +foo /= 2; +foo %= 2; +foo <<= 2; +foo >>= 2; +foo >>>= 2; +foo |= 2; +foo ^= 2; +foo &= 2; +foo **= 2; +foo &&= 2; +foo ||= 2; +foo ??= 2; + +[foo] = [2]; +[foo = 3] = []; +({ bar: foo } = { bar: 2 }); diff --git a/crates/swc_ecma_transforms_module/tests/fixture/commonjs/issue-3898/1/output.js b/crates/swc_ecma_transforms_module/tests/fixture/commonjs/issue-3898/1/output.js new file mode 100644 index 00000000000..eb3c41dab72 --- /dev/null +++ b/crates/swc_ecma_transforms_module/tests/fixture/commonjs/issue-3898/1/output.js @@ -0,0 +1,30 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.foo = void 0; +let foo = 1; +exports.foo = foo; +exports.foo = foo = 2; +exports.foo = foo += 2; +exports.foo = foo -= 2; +exports.foo = foo *= 2; +exports.foo = foo /= 2; +exports.foo = foo %= 2; +exports.foo = foo <<= 2; +exports.foo = foo >>= 2; +exports.foo = foo >>>= 2; +exports.foo = foo |= 2; +exports.foo = foo ^= 2; +exports.foo = foo &= 2; +exports.foo = foo **= 2; +exports.foo = foo &&= 2; +exports.foo = foo ||= 2; +exports.foo = foo ??= 2; +[foo] = [ + 2 +], exports.foo = foo; +[foo = 3] = [], exports.foo = foo; +({ bar: foo } = { + bar: 2 +}), exports.foo = foo;