Skip to content

fix(parser): correct precedence handling for private-in expression#18169

Merged
graphite-app[bot] merged 1 commit intomainfrom
fix/parser-private-in-precedence
Jan 18, 2026
Merged

fix(parser): correct precedence handling for private-in expression#18169
graphite-app[bot] merged 1 commit intomainfrom
fix/parser-private-in-precedence

Conversation

@Boshen
Copy link
Member

@Boshen Boshen commented Jan 18, 2026

Summary

  • Fix incorrect parsing of 1 + #a in b which was parsed as 1 + (#a in b) instead of (1 + #a) in b
  • Add precedence check before parsing #a in as PrivateInExpression
  • Report "Unexpected private identifier" error when precedence doesn't allow in operator

Details

The parser was greedily parsing #a in as a PrivateInExpression without checking operator precedence. For example, when parsing the RHS of + in 1 + #a in b, the in operator's precedence (Compare = 13) is lower than +'s precedence (Add = 15), so #a in should not be parsed as a unit.

The fix extracts private-in parsing into parse_private_in_expression and adds a check: if lhs_precedence >= Precedence::Compare, we reject the private identifier with a syntax error, matching V8 and Babel behavior.

Test plan

  • cargo test -p oxc_parser passes
  • Conformance improved: Negative Passed 1648 → 1649 for Babel tests
  • invalid-private-followed-by-in-2 test case now correctly reports syntax error

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings January 18, 2026 07:02
@github-actions github-actions bot added A-parser Area - Parser C-bug Category - Bug labels Jan 18, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes incorrect parsing of private-in expressions by adding proper precedence checking. Previously, 1 + #a in b was incorrectly parsed as 1 + (#a in b) instead of the correct (1 + #a) in b.

Changes:

  • Extracts private-in parsing logic into a new parse_private_in_expression function with precedence validation
  • Adds precedence check to reject private identifiers when the in operator's precedence is too low for the current context
  • Introduces new unexpected_private_identifier diagnostic for more precise error reporting

Reviewed changes

Copilot reviewed 2 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
crates/oxc_parser/src/js/expression.rs Adds parse_private_in_expression function with precedence check and refactors existing inline logic to use it
crates/oxc_parser/src/diagnostics.rs Adds new unexpected_private_identifier error diagnostic
tasks/coverage/snapshots/parser_babel.snap Shows improved test conformance (1648→1649 negative tests passed) and more precise error messages
tasks/coverage/snapshots/parser_test262.snap Updates error messages to be more precise, pointing to specific private identifier issues
tasks/coverage/snapshots/parser_typescript.snap Correctly identifies precedence-related syntax errors in TypeScript test cases

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 18, 2026

Merging this PR will not alter performance

✅ 42 untouched benchmarks
⏩ 3 skipped benchmarks1


Comparing fix/parser-private-in-precedence (527fc94) with main (38e4b53)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@Boshen Boshen force-pushed the fix/parser-private-in-precedence branch from 52059a9 to 527fc94 Compare January 18, 2026 07:15
@Boshen Boshen added the 0-merge Merge with Graphite Merge Queue label Jan 18, 2026
Copy link
Member Author

Boshen commented Jan 18, 2026

Merge activity

…18169)

## Summary

- Fix incorrect parsing of `1 + #a in b` which was parsed as `1 + (#a in b)` instead of `(1 + #a) in b`
- Add precedence check before parsing `#a in` as `PrivateInExpression`
- Report "Unexpected private identifier" error when precedence doesn't allow `in` operator

## Details

The parser was greedily parsing `#a in` as a `PrivateInExpression` without checking operator precedence. For example, when parsing the RHS of `+` in `1 + #a in b`, the `in` operator's precedence (`Compare = 13`) is lower than `+`'s precedence (`Add = 15`), so `#a in` should not be parsed as a unit.

The fix extracts private-in parsing into `parse_private_in_expression` and adds a check: if `lhs_precedence >= Precedence::Compare`, we reject the private identifier with a syntax error, matching V8 and Babel behavior.

## Test plan

- `cargo test -p oxc_parser` passes
- Conformance improved: Negative Passed 1648 → 1649 for Babel tests
- `invalid-private-followed-by-in-2` test case now correctly reports syntax error

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@graphite-app graphite-app bot force-pushed the fix/parser-private-in-precedence branch from 527fc94 to 2c6966d Compare January 18, 2026 07:51
@graphite-app graphite-app bot merged commit 2c6966d into main Jan 18, 2026
22 checks passed
@graphite-app graphite-app bot deleted the fix/parser-private-in-precedence branch January 18, 2026 07:57
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Jan 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-parser Area - Parser C-bug Category - Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants