fix(parser): preserve in-context after TypeScript type arguments (#28300)

Type arguments followed by `in` must preserve the surrounding grammar
context. Accept the binary operator in expressions while leaving it
available as the separator in `for-in` heads.

AI-assisted implementation.
This commit is contained in:
Boshen authored and GitHub committed 2026-10-29 16:30:19 +08:00
1 parent 2e3126c1cf
commit 3b36543095
9 files changed
+29 -14

No files matched your search

+2 -2
View File
@@ -1610,7 +1610,7 @@ impl<'a, C: Config> ParserImpl<'a, C> {
}
fn is_binary_operator(&self) -> bool {
if self.ctx.has_in() && self.at(Kind::In) {
if !self.ctx.has_in() && self.at(Kind::In) {
return false;
}
self.cur_kind().is_binary_operator()
@@ -1624,7 +1624,7 @@ impl<'a, C: Config> ParserImpl<'a, C> {
kind if kind.is_unary_operator() => true,
kind if kind.is_update_operator() => true,
Kind::LAngle | Kind::Await | Kind::Yield | Kind::Private | Kind::At => true,
kind if kind.is_binary_operator() => true,
_ if self.is_binary_operator() => true,
kind => kind.is_ts_identifier(self.ctx.has_yield(), self.ctx.has_await()),
}
}
@@ -0,0 +1,5 @@
const factory = null as unknown as string & { <T>(): T };
const object = {};
// Keep the instantiation before the for-in delimiter in this non-strict CommonJS file.
for (var key = factory<number> in object) {}
@@ -0,0 +1,10 @@
const factory = null as unknown as string & { <T>(): T };
const object = {};
type Box<T> = { value: T };
const direct = factory<number> in object;
const nested = factory<Box<number>> in object;
if (factory<string> in object) {}
for (; factory<number> in object; ) {}
for (let present = (factory<boolean> in object); present; ) {}
+2 -2
View File
@@ -1,3 +1,3 @@
codegen_misc Summary:
AST Parsed : 125/125 (100.00%)
Positive Passed: 125/125 (100.00%)
AST Parsed : 127/127 (100.00%)
Positive Passed: 127/127 (100.00%)
+2 -2
View File
@@ -1,3 +1,3 @@
formatter_misc Summary:
AST Parsed : 125/125 (100.00%)
Positive Passed: 125/125 (100.00%)
AST Parsed : 127/127 (100.00%)
Positive Passed: 127/127 (100.00%)
+2 -2
View File
@@ -1,3 +1,3 @@
lexer_misc Summary:
AST Parsed : 388/388 (100.00%)
Positive Passed: 388/388 (100.00%)
AST Parsed : 390/390 (100.00%)
Positive Passed: 390/390 (100.00%)
+2 -2
View File
@@ -1,6 +1,6 @@
parser_misc Summary:
AST Parsed : 125/125 (100.00%)
Positive Passed: 125/125 (100.00%)
AST Parsed : 127/127 (100.00%)
Positive Passed: 127/127 (100.00%)
Negative Passed: 265/265 (100.00%)
× TS(1275): 'accessor' modifier can only appear on a property declaration.
+2 -2
View File
@@ -1,6 +1,6 @@
semantic_misc Summary:
AST Parsed : 125/125 (100.00%)
Positive Passed: 119/125 (95.20%)
AST Parsed : 127/127 (100.00%)
Positive Passed: 121/127 (95.28%)
semantic Error: tasks/coverage/misc/pass/declare-let-private.ts
Bindings mismatch:
after transform: ScopeId(0): ["private"]
@@ -1,3 +1,3 @@
transformer_misc Summary:
AST Parsed : 125/125 (100.00%)
Positive Passed: 125/125 (100.00%)
AST Parsed : 127/127 (100.00%)
Positive Passed: 127/127 (100.00%)