From 9772545dd0fc684cb1c784f7f18dba6804359096 Mon Sep 17 00:00:00 2001 From: Ulrich Stark Date: Sun, 31 Aug 2025 20:46:59 +0200 Subject: [PATCH] fix(parser): reset popped lexer errors when rewinding --- crates/oxc_parser/src/lexer/mod.rs | 17 +++++++---------- tasks/coverage/misc/fail/oxc-12816.ts | 1 + tasks/coverage/snapshots/parser_misc.snap | 8 +++++++- 3 files changed, 15 insertions(+), 11 deletions(-) create mode 100644 tasks/coverage/misc/fail/oxc-12816.ts diff --git a/crates/oxc_parser/src/lexer/mod.rs b/crates/oxc_parser/src/lexer/mod.rs index f2292d7129f5a..2bbc1ff0529c9 100644 --- a/crates/oxc_parser/src/lexer/mod.rs +++ b/crates/oxc_parser/src/lexer/mod.rs @@ -40,14 +40,11 @@ pub use token::Token; use source::{Source, SourcePosition}; use trivia_builder::TriviaBuilder; -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] pub struct LexerCheckpoint<'a> { - /// Current position in source - position: SourcePosition<'a>, - + source_position: SourcePosition<'a>, token: Token, - - errors_pos: usize, + errors: Vec, } #[derive(Debug, Copy, Clone, Eq, PartialEq)] @@ -141,16 +138,16 @@ impl<'a> Lexer<'a> { /// Use `rewind` to restore the lexer to the state stored in the checkpoint. pub fn checkpoint(&self) -> LexerCheckpoint<'a> { LexerCheckpoint { - position: self.source.position(), + source_position: self.source.position(), token: self.token, - errors_pos: self.errors.len(), + errors: self.errors.clone(), } } /// Rewinds the lexer to the same state as when the passed in `checkpoint` was created. pub fn rewind(&mut self, checkpoint: LexerCheckpoint<'a>) { - self.errors.truncate(checkpoint.errors_pos); - self.source.set_position(checkpoint.position); + self.errors = checkpoint.errors; + self.source.set_position(checkpoint.source_position); self.token = checkpoint.token; } diff --git a/tasks/coverage/misc/fail/oxc-12816.ts b/tasks/coverage/misc/fail/oxc-12816.ts new file mode 100644 index 0000000000000..747246cfef609 --- /dev/null +++ b/tasks/coverage/misc/fail/oxc-12816.ts @@ -0,0 +1 @@ +{if(\ ()<1){}} \ No newline at end of file diff --git a/tasks/coverage/snapshots/parser_misc.snap b/tasks/coverage/snapshots/parser_misc.snap index 3f4579684208f..6ebc70330f1b2 100644 --- a/tasks/coverage/snapshots/parser_misc.snap +++ b/tasks/coverage/snapshots/parser_misc.snap @@ -1,7 +1,7 @@ parser_misc Summary: AST Parsed : 48/48 (100.00%) Positive Passed: 48/48 (100.00%) -Negative Passed: 78/78 (100.00%) +Negative Passed: 79/79 (100.00%) × Cannot assign to 'arguments' in strict mode ╭─[misc/fail/arguments-eval.ts:1:10] @@ -437,6 +437,12 @@ Negative Passed: 78/78 (100.00%) · ────────────────────── ╰──── + × Invalid Unicode escape sequence + ╭─[misc/fail/oxc-12816.ts:1:6] + 1 │ {if(\ ()<1){}} + · ─ + ╰──── + × 'super' can only be referenced in members of derived classes or object literal expressions. ╭─[misc/fail/oxc-13284.ts:5:9] 4 │ bar() {