From 97068e12d16803012a4859114702577def024a36 Mon Sep 17 00:00:00 2001 From: Austaras Date: Sun, 10 Sep 2023 14:27:30 +0800 Subject: [PATCH] fix(es/compat): Visit assign expr in generator (#7932) **Related issue:** - Closes #7809 --- .../src/es2015/generator.rs | 120 +++++++++--------- .../tests/es2015_generator.rs | 44 +++++++ 2 files changed, 103 insertions(+), 61 deletions(-) diff --git a/crates/swc_ecma_transforms_compat/src/es2015/generator.rs b/crates/swc_ecma_transforms_compat/src/es2015/generator.rs index a6da0916a0ed..a409203a50e2 100644 --- a/crates/swc_ecma_transforms_compat/src/es2015/generator.rs +++ b/crates/swc_ecma_transforms_compat/src/es2015/generator.rs @@ -572,72 +572,70 @@ impl VisitMut for Generator { e.visit_mut_children_with(self); } - Expr::Assign(node) => { - if contains_yield(&node.right) { - match node.left.as_expr_mut() { - Some(Expr::Member(left)) => { - match &mut left.prop { - MemberProp::Ident(..) | MemberProp::PrivateName(..) => { - // a.b = yield; - // - // [intermediate] - // .local _a - // _a = a; - // .yield resumeLabel - // .mark resumeLabel - // _a.b = %sent%; - - left.obj.visit_mut_with(self); - let obj = self.cache_expression(left.obj.take()); - - left.obj = Box::new(Expr::Ident(obj)); - } - MemberProp::Computed(prop) => { - // [source] - // a[b] = yield; - // - // [intermediate] - // .local _a, _b - // _a = a; - // _b = b; - // .yield resumeLabel - // .mark resumeLabel - // _a[_b] = %sent%; - let prop_span = prop.span; - - left.obj.visit_mut_with(self); - let obj = self.cache_expression(left.obj.take()); - - prop.visit_mut_with(self); - let prop = self.cache_expression(prop.expr.take()); - - left.obj = Box::new(Expr::Ident(obj)); - left.prop = MemberProp::Computed(ComputedPropName { - span: prop_span, - expr: Box::new(Expr::Ident(prop)), - }); - } + Expr::Assign(node) if contains_yield(&node.right) => { + match node.left.as_expr_mut() { + Some(Expr::Member(left)) => { + match &mut left.prop { + MemberProp::Ident(..) | MemberProp::PrivateName(..) => { + // a.b = yield; + // + // [intermediate] + // .local _a + // _a = a; + // .yield resumeLabel + // .mark resumeLabel + // _a.b = %sent%; + + left.obj.visit_mut_with(self); + let obj = self.cache_expression(left.obj.take()); + + left.obj = Box::new(Expr::Ident(obj)); + } + MemberProp::Computed(prop) => { + // [source] + // a[b] = yield; + // + // [intermediate] + // .local _a, _b + // _a = a; + // _b = b; + // .yield resumeLabel + // .mark resumeLabel + // _a[_b] = %sent%; + let prop_span = prop.span; + + left.obj.visit_mut_with(self); + let obj = self.cache_expression(left.obj.take()); + + prop.visit_mut_with(self); + let prop = self.cache_expression(prop.expr.take()); + + left.obj = Box::new(Expr::Ident(obj)); + left.prop = MemberProp::Computed(ComputedPropName { + span: prop_span, + expr: Box::new(Expr::Ident(prop)), + }); } - // [source] - } - _ => { - node.left.visit_mut_with(self); } + // [source] + } + _ => { + node.left.visit_mut_with(self); } - if node.op != op!("=") { - let left_of_right = self.cache_expression(node.left.take().expect_expr()); + } + if node.op != op!("=") { + let left_of_right = self.cache_expression(node.left.take().expect_expr()); - node.right.visit_mut_with(self); + node.right.visit_mut_with(self); - *e = Expr::Assign(AssignExpr { - span: node.right.span(), - op: node.op, - left: left_of_right.into(), - right: node.right.take(), - }); - } else { - node.right.visit_mut_with(self); - } + *e = Expr::Assign(AssignExpr { + span: node.right.span(), + op: node.op, + left: left_of_right.into(), + right: node.right.take(), + }); + } else { + node.right.visit_mut_with(self); } } diff --git a/crates/swc_ecma_transforms_compat/tests/es2015_generator.rs b/crates/swc_ecma_transforms_compat/tests/es2015_generator.rs index 1b7a8f54990b..4a29cfb36dff 100644 --- a/crates/swc_ecma_transforms_compat/tests/es2015_generator.rs +++ b/crates/swc_ecma_transforms_compat/tests/es2015_generator.rs @@ -1937,3 +1937,47 @@ test_exec!( await res; " ); + +test!( + Syntax::default(), + |_| { + let mark = Mark::fresh(Mark::root()); + es2015::(mark, None, Default::default()) + }, + issue_7809, + r#" + function a(fn) { + return _a.apply(this, arguments); + } + function _a() { + _a = _async_to_generator(function*(fn) { + (yield fn()).a = 1; + }); + return _a.apply(this, arguments); + } + "#, + r#" + function a(fn) { + return _a.apply(this, arguments); + } + function _a() { + _a = _async_to_generator(function(fn) { + return _ts_generator(this, function(_state) { + switch(_state.label){ + case 0: + return [ + 4, + fn() + ]; + case 1: + _state.sent().a = 1; + return [ + 2 + ]; + } + }); + }); + return _a.apply(this, arguments); + } + "# +);