Skip to content

Commit

Permalink
fix(es/transform_base): should add correct parens for optioanl chaini…
Browse files Browse the repository at this point in the history
…ng expression
  • Loading branch information
hyf0 committed Dec 13, 2022
1 parent 4f39d82 commit 2389bd0
Show file tree
Hide file tree
Showing 10 changed files with 74 additions and 1 deletion.
10 changes: 10 additions & 0 deletions crates/swc/tests/fixture/issues-6xxx/6459/1/input/.swcrc
@@ -0,0 +1,10 @@
{
"jsc": {
"parser": {
"syntax": "typescript"
},
"target": "es2020",
"loose": false
},
"isModule": true
}
1 change: 1 addition & 0 deletions crates/swc/tests/fixture/issues-6xxx/6459/1/input/index.ts
@@ -0,0 +1 @@
(myValue.children?.children[0] as ChildType).value = 'My Value';
@@ -0,0 +1 @@
(myValue.children?.children)[0].value = 'My Value';
10 changes: 10 additions & 0 deletions crates/swc/tests/fixture/issues-6xxx/6459/2/input/.swcrc
@@ -0,0 +1,10 @@
{
"jsc": {
"parser": {
"syntax": "typescript"
},
"target": "es2020",
"loose": false
},
"isModule": true
}
1 change: 1 addition & 0 deletions crates/swc/tests/fixture/issues-6xxx/6459/2/input/index.ts
@@ -0,0 +1 @@
(foo?.bar.baz?.bax).faz = 1
@@ -0,0 +1 @@
(foo?.bar.baz?.bax).faz = 1;
10 changes: 10 additions & 0 deletions crates/swc/tests/fixture/issues-6xxx/6459/3/input/.swcrc
@@ -0,0 +1,10 @@
{
"jsc": {
"parser": {
"syntax": "typescript"
},
"target": "es2020",
"loose": false
},
"isModule": true
}
1 change: 1 addition & 0 deletions crates/swc/tests/fixture/issues-6xxx/6459/3/input/index.ts
@@ -0,0 +1 @@
(foo?.bar.bar.bar?.baz.baz.baz).foo.baz = 1
@@ -0,0 +1 @@
(foo?.bar.bar.bar?.baz).baz.baz.foo.baz = 1;
39 changes: 38 additions & 1 deletion crates/swc_ecma_transforms_base/src/fixer.rs
Expand Up @@ -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,
})
}
Expand All @@ -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,
})
}
Expand All @@ -40,6 +42,7 @@ struct Fixer<'a> {
span_map: FxHashMap<Span, Span>,

in_for_stmt_head: bool,
in_assign_lhs: bool,

remove_only: bool,
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 2389bd0

Please sign in to comment.