Skip to content

Commit 847ad22

Browse files
authored
fix(es/compat): Preserve return value for single-property object destructuring (#11334)
**Related issue:** - Closes #11051
1 parent f6ce514 commit 847ad22

File tree

5 files changed

+82
-1
lines changed

5 files changed

+82
-1
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
swc_core: patch
3+
swc_ecma_compat_es2015: patch
4+
---
5+
6+
fix(es/compat): Preserve return value for single-property object destructuring
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"jsc": {
3+
"target": "es5"
4+
}
5+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
let myObject = { value: 5, isEven: true };
2+
3+
function checkIfEven() {
4+
if (({ isEven } = myObject).isEven) {
5+
return "Number is even";
6+
}
7+
else {
8+
return "Number is odd";
9+
}
10+
}
11+
12+
function func1() {
13+
return checkIfEven();
14+
}
15+
16+
function main() {
17+
let res = func1();
18+
console.log(res);
19+
}
20+
21+
main();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
var myObject = {
2+
value: 5,
3+
isEven: true
4+
};
5+
function checkIfEven() {
6+
var ref;
7+
if ((ref = myObject, isEven = ref.isEven, ref).isEven) {
8+
return "Number is even";
9+
} else {
10+
return "Number is odd";
11+
}
12+
}
13+
function func1() {
14+
return checkIfEven();
15+
}
16+
function main() {
17+
var res = func1();
18+
console.log(res);
19+
}
20+
main();

crates/swc_ecma_compat_es2015/src/destructuring.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,10 @@ impl AssignFolder {
592592
}
593593
.into();
594594

595+
// The return value of intermediate expressions is not used
596+
let ignore_return_value = self.ignore_return_value.replace(());
595597
assign_cond_expr.visit_mut_with(self);
598+
self.ignore_return_value = ignore_return_value;
596599
exprs.push(Box::new(assign_cond_expr));
597600

598601
SeqExpr {
@@ -639,7 +642,30 @@ impl VisitMut for AssignFolder {
639642
self.exporting = exporting;
640643
}
641644

645+
fn visit_mut_seq_expr(&mut self, seq: &mut SeqExpr) {
646+
// In a sequence expression like (a, b, c), only the last expression's
647+
// return value matters. All previous expressions should ignore their
648+
// return value.
649+
let ignore_return_value = self.ignore_return_value.take();
650+
651+
if let Some((last, rest)) = seq.exprs.split_last_mut() {
652+
for expr in rest {
653+
self.ignore_return_value = Some(());
654+
expr.visit_mut_with(self);
655+
}
656+
self.ignore_return_value = ignore_return_value;
657+
last.visit_mut_with(self);
658+
}
659+
}
660+
642661
fn visit_mut_expr(&mut self, expr: &mut Expr) {
662+
// For transparent wrapper expressions, pass through ignore_return_value
663+
// to the inner expression without consuming it.
664+
if let Expr::Paren(..) = expr {
665+
expr.visit_mut_children_with(self);
666+
return;
667+
}
668+
643669
let ignore_return_value = self.ignore_return_value.take().is_some();
644670

645671
match expr {
@@ -903,7 +929,7 @@ impl VisitMut for AssignFolder {
903929
.as_call(DUMMY_SP, vec![right.as_arg()]);
904930
}
905931
AssignTargetPat::Object(ObjectPat { span, props, .. }) => {
906-
if props.len() == 1 {
932+
if ignore_return_value && props.len() == 1 {
907933
if let ObjectPatProp::Assign(p @ AssignPatProp { value: None, .. }) =
908934
&props[0]
909935
{
@@ -952,7 +978,10 @@ impl VisitMut for AssignFolder {
952978
.into()
953979
};
954980

981+
// The return value of intermediate expressions is not used
982+
let ignore_return_value = self.ignore_return_value.replace(());
955983
expr.visit_mut_with(self);
984+
self.ignore_return_value = ignore_return_value;
956985
exprs.push(Box::new(expr));
957986
}
958987
ObjectPatProp::Assign(AssignPatProp { key, value, .. }) => {

0 commit comments

Comments
 (0)