diff --git a/crates/oxc_parser/src/diagnostics.rs b/crates/oxc_parser/src/diagnostics.rs index ec17389f55867..de0b8deed5190 100644 --- a/crates/oxc_parser/src/diagnostics.rs +++ b/crates/oxc_parser/src/diagnostics.rs @@ -471,6 +471,11 @@ pub fn new_target(span: Span) -> OxcDiagnostic { OxcDiagnostic::error("The only valid meta property for new is new.target").with_label(span) } +#[cold] +pub fn private_in_private(span: Span) -> OxcDiagnostic { + OxcDiagnostic::error("Unexpected right-hand side of private-in expression").with_label(span) +} + // ================================= MODIFIERS ================================= #[cold] diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 1b7af6cbba716..c0f1a8b274581 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -983,7 +983,10 @@ impl<'a> ParserImpl<'a> { let lhs = if self.ctx.has_in() && self.at(Kind::PrivateIdentifier) { let left = self.parse_private_identifier(); self.expect(Kind::In)?; - let right = self.parse_unary_expression_or_higher(lhs_span)?; + let right = self.parse_binary_expression_or_higher(Precedence::Lowest)?; + if let Expression::PrivateInExpression(private_in_expr) = right { + return Err(diagnostics::private_in_private(private_in_expr.span)); + } self.ast.expression_private_in(self.end_span(lhs_span), left, BinaryOperator::In, right) } else { self.parse_unary_expression_or_higher(lhs_span)? diff --git a/tasks/coverage/snapshots/estree_test262.snap b/tasks/coverage/snapshots/estree_test262.snap index 609e80e1ceaad..19cbd1cae034c 100644 --- a/tasks/coverage/snapshots/estree_test262.snap +++ b/tasks/coverage/snapshots/estree_test262.snap @@ -2,7 +2,7 @@ commit: bc5c1417 estree_test262 Summary: AST Parsed : 44293/44293 (100.00%) -Positive Passed: 44162/44293 (99.70%) +Positive Passed: 44163/44293 (99.71%) tasks/coverage/test262/test/annexB/built-ins/RegExp/prototype/compile/pattern-string-u.js serde_json error: unexpected end of hex escape at line 316 column 33 @@ -187,7 +187,6 @@ serde_json error: unexpected end of hex escape at line 184 column 33 Mismatch: tasks/coverage/test262/test/language/expressions/assignment/fn-name-lhs-cover.js Mismatch: tasks/coverage/test262/test/language/expressions/assignment/target-cover-id.js Mismatch: tasks/coverage/test262/test/language/expressions/dynamic-import/import-attributes/2nd-param-await-ident.js -Mismatch: tasks/coverage/test262/test/language/expressions/in/private-field-rhs-non-object.js Mismatch: tasks/coverage/test262/test/language/expressions/postfix-decrement/target-cover-id.js Mismatch: tasks/coverage/test262/test/language/expressions/postfix-increment/target-cover-id.js Mismatch: tasks/coverage/test262/test/language/expressions/prefix-decrement/target-cover-id.js diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index 6c223808e6293..d0d0487596016 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -8407,11 +8407,11 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc ╰──── help: Did you mean `export { "吾道一以貫之。" as "忠恕。" } from 'some-module'`? - × Unexpected token + × Unexpected right-hand side of private-in expression ╭─[babel/packages/babel-parser/test/fixtures/es2022/private-in/invalid-private-followed-by-in-1/input.js:5:11] 4 │ method() { 5 │ #a in #b in c - · ── + · ─────── 6 │ } ╰──── diff --git a/tasks/coverage/snapshots/parser_test262.snap b/tasks/coverage/snapshots/parser_test262.snap index f6ec60ccba067..086eea7afa4b7 100644 --- a/tasks/coverage/snapshots/parser_test262.snap +++ b/tasks/coverage/snapshots/parser_test262.snap @@ -17731,11 +17731,11 @@ Negative Passed: 4519/4519 (100.00%) · ─────────── ╰──── - × Unexpected token + × Unexpected right-hand side of private-in expression ╭─[test262/test/language/expressions/in/private-field-in-nested.js:26:15] 25 │ constructor() { 26 │ #field in #field in this; - · ────── + · ────────────── 27 │ } ╰──── diff --git a/tasks/prettier_conformance/snapshots/prettier.ts.snap.md b/tasks/prettier_conformance/snapshots/prettier.ts.snap.md index d7cb73d2c0096..7a07b91496381 100644 --- a/tasks/prettier_conformance/snapshots/prettier.ts.snap.md +++ b/tasks/prettier_conformance/snapshots/prettier.ts.snap.md @@ -301,7 +301,7 @@ ts compatibility: 199/568 (35.04%) | typescript/prettier-ignore/mapped-types.ts | 💥 | 26.83% | | typescript/prettier-ignore/prettier-ignore-nested-unions.ts | 💥 | 7.69% | | typescript/prettier-ignore/prettier-ignore-parenthesized-type.ts | 💥 | 0.00% | -| typescript/private-fields-in-in/basic.ts | 💥 | 68.75% | +| typescript/private-fields-in-in/basic.ts | 💥 | 70.97% | | typescript/rest-type/complex.ts | 💥 | 0.00% | | typescript/rest-type/infer-type.ts | 💥 | 58.33% | | typescript/satisfies-operators/argument-expansion.ts | 💥💥 | 80.00% | diff --git a/tasks/transform_conformance/snapshots/babel_exec.snap.md b/tasks/transform_conformance/snapshots/babel_exec.snap.md index c7c4aea16bee5..a7294bc59d21e 100644 --- a/tasks/transform_conformance/snapshots/babel_exec.snap.md +++ b/tasks/transform_conformance/snapshots/babel_exec.snap.md @@ -436,20 +436,29 @@ AssertionError: expected [Function] to throw error including 'right-hand side of at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-loose-rhs-not-object-exec.test.js:176:5 ./fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-loose-static-shadow-exec.test.js -AssertionError: expected 2 to be 5 // Object.is equality - at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-loose-static-shadow-exec.test.js:18:25 +TypeError: right-hand side of 'in' should be an object, got number + at _checkInRHS (./node_modules/.pnpm/@babel+runtime@7.26.7/node_modules/@babel/runtime/helpers/checkInRHS.js:3:30) + at func (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-loose-static-shadow-exec.test.js:10:12) + at Test.method (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-loose-static-shadow-exec.test.js:12:11) + at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-loose-static-shadow-exec.test.js:18:11 ./fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-static-shadow-exec.test.js -AssertionError: expected 2 to be 5 // Object.is equality - at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-static-shadow-exec.test.js:18:25 +TypeError: right-hand side of 'in' should be an object, got number + at _checkInRHS (./node_modules/.pnpm/@babel+runtime@7.26.7/node_modules/@babel/runtime/helpers/checkInRHS.js:3:30) + at func (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-static-shadow-exec.test.js:10:12) + at Test.method (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-static-shadow-exec.test.js:12:11) + at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-private-static-shadow-exec.test.js:18:11 ./fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-to-native-fields-half-constructed-static-exec.test.js AssertionError: expected true to be false // Object.is equality at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-to-native-fields-half-constructed-static-exec.test.js:29:15 ./fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-to-native-fields-static-shadow-exec.test.js -AssertionError: expected 2 to be 5 // Object.is equality - at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-to-native-fields-static-shadow-exec.test.js:18:25 +TypeError: right-hand side of 'in' should be an object, got number + at _checkInRHS (./node_modules/.pnpm/@babel+runtime@7.26.7/node_modules/@babel/runtime/helpers/checkInRHS.js:3:30) + at func (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-to-native-fields-static-shadow-exec.test.js:10:12) + at Test.method (./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-to-native-fields-static-shadow-exec.test.js:12:11) + at ./tasks/transform_conformance/fixtures/babel/babel-plugin-transform-private-property-in-object-test-fixtures-to-native-fields-static-shadow-exec.test.js:18:11 ./fixtures/babel/babel-plugin-transform-react-jsx-source-test-fixtures-react-source-basic-sample-exec.test.js ReferenceError: transformAsync is not defined