perf(parser): factor return type identifier parsing (#28416)

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.
This commit is contained in:
Boshen committed 2026-10-29 14:22:31 +00:00
1 parent 553dd1d1a0
commit 179a43288d
1 file changed
+15 -2
+15 -2
View File
@@ -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 {