From ee17b55cfc09f6fc6c49f8ec3f3b782f972ebd66 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Tue, 13 Dec 2022 20:43:35 +0800 Subject: [PATCH 1/3] fix(es/transform_base): should add correct parens for optioanl chaining expression --- .../fixture/issues-6xxx/6459/1/input/.swcrc | 10 +++++ .../fixture/issues-6xxx/6459/1/input/index.ts | 1 + .../issues-6xxx/6459/1/output/index.ts | 1 + .../fixture/issues-6xxx/6459/2/input/.swcrc | 10 +++++ .../fixture/issues-6xxx/6459/2/input/index.ts | 1 + .../issues-6xxx/6459/2/output/index.ts | 1 + .../fixture/issues-6xxx/6459/3/input/.swcrc | 10 +++++ .../fixture/issues-6xxx/6459/3/input/index.ts | 1 + .../issues-6xxx/6459/3/output/index.ts | 1 + crates/swc_ecma_transforms_base/src/fixer.rs | 39 ++++++++++++++++++- 10 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 crates/swc/tests/fixture/issues-6xxx/6459/1/input/.swcrc create mode 100644 crates/swc/tests/fixture/issues-6xxx/6459/1/input/index.ts create mode 100644 crates/swc/tests/fixture/issues-6xxx/6459/1/output/index.ts create mode 100644 crates/swc/tests/fixture/issues-6xxx/6459/2/input/.swcrc create mode 100644 crates/swc/tests/fixture/issues-6xxx/6459/2/input/index.ts create mode 100644 crates/swc/tests/fixture/issues-6xxx/6459/2/output/index.ts create mode 100644 crates/swc/tests/fixture/issues-6xxx/6459/3/input/.swcrc create mode 100644 crates/swc/tests/fixture/issues-6xxx/6459/3/input/index.ts create mode 100644 crates/swc/tests/fixture/issues-6xxx/6459/3/output/index.ts diff --git a/crates/swc/tests/fixture/issues-6xxx/6459/1/input/.swcrc b/crates/swc/tests/fixture/issues-6xxx/6459/1/input/.swcrc new file mode 100644 index 000000000000..596439d43450 --- /dev/null +++ b/crates/swc/tests/fixture/issues-6xxx/6459/1/input/.swcrc @@ -0,0 +1,10 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript" + }, + "target": "es2020", + "loose": false + }, + "isModule": true +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-6xxx/6459/1/input/index.ts b/crates/swc/tests/fixture/issues-6xxx/6459/1/input/index.ts new file mode 100644 index 000000000000..7f2a677887ca --- /dev/null +++ b/crates/swc/tests/fixture/issues-6xxx/6459/1/input/index.ts @@ -0,0 +1 @@ +(myValue.children?.children[0] as ChildType).value = 'My Value'; diff --git a/crates/swc/tests/fixture/issues-6xxx/6459/1/output/index.ts b/crates/swc/tests/fixture/issues-6xxx/6459/1/output/index.ts new file mode 100644 index 000000000000..ec4e5fe19132 --- /dev/null +++ b/crates/swc/tests/fixture/issues-6xxx/6459/1/output/index.ts @@ -0,0 +1 @@ +(myValue.children?.children)[0].value = 'My Value'; diff --git a/crates/swc/tests/fixture/issues-6xxx/6459/2/input/.swcrc b/crates/swc/tests/fixture/issues-6xxx/6459/2/input/.swcrc new file mode 100644 index 000000000000..596439d43450 --- /dev/null +++ b/crates/swc/tests/fixture/issues-6xxx/6459/2/input/.swcrc @@ -0,0 +1,10 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript" + }, + "target": "es2020", + "loose": false + }, + "isModule": true +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-6xxx/6459/2/input/index.ts b/crates/swc/tests/fixture/issues-6xxx/6459/2/input/index.ts new file mode 100644 index 000000000000..284eab42846a --- /dev/null +++ b/crates/swc/tests/fixture/issues-6xxx/6459/2/input/index.ts @@ -0,0 +1 @@ +(foo?.bar.baz?.bax).faz = 1 \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-6xxx/6459/2/output/index.ts b/crates/swc/tests/fixture/issues-6xxx/6459/2/output/index.ts new file mode 100644 index 000000000000..245477e7e86e --- /dev/null +++ b/crates/swc/tests/fixture/issues-6xxx/6459/2/output/index.ts @@ -0,0 +1 @@ +(foo?.bar.baz?.bax).faz = 1; diff --git a/crates/swc/tests/fixture/issues-6xxx/6459/3/input/.swcrc b/crates/swc/tests/fixture/issues-6xxx/6459/3/input/.swcrc new file mode 100644 index 000000000000..596439d43450 --- /dev/null +++ b/crates/swc/tests/fixture/issues-6xxx/6459/3/input/.swcrc @@ -0,0 +1,10 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript" + }, + "target": "es2020", + "loose": false + }, + "isModule": true +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-6xxx/6459/3/input/index.ts b/crates/swc/tests/fixture/issues-6xxx/6459/3/input/index.ts new file mode 100644 index 000000000000..3e8a5b57548c --- /dev/null +++ b/crates/swc/tests/fixture/issues-6xxx/6459/3/input/index.ts @@ -0,0 +1 @@ +(foo?.bar.bar.bar?.baz.baz.baz).foo.baz = 1 \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-6xxx/6459/3/output/index.ts b/crates/swc/tests/fixture/issues-6xxx/6459/3/output/index.ts new file mode 100644 index 000000000000..b464686388f2 --- /dev/null +++ b/crates/swc/tests/fixture/issues-6xxx/6459/3/output/index.ts @@ -0,0 +1 @@ +(foo?.bar.bar.bar?.baz).baz.baz.foo.baz = 1; diff --git a/crates/swc_ecma_transforms_base/src/fixer.rs b/crates/swc_ecma_transforms_base/src/fixer.rs index f06daf330301..98781f67ac66 100644 --- a/crates/swc_ecma_transforms_base/src/fixer.rs +++ b/crates/swc_ecma_transforms_base/src/fixer.rs @@ -16,6 +16,7 @@ pub fn fixer(comments: Option<&dyn Comments>) -> impl '_ + Fold + VisitMut { ctx: Default::default(), span_map: Default::default(), in_for_stmt_head: Default::default(), + in_assign_lhs: Default::default(), remove_only: false, }) } @@ -26,6 +27,7 @@ pub fn paren_remover(comments: Option<&dyn Comments>) -> impl '_ + Fold + VisitM ctx: Default::default(), span_map: Default::default(), in_for_stmt_head: Default::default(), + in_assign_lhs: Default::default(), remove_only: true, }) } @@ -40,6 +42,7 @@ struct Fixer<'a> { span_map: FxHashMap, in_for_stmt_head: bool, + in_assign_lhs: bool, remove_only: bool, } @@ -152,12 +155,18 @@ impl VisitMut for Fixer<'_> { } fn visit_mut_assign_expr(&mut self, expr: &mut AssignExpr) { + let old = self.in_assign_lhs; + + self.in_assign_lhs = true; expr.left.visit_mut_with(self); let ctx = self.ctx; self.ctx = Context::FreeExpr; + self.in_assign_lhs = false; expr.right.visit_mut_with(self); + self.ctx = ctx; + self.in_assign_lhs = old; fn rhs_need_paren(e: &Expr) -> bool { match e { @@ -170,6 +179,34 @@ impl VisitMut for Fixer<'_> { if rhs_need_paren(&expr.right) { self.wrap(&mut expr.right); } + + fn find_nearest_opt_chain_as_obj(e: &mut Expr) -> Option<&mut Expr> { + match e { + Expr::Member(MemberExpr { obj, .. }) => { + if obj.is_opt_chain() { + Some(obj) + } else { + find_nearest_opt_chain_as_obj(obj) + } + } + _ => None, + } + } + + let lhs_expr = match &mut expr.left { + PatOrExpr::Expr(e) => Some(e), + PatOrExpr::Pat(pat) => { + if let Pat::Expr(e) = pat.as_mut() { + Some(e) + } else { + None + } + } + }; + + if let Some(e) = lhs_expr.and_then(|e| find_nearest_opt_chain_as_obj(e)) { + self.wrap(e) + }; } fn visit_mut_assign_pat(&mut self, node: &mut AssignPat) { @@ -440,7 +477,7 @@ impl VisitMut for Fixer<'_> { e.visit_mut_children_with(self); self.ctx = ctx; - self.wrap_with_paren_if_required(e) + self.wrap_with_paren_if_required(e); } fn visit_mut_expr_or_spread(&mut self, e: &mut ExprOrSpread) { From 5877ca8a7c116bcc65c3c25574780e52069fd4cc Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Tue, 13 Dec 2022 21:18:25 +0800 Subject: [PATCH 2/3] Undo useless changes --- crates/swc_ecma_transforms_base/src/fixer.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/crates/swc_ecma_transforms_base/src/fixer.rs b/crates/swc_ecma_transforms_base/src/fixer.rs index 98781f67ac66..95d49f4fc832 100644 --- a/crates/swc_ecma_transforms_base/src/fixer.rs +++ b/crates/swc_ecma_transforms_base/src/fixer.rs @@ -16,7 +16,6 @@ pub fn fixer(comments: Option<&dyn Comments>) -> impl '_ + Fold + VisitMut { ctx: Default::default(), span_map: Default::default(), in_for_stmt_head: Default::default(), - in_assign_lhs: Default::default(), remove_only: false, }) } @@ -27,7 +26,6 @@ pub fn paren_remover(comments: Option<&dyn Comments>) -> impl '_ + Fold + VisitM ctx: Default::default(), span_map: Default::default(), in_for_stmt_head: Default::default(), - in_assign_lhs: Default::default(), remove_only: true, }) } @@ -42,7 +40,6 @@ struct Fixer<'a> { span_map: FxHashMap, in_for_stmt_head: bool, - in_assign_lhs: bool, remove_only: bool, } @@ -155,18 +152,13 @@ impl VisitMut for Fixer<'_> { } fn visit_mut_assign_expr(&mut self, expr: &mut AssignExpr) { - let old = self.in_assign_lhs; - - self.in_assign_lhs = true; expr.left.visit_mut_with(self); let ctx = self.ctx; self.ctx = Context::FreeExpr; - self.in_assign_lhs = false; expr.right.visit_mut_with(self); self.ctx = ctx; - self.in_assign_lhs = old; fn rhs_need_paren(e: &Expr) -> bool { match e { From 32e6be27955e1f39cb004f5094b72fc64d04a4a4 Mon Sep 17 00:00:00 2001 From: YunfeiHe Date: Tue, 13 Dec 2022 21:19:50 +0800 Subject: [PATCH 3/3] Undo useless changes --- crates/swc_ecma_transforms_base/src/fixer.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/swc_ecma_transforms_base/src/fixer.rs b/crates/swc_ecma_transforms_base/src/fixer.rs index 95d49f4fc832..1837608d0ed1 100644 --- a/crates/swc_ecma_transforms_base/src/fixer.rs +++ b/crates/swc_ecma_transforms_base/src/fixer.rs @@ -157,7 +157,6 @@ impl VisitMut for Fixer<'_> { let ctx = self.ctx; self.ctx = Context::FreeExpr; expr.right.visit_mut_with(self); - self.ctx = ctx; fn rhs_need_paren(e: &Expr) -> bool { @@ -469,7 +468,7 @@ impl VisitMut for Fixer<'_> { e.visit_mut_children_with(self); self.ctx = ctx; - self.wrap_with_paren_if_required(e); + self.wrap_with_paren_if_required(e) } fn visit_mut_expr_or_spread(&mut self, e: &mut ExprOrSpread) {