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..1837608d0ed1 100644 --- a/crates/swc_ecma_transforms_base/src/fixer.rs +++ b/crates/swc_ecma_transforms_base/src/fixer.rs @@ -170,6 +170,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) {