From e7a833da1db41e243657ee1ac3eddaf0e00677ff Mon Sep 17 00:00:00 2001 From: Eric Minish Date: Thu, 5 Nov 2026 20:51:44 -0500 Subject: [PATCH 1/2] test(ts-differential): pin constructs the SegaraRai fork regresses Reserved words as export aliases and typeof import("x").member parse on the vendored grammar but fail on SegaraRai/tree-sitter-typescript@82b3609. They were only covered by chance inside the Effect, Zod and VS Code corpora; as strict fixtures, any grammar bump or fork that regresses them fails the job. --- __tests__/fixtures/ts-syntax/reserved-word-alias.ts | 6 ++++++ __tests__/fixtures/ts-syntax/typeof-import-member.ts | 4 ++++ 2 files changed, 10 insertions(+) create mode 100644 __tests__/fixtures/ts-syntax/reserved-word-alias.ts create mode 100644 __tests__/fixtures/ts-syntax/typeof-import-member.ts diff --git a/__tests__/fixtures/ts-syntax/reserved-word-alias.ts b/__tests__/fixtures/ts-syntax/reserved-word-alias.ts new file mode 100644 index 000000000..a7afe10b6 --- /dev/null +++ b/__tests__/fixtures/ts-syntax/reserved-word-alias.ts @@ -0,0 +1,6 @@ +// Reserved words as export aliases (ES2015 IdentifierName). The current grammar parses +// these; SegaraRai/tree-sitter-typescript@82b3609 regresses them (Effect, Zod use them). +const a = 1; +const b = 2; +export { a as null, b as void }; +export { a as delete, b as function }; diff --git a/__tests__/fixtures/ts-syntax/typeof-import-member.ts b/__tests__/fixtures/ts-syntax/typeof-import-member.ts new file mode 100644 index 000000000..312378d03 --- /dev/null +++ b/__tests__/fixtures/ts-syntax/typeof-import-member.ts @@ -0,0 +1,4 @@ +// `typeof import("x").member` in a type position. The current grammar parses it; +// SegaraRai/tree-sitter-typescript@82b3609 regresses it (VS Code uses it). +export type Mod = typeof import("./mod").default; +export type Fn = typeof import("./mod").helper; From 5888bf2e48f11e1d5366786855bce76b1660b7e0 Mon Sep 17 00:00:00 2001 From: Eric Minish Date: Thu, 5 Nov 2026 20:55:15 -0500 Subject: [PATCH 2/2] test(ts-differential): pin the actual regressed rules, in ts and tsx Review found the fork breaks a reserved word after typeof in a type (typeof ns.default), not typeof import() itself, and reserved words in import and re-export specifiers too. Rename and widen the fixtures, and add tsx twins so the tsx grammar is pinned as well. --- __tests__/fixtures/ts-syntax/reserved-word-alias.ts | 11 ++++++----- __tests__/fixtures/ts-syntax/reserved-word-alias.tsx | 7 +++++++ __tests__/fixtures/ts-syntax/typeof-import-member.ts | 4 ---- .../fixtures/ts-syntax/typeof-reserved-member.ts | 8 ++++++++ .../fixtures/ts-syntax/typeof-reserved-member.tsx | 8 ++++++++ 5 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 __tests__/fixtures/ts-syntax/reserved-word-alias.tsx delete mode 100644 __tests__/fixtures/ts-syntax/typeof-import-member.ts create mode 100644 __tests__/fixtures/ts-syntax/typeof-reserved-member.ts create mode 100644 __tests__/fixtures/ts-syntax/typeof-reserved-member.tsx diff --git a/__tests__/fixtures/ts-syntax/reserved-word-alias.ts b/__tests__/fixtures/ts-syntax/reserved-word-alias.ts index a7afe10b6..834cebecd 100644 --- a/__tests__/fixtures/ts-syntax/reserved-word-alias.ts +++ b/__tests__/fixtures/ts-syntax/reserved-word-alias.ts @@ -1,6 +1,7 @@ -// Reserved words as export aliases (ES2015 IdentifierName). The current grammar parses -// these; SegaraRai/tree-sitter-typescript@82b3609 regresses them (Effect, Zod use them). +// Reserved words as module export/import names (ES2015 IdentifierName). The current +// grammar parses these; SegaraRai/tree-sitter-typescript@82b3609 does not (Effect, Zod). +import { null as n, void as v } from "./mod"; const a = 1; -const b = 2; -export { a as null, b as void }; -export { a as delete, b as function }; +export { a as null, a as delete, n as function, v as void }; +export { null as x, a as default } from "./mod"; +export * as delete from "./mod"; diff --git a/__tests__/fixtures/ts-syntax/reserved-word-alias.tsx b/__tests__/fixtures/ts-syntax/reserved-word-alias.tsx new file mode 100644 index 000000000..834cebecd --- /dev/null +++ b/__tests__/fixtures/ts-syntax/reserved-word-alias.tsx @@ -0,0 +1,7 @@ +// Reserved words as module export/import names (ES2015 IdentifierName). The current +// grammar parses these; SegaraRai/tree-sitter-typescript@82b3609 does not (Effect, Zod). +import { null as n, void as v } from "./mod"; +const a = 1; +export { a as null, a as delete, n as function, v as void }; +export { null as x, a as default } from "./mod"; +export * as delete from "./mod"; diff --git a/__tests__/fixtures/ts-syntax/typeof-import-member.ts b/__tests__/fixtures/ts-syntax/typeof-import-member.ts deleted file mode 100644 index 312378d03..000000000 --- a/__tests__/fixtures/ts-syntax/typeof-import-member.ts +++ /dev/null @@ -1,4 +0,0 @@ -// `typeof import("x").member` in a type position. The current grammar parses it; -// SegaraRai/tree-sitter-typescript@82b3609 regresses it (VS Code uses it). -export type Mod = typeof import("./mod").default; -export type Fn = typeof import("./mod").helper; diff --git a/__tests__/fixtures/ts-syntax/typeof-reserved-member.ts b/__tests__/fixtures/ts-syntax/typeof-reserved-member.ts new file mode 100644 index 000000000..ab4517d8d --- /dev/null +++ b/__tests__/fixtures/ts-syntax/typeof-reserved-member.ts @@ -0,0 +1,8 @@ +// A reserved word as the member after `typeof` in a type position (`typeof X.default`). +// The current grammar parses these; SegaraRai/tree-sitter-typescript@82b3609 does not +// (VS Code's `typeof import("x").default` is the common real-world form). +declare const ns: { default: 1; delete: 2; null: 3; b: { delete: 4 } }; +export type A = typeof import("./mod").default; +export type B = typeof ns.default; +export type C = typeof ns.b.delete; +export let v: typeof ns.null; diff --git a/__tests__/fixtures/ts-syntax/typeof-reserved-member.tsx b/__tests__/fixtures/ts-syntax/typeof-reserved-member.tsx new file mode 100644 index 000000000..ab4517d8d --- /dev/null +++ b/__tests__/fixtures/ts-syntax/typeof-reserved-member.tsx @@ -0,0 +1,8 @@ +// A reserved word as the member after `typeof` in a type position (`typeof X.default`). +// The current grammar parses these; SegaraRai/tree-sitter-typescript@82b3609 does not +// (VS Code's `typeof import("x").default` is the common real-world form). +declare const ns: { default: 1; delete: 2; null: 3; b: { delete: 4 } }; +export type A = typeof import("./mod").default; +export type B = typeof ns.default; +export type C = typeof ns.b.delete; +export let v: typeof ns.null;