Files
oxc-project__oxc/packages/codegen/test/fixtures/private-in-binary-right.js
camc314 598618793c fix(packages/codegen): preserve private-in right operand precedence (#26420)
`packages/codegen` drops required parentheses around the right operand of a private-in expression when that operand is another relational expression. This changes which value the private-field check receives and can change observable behavior.

For example, this input throws a `TypeError`:

```js
class C {
  #x;
  test(a, b) {
    return #x in (a instanceof b);
  }
}
new C().test({}, Object);
```

`a instanceof b` evaluates to `true`, but a private-field check requires an object on its right-hand side.

The JavaScript printer previously emitted:

```js
return #x in a instanceof b;
```

Relational operators associate to the left, so that output is parsed as `(#x in a) instanceof b`. The private-field check on `{}` produces `false`, and `false instanceof Object` returns `false` instead of throwing.

The printer now preserves the original grouping:

```js
return #x in (a instanceof b);
```

`printPrivateInExpression` now prints its right operand with `PREC_COMPARE` instead of `PREC_EQUALS`. The expression printers wrap operands whose precedence is equal to or lower than the requested precedence, so the comparison threshold retains parentheses around `<`, `<=`, `>`, `>=`, `instanceof`, and nested private-in expressions. The now-unused `PREC_EQUALS` import is removed.

Equality and lower-precedence operands continue to retain their required grouping. Shift, arithmetic, and exponentiation operands can still omit unnecessary parentheses. The existing `CTX_FORBID_IN` handling remains in place.

This applies to both ordinary and source-map-enabled printer builds and brings the JavaScript implementation in line with the Rust fix in #26411. It addresses grouping of the private-in right operand, separately from the left-operand correction in #26403.
2026-09-07 17:54:59 +00:00

37 lines
697 B
JavaScript

class C {
#x;
test(a, b) {
return [
#x in (a instanceof b),
#x in (a in b),
#x in (a < b),
#x in (a <= b),
#x in (a > b),
#x in (a >= b),
#x in (a == b),
#x in (a != b),
#x in (a === b),
#x in (a !== b),
#x in (a & b),
#x in (a ^ b),
#x in (a | b),
#x in (a && b),
#x in (a || b),
#x in (a ?? b),
#x in (a = b),
#x in (a << b),
#x in (a >> b),
#x in (a >>> b),
#x in (a + b),
#x in (a - b),
#x in (a * b),
#x in (a / b),
#x in (a % b),
#x in (a ** b),
#x in (#x in a),
#x in (a ? a : b),
#x in (a, b),
];
}
}