From 179a43288db120a9bf506586849643ff50d44776 Mon Sep 17 00:00:00 2001 From: Boshen Date: Thu, 29 Oct 2026 14:22:30 +0000 Subject: [PATCH] perf(parser): factor return type identifier parsing (#28416) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consume the shared leading identifier once for return types and type predicates. Local arm64 parse time: named return-type fixtures −8–11%; parenthesized return fixture +1.5%. Ordinary corpus −0.20% (−0.32% with tokens). Validated parser and Node suites, unchanged conformance and allocations, and 50,668 differential comparisons. AI assistance: Codex. --- crates/oxc_parser/src/ts/types.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/crates/oxc_parser/src/ts/types.rs b/crates/oxc_parser/src/ts/types.rs index 0d84f85050..092a725e94 100644 --- a/crates/oxc_parser/src/ts/types.rs +++ b/crates/oxc_parser/src/ts/types.rs @@ -1102,7 +1102,8 @@ impl<'a, C: Config> ParserImpl<'a, C> { } } - /// Continue a tuple element type after consuming its leading identifier. + /// Continue a type after consuming its leading identifier. + #[inline] fn parse_ts_type_from_identifier(&mut self, ident: &IdentifierName<'a>) -> TSType<'a> { let start = ident.span.start; let ty = self.context_remove(Context::DisallowConditionalTypes, |p| { @@ -1375,7 +1376,19 @@ impl<'a, C: Config> ParserImpl<'a, C> { fn parse_type_or_type_predicate(&mut self) -> TSType<'a> { let start = self.cur_start(); - let type_predicate_variable = self.parse_type_predicate_prefix(); + let type_predicate_variable = if self.at(Kind::Ident) { + // A plain identifier begins either a predicate parameter or a type reference. + // Consume their shared prefix once instead of lexing the next token twice. + let ident = self.parse_known_identifier_name(); + if !self.at(Kind::Is) || self.cur_token().is_on_new_line() { + return self.parse_ts_type_from_identifier(&ident); + } + let parameter_name = TSTypePredicateName::Identifier(self.alloc(ident)); + self.bump_any(); // bump `is` + Some(parameter_name) + } else { + self.parse_type_predicate_prefix() + }; let ty = self.parse_ts_type(); if let Some(parameter_name) = type_predicate_variable {