feat(parser): report spec parse errors via recoverable_errors#94
Merged
Conversation
CSS Syntax recovers from EOF/newline-unclosed constructs to a valid AST,
but the spec labels each "this is a parse error". These recoveries were
silent (no `recoverable_errors()` entry), so downstream consumers could
not tell recovered-from-broken input apart from valid CSS.
Record them, purely additively (AST and recovery unchanged):
- `EofInBlock` — a `{}`-block closed at EOF (covers style-rule and
at-rule blocks), recorded in `SimpleBlock::parse`.
- `UnterminatedString` (EOF) / `BadString` (newline) — an unterminated
string kept as a preserved `<bad-string-token>`, recorded in
`parse_declaration_value_tokens` and split by where the string stopped.
- `UnclosedParen` — a `(`/`[` group closed at EOF in a raw value.
wpt css-syntax conformance is unaffected; only genuinely-broken `.css`
fixtures in the dialect suites flip clean -> recovered.
Merging this PR will not alter performance
Comparing Footnotes
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a7f560b80b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #86.
Problem
Since the css-syntax conformance work (#61), the parser recovers from EOF/newline-unclosed constructs to a valid AST but records nothing in
recoverable_errors(). The recovery is spec-conformant, yet the spec labels each of these "this is a parse error", so downstream consumers (oxc_formatter_css) cannot tell recovered-from-broken input apart from valid CSS — and end up formatting it into corrupted, non-idempotent output.Change
Record these spec parse errors. Purely additive — the AST and recovery behavior are unchanged, so css-syntax conformance is unaffected (same mechanism as the existing
TopLevelDeclarationrecoverable error).New
ErrorKinds and where they're recorded (two sites cover every case):EofInBlock{}-block closed at EOF (style-rule and at-rule blocks)SimpleBlock::parseUnterminatedString(reused)<string-token>parse_declaration_value_tokensBadString<bad-string-token>parse_declaration_value_tokensUnclosedParen(/[group closed at EOF in a raw valueparse_declaration_value_tokensEvery other unclosed-construct context (
@import "…,a[href="…,@media (…) already hard-errors, so these are the only silent-recovery paths.BadUrlfrom the issue's "e.g." list is not applicable: this parser modelsurl(…)as a flexible function rather than emitting spec bad-url-tokens, so there was never a silent bad-url recovery to convert.Verification
cargo fmt+clippyclean..cssfixtures in the dialect suites (sass-spec, less.js) fromclean→recovered; each is a genuine malformation (e.g. a sassoutput.csswith a strayoutput: ";, and a truncated less.jsactual.cssending mid-base64). Snapshots regenerated.tests/ast/(which asserts no recoverable errors) intotests/recoverable/eof/, and added fixtures/snapshots covering every kind.🤖 Generated with Claude Code