fix(es/compat): Handle initializer hole in array patterns (#3442)

This commit is contained in:
magic-akari 2022-02-04 11:33:19 +08:00 committed by GitHub
parent e732ac9621
commit 3bb2a6ccca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 132 additions and 25 deletions

View File

@ -434,40 +434,36 @@ impl AssignFolder {
right: def_value,
..
}) => {
assert!(
decl.init.is_some(),
"destructuring pattern binding requires initializer"
);
let init = if let Some(init) = decl.init {
let tmp_ident = match &*init {
Expr::Ident(ref i) if i.span.ctxt() != SyntaxContext::empty() => i.clone(),
let init = decl.init;
let tmp_ident: Ident = (|| {
if let Some(ref e) = init {
match &**e {
Expr::Ident(ref i) if i.span.ctxt() != SyntaxContext::empty() => {
return i.clone();
}
_ => {}
_ => {
let tmp_ident = private_ident!(span, "tmp");
decls.push(VarDeclarator {
span: DUMMY_SP,
name: tmp_ident.clone().into(),
init: Some(init),
definite: false,
});
tmp_ident
}
}
};
let tmp_ident = private_ident!(span, "tmp");
decls.push(VarDeclarator {
span: DUMMY_SP,
name: tmp_ident.clone().into(),
init,
definite: false,
});
tmp_ident
})();
// tmp === void 0 ? def_value : tmp
Some(Box::new(make_cond_expr(tmp_ident, def_value)))
} else {
Some(def_value)
};
let var_decl = VarDeclarator {
span,
name: *left,
// tmp === void 0 ? def_value : tmp
init: Some(Box::new(make_cond_expr(tmp_ident, def_value))),
init,
definite: false,
};
let mut var_decls = vec![var_decl];
var_decls.visit_mut_with(self);
decls.extend(var_decls);

View File

@ -1992,3 +1992,114 @@ test!(
ref = [], ref1 = ref[0], bar = ref1 === void 0 ? baz : ref1, ref;
"
);
test!(
syntax(),
|_| tr(),
statements_let_dstr_ary_ptrn_elem_id_init_hole,
"\
let [x = 23] = [,];
assert.sameValue(x, 23);
",
"\
let x = 23;
assert.sameValue(x, 23);
"
);
test!(
syntax(),
|_| tr(),
statements_let_dstr_ary_ptrn_elem_id_init_hole_2,
"\
let y = [x = 23] = [,];
",
"\
var ref, ref1;
let y = (ref = [,], ref1 = ref[0], x = ref1 === void 0 ? 23 : ref1, ref);
"
);
test!(
syntax(),
|_| tr(),
statements_const_dstr_ary_ptrn_elem_id_init_hole,
"\
const [x = 23] = [,];
assert.sameValue(x, 23);
",
"\
const x = 23;
assert.sameValue(x, 23);
"
);
test!(
syntax(),
|_| tr(),
statements_const_dstr_ary_ptrn_elem_id_init_hole_2,
"const [x = 23, y = 42] = [,,];",
"const x = 23, y = 42;"
);
test!(
syntax(),
|_| tr(),
statements_const_dstr_ary_ptrn_elem_id_init_hole_3,
"const [x = 23, y] = [, 42];",
"const x = 23, y = 42;"
);
test!(
syntax(),
|_| tr(),
statements_const_dstr_ary_ptrn_elem_id_init_hole_4,
"\
function* foo() {
yield 1;
yield 2;
}
let bar = foo();
const [x = bar.next().value, y] = [, bar.next().value];
console.log(x, y);
",
"\
function* foo() {
yield 1;
yield 2;
}
let bar = foo();
const ref = [,bar.next().value], tmp = ref[0],
x = tmp === void 0 ? bar.next().value : tmp, y = ref[1];
console.log(x, y);"
);
test!(
syntax(),
|_| tr(),
for_const_dstr_ary_ptrn_elem_id_init_hole,
"\
var iterCount = 0;
for (const [x = 23] = [,]; iterCount < 1; ) {
assert.sameValue(x, 23);
// another statement
iterCount += 1;
}
assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
",
"\
var iterCount = 0;
for(const x = 23; iterCount < 1;){
assert.sameValue(x, 23);
iterCount += 1;
}
assert.sameValue(iterCount, 1, 'Iteration occurred as expected');
"
);