fix(codegen): missing parens for in in for loop init when it includes two binary expression (#7703)

close: #7690

I don't know the logic much, it works without `left_ctx` and no tests failed
This commit is contained in:
Dunqing 2024-12-06 15:52:03 +00:00
parent f7d41dd6fb
commit 4afbe5599e
3 changed files with 17 additions and 10 deletions

View file

@ -100,7 +100,6 @@ pub struct BinaryExpressionVisitor<'a> {
pub ctx: Context,
pub left_precedence: Precedence,
pub left_ctx: Context,
pub operator: BinaryishOperator,
pub wrap: bool,
@ -124,7 +123,7 @@ impl<'a> BinaryExpressionVisitor<'a> {
};
let Some(left_binary) = left_binary else {
left.gen_expr(p, v.left_precedence, v.left_ctx);
left.gen_expr(p, v.left_precedence, v.ctx);
v.visit_right_and_finish(p);
break;
};
@ -133,9 +132,8 @@ impl<'a> BinaryExpressionVisitor<'a> {
v = BinaryExpressionVisitor {
e: left_binary,
precedence: v.left_precedence,
ctx: v.left_ctx,
ctx: v.ctx,
left_precedence: Precedence::Lowest,
left_ctx: Context::empty(),
operator: v.operator,
wrap: false,
right_precedence: Precedence::Lowest,
@ -168,6 +166,9 @@ impl<'a> BinaryExpressionVisitor<'a> {
if self.wrap {
p.print_ascii_byte(b'(');
// `for (1 * (x == a in b);;);`
// ^^^^^^^^^^^^ has been wrapped in parens, so it doesn't need to
// print parens for `a in b` again.
self.ctx &= Context::FORBID_IN.not();
}
@ -221,7 +222,7 @@ impl<'a> BinaryExpressionVisitor<'a> {
p.print_soft_space();
self.operator.gen(p);
p.print_soft_space();
self.e.right().gen_expr(p, self.right_precedence, self.ctx & Context::FORBID_IN);
self.e.right().gen_expr(p, self.right_precedence, self.ctx);
if self.wrap {
p.print_ascii_byte(b')');
}

View file

@ -1733,7 +1733,6 @@ impl GenExpr for BinaryExpression<'_> {
precedence,
ctx,
left_precedence: Precedence::Lowest,
left_ctx: Context::empty(),
operator: BinaryishOperator::Binary(self.operator),
wrap: false,
right_precedence: Precedence::Lowest,
@ -1763,7 +1762,6 @@ impl GenExpr for LogicalExpression<'_> {
precedence,
ctx,
left_precedence: Precedence::Lowest,
left_ctx: ctx,
operator: BinaryishOperator::Logical(self.operator),
wrap: false,
right_precedence: Precedence::Lowest,

View file

@ -55,10 +55,18 @@ fn for_stmt() {
test("for (;;i++) {}", "for (;; i++) {}\n");
test("for (using x = 1;;) {}", "for (using x = 1;;) {}\n");
// TODO
// `in` expression
test("for (x = (y in z) || y;;);", "for (x = (y in z) || y;;);\n");
test("for (x = (y in z) || y || y;;);", "for (x = (y in z) || y || y;;);\n");
test("for (x = y || y || (y in z);;);", "for (x = y || y || (y in z);;);\n");
test(
"for (x = (y in z) || y || (y in z) || y || (y in z);;);",
"for (x = (y in z) || y || (y in z) || y || (y in z);;);\n",
);
// test(
// "for (var a = 1 || (2 in {}) in { x: 1 }) count++;",
// "for (var a = 1 || (2 in {}) in {x: 1}) count++;\n",
// "for (var a = 1 || (2 in {}) in { x: 1 }) count++;",
// "for (var a = 1 || (2 in {}) in {x: 1}) count++;\n",
// );
}