mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
perf(parser): peek before the await-using lookahead (#23059)
## What
`is_using_statement` is gated only on `Kind::Await` in the statement dispatch (`Kind::Await if self.is_using_statement()`), so **every `await` statement** (`await foo();`) ran a full parser `lookahead` — `checkpoint` + `bump` + `eat` + `rewind` — only to discover it isn't `await using`.
Add a cheap `peek_token` pre-check: `await using` requires `using` immediately after `await` on the same line, so only that case pays for the full lookahead (which still does the binding-identifier check on the token after `using`).
```rust
let next = self.lexer.peek_token();
next.kind() == Kind::Using
&& !next.is_on_new_line()
&& self.lookahead(Self::is_next_token_using_keyword_then_binding_identifier)
```
## Why
`await` statements are extremely common in async code; the previous code paid a parser-level checkpoint/rewind on each. `peek_token` is a cached lexer-level re-lex, much cheaper, and short-circuits before the checkpoint in the overwhelmingly common `await <expr>` case.
## Conformance
No AST change — estree (full AST + spans + token streams) byte-identical to `main`.
This commit is contained in:
1 file changed
+7
-1
@@ -38,7 +38,13 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
}
|
||||
|
||||
pub(crate) fn is_using_statement(&mut self) -> bool {
|
||||
self.lookahead(Self::is_next_token_using_keyword_then_binding_identifier)
|
||||
// `await using` requires `using` immediately after `await` on the same line. Cheaply peek
|
||||
// for it first, so the common `await <expr>` statement avoids the heavier `lookahead`
|
||||
// (checkpoint + rewind) and only `await using` pays for the binding-identifier check.
|
||||
let next = self.lexer.peek_token();
|
||||
next.kind() == Kind::Using
|
||||
&& !next.is_on_new_line()
|
||||
&& self.lookahead(Self::is_next_token_using_keyword_then_binding_identifier)
|
||||
}
|
||||
|
||||
fn is_next_token_using_keyword_then_binding_identifier(&mut self) -> bool {
|
||||
|
||||
Reference in new issue
Block a user