-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
feat(es/parser): Add error recovery for recoverable syntax errors #11479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This change makes the ES parser less strict by recovering from recoverable errors instead of failing immediately. The parser now: - Adds `expect_or_recover!` macro that emits errors but continues parsing - Recovers from missing closing brackets/parens in arrays, objects, and function calls - Recovers from missing commas in array and object literals - Recovers from missing parens in if, while, do-while, for, and switch statements - Recovers from missing colons in switch cases The parser emits errors for these cases but continues to produce a valid AST, making it more suitable for IDE tooling where partial or incomplete code needs to be analyzed. Closes #11468 Co-authored-by: Donny/강동윤 <[email protected]>
|
|
1 similar comment
|
|
|
Binary Sizes
Commit: e5f6440 |
|
@claude fix CI |
This comment has been minimized.
This comment has been minimized.
Update test fixtures to include additional errors produced by the error recovery feature. The parser now continues after recovering from missing parentheses, which can result in additional error messages being reported. Co-authored-by: Donny/강동윤 <[email protected]>
|
@claude Fix CI |
This comment has been minimized.
This comment has been minimized.
…hanges The error recovery feature produces additional error messages when parsing continues after recovering from syntax errors. This commit updates the test reference files to reflect the new error output. Co-authored-by: Donny/강동윤 <[email protected]>
PR Review: Error Recovery for ES ParserSummaryThis PR implements error recovery for common syntax errors in the ES parser, making it less strict and allowing parsing to continue even when encountering recoverable errors. This addresses issue #11468. Code Quality & Best Practices ✅Good practices observed:
Potential Issues
|
There was a problem hiding this 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 implements error recovery in the swc ECMAScript parser to make it less strict by allowing it to continue parsing after encountering certain syntax errors, rather than immediately failing.
Changes:
- Adds a new
expect_or_recover!macro that emits errors but continues parsing instead of aborting - Updates control flow statements (if, while, for, do-while, switch) to use error recovery for missing parentheses and braces
- Updates expression parsing (arrays, function calls) to recover from missing commas and closing delimiters
- Updates object literal parsing to recover from missing commas and closing braces
Reviewed changes
Copilot reviewed 47 out of 47 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/swc_ecma_parser/src/parser/macros.rs | Adds expect_or_recover! macro for non-fatal error handling |
| crates/swc_ecma_parser/src/parser/stmt.rs | Applies error recovery to control flow statements (if, while, for, switch, do-while) |
| crates/swc_ecma_parser/src/parser/expr.rs | Applies error recovery to array literals and function call arguments |
| crates/swc_ecma_parser/src/parser/object.rs | Applies error recovery to object literal parsing |
| crates/swc_ecma_parser/tests/errors/* | Adds new test cases for error recovery scenarios |
| crates/swc_ecma_parser/tests/test262-error-references/fail/* | Updates expected error outputs to include additional recovery errors |
| crates/swc_ecma_parser/tests/typescript-errors/issue-7104/* | Removes test files (errors are now recovered from) |
| crates/swc/tests/tsc-references/* | Updates TypeScript test reference outputs |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Emit error for missing comma | ||
| let span = p.input().cur_span(); | ||
| let cur = p.input_mut().dump_cur(); | ||
| p.emit_err(span, SyntaxError::Expected(",".into(), cur)); |
Copilot
AI
Feb 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After emitting an error for a missing comma, the parser continues without consuming the unexpected token. This could potentially lead to issues if parse_prop on the next iteration doesn't consume the token or make progress. While the tests may pass for common cases, consider adding explicit token consumption after the error to make the recovery more robust and prevent potential infinite loops in edge cases. For example, you could add a check to consume the unexpected token before continuing the loop.
| p.emit_err(span, SyntaxError::Expected(",".into(), cur)); | |
| p.emit_err(span, SyntaxError::Expected(",".into(), cur)); | |
| // Consume the unexpected token to ensure forward progress | |
| p.input_mut().bump(); |
| // Emit error for missing comma but continue parsing | ||
| let span = self.input().cur_span(); | ||
| let cur = self.input_mut().dump_cur(); | ||
| self.emit_err(span, SyntaxError::Expected(",".into(), cur)); |
Copilot
AI
Feb 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After emitting an error for a missing comma, the parser continues without consuming the unexpected token. This could potentially lead to issues if parse_expr_or_spread on the next iteration doesn't consume the token or make progress. While the tests may pass for common cases, consider adding explicit token consumption after the error to make the recovery more robust and prevent potential infinite loops in edge cases. For example, you could add a check to consume the unexpected token before continuing the loop.
| // Emit error for missing comma but continue parsing | |
| let span = self.input().cur_span(); | |
| let cur = self.input_mut().dump_cur(); | |
| self.emit_err(span, SyntaxError::Expected(",".into(), cur)); | |
| // Emit error for missing comma but continue parsing. | |
| // Also consume the unexpected token to ensure forward progress. | |
| let span = self.input().cur_span(); | |
| let cur = self.input_mut().dump_cur(); | |
| self.emit_err(span, SyntaxError::Expected(",".into(), cur)); | |
| // Consume the unexpected token to avoid potential infinite loops | |
| self.input_mut().bump(); |
| // Emit error for missing comma | ||
| let span = p.input().cur_span(); | ||
| let cur = p.input_mut().dump_cur(); | ||
| p.emit_err(span, SyntaxError::Expected(",".into(), cur)); |
Copilot
AI
Feb 2, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After emitting an error for a missing comma, the parser continues without consuming the unexpected token. This could potentially lead to issues if parse_expr_or_spread on the next iteration doesn't consume the token or make progress. While the tests may pass for common cases, consider adding explicit token consumption after the error to make the recovery more robust and prevent potential infinite loops in edge cases. For example, you could add a check to consume the unexpected token before continuing the loop.
| p.emit_err(span, SyntaxError::Expected(",".into(), cur)); | |
| p.emit_err(span, SyntaxError::Expected(",".into(), cur)); | |
| // Recovery: consume the unexpected token to ensure progress | |
| p.input_mut().bump(); | |
| continue; |
This PR makes the ES parser less strict by implementing error recovery for common syntax errors.
Closes #11468
Generated with Claude Code