Skip to content

Commit 0d0c6f6

Browse files
NullVoxPopuliclaude
andcommitted
Delegate .tsbuildinfo reads to the real ts.sys.readFile
Only the default `tsconfig.tsbuildinfo` name was guarded, so a project with a custom `tsBuildInfoFile` (e.g. "declarations/.tsbuildinfo") that hasn't been built yet crashed type-aware linting of every file with `Parsing error: ENOENT`. The watch program reads the buildinfo without a fileExists probe, so readFile must report missing as absent per the ts.sys contract. Buildinfo is never a .gts/.gjs file, so instead of guarding with our own fs call, delegate to the unpatched host readFile: content when present, undefined when missing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 484f500 commit 0d0c6f6

2 files changed

Lines changed: 27 additions & 29 deletions

File tree

src/parser/ts-patch.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,15 @@ try {
3737
let fileName = fname;
3838
let content = '';
3939
if (fileName.endsWith('.tsbuildinfo')) {
40-
// Incremental build state is optional: return it when present, but
41-
// report a missing file as absent instead of throwing. The watch
42-
// program reads `tsBuildInfoFile` without a fileExists probe
43-
// (readBuilderProgram -> host.readFile), so a fresh/cleaned project
44-
// with a custom buildinfo path (e.g. "declarations/.tsbuildinfo")
45-
// would otherwise abort linting with a Parsing error: ENOENT.
46-
try {
47-
return fs.readFileSync(fileName).toString();
48-
} catch {
49-
return content;
50-
}
40+
// Incremental build state is optional and never a .gts/.gjs file, so
41+
// delegate to the real host: it returns the content when present and
42+
// reports a missing file as absent (undefined) instead of throwing.
43+
// The watch program reads `tsBuildInfoFile` without a fileExists
44+
// probe (readBuilderProgram -> host.readFile), so a fresh/cleaned
45+
// project with a custom buildinfo path (e.g.
46+
// "declarations/.tsbuildinfo") would otherwise abort linting of
47+
// every file with a Parsing error: ENOENT.
48+
return sys.readFile(fileName);
5149
}
5250

5351
try {

tests/ts-patch.test.js

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,26 @@ const ts = require(require.resolve('typescript', { paths: [parserPath] }));
2020
// linting of every file in the project with
2121
// `Parsing error: ENOENT ... <project>/declarations/.tsbuildinfo`.
2222
describe('patched ts.sys.readFile — .tsbuildinfo handling', () => {
23-
patchTs();
23+
patchTs();
2424

25-
it('treats a missing custom-named .tsbuildinfo as absent instead of throwing', () => {
26-
// e.g. { "tsBuildInfoFile": "declarations/.tsbuildinfo" } — only the
27-
// default `tsconfig.tsbuildinfo` name was guarded before.
28-
const missing = path.join(os.tmpdir(), 'ee-parser-no-such-dir', 'declarations', '.tsbuildinfo');
25+
it('treats a missing custom-named .tsbuildinfo as absent instead of throwing', () => {
26+
// e.g. { "tsBuildInfoFile": "declarations/.tsbuildinfo" } — only the
27+
// default `tsconfig.tsbuildinfo` name was guarded before.
28+
const missing = path.join(os.tmpdir(), 'ee-parser-no-such-dir', 'declarations', '.tsbuildinfo');
2929

30-
expect(() => ts.sys.readFile(missing)).not.toThrow();
31-
expect(ts.sys.readFile(missing)).toBe('');
32-
});
30+
expect(() => ts.sys.readFile(missing)).not.toThrow();
31+
expect(ts.sys.readFile(missing)).toBeUndefined();
32+
});
3333

34-
it('returns the real content when the .tsbuildinfo exists', () => {
35-
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ee-parser-buildinfo-'));
36-
const buildInfo = path.join(dir, 'custom.tsbuildinfo');
37-
fs.writeFileSync(buildInfo, '{"version":"5.9.3"}');
34+
it('returns the real content when the .tsbuildinfo exists', () => {
35+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ee-parser-buildinfo-'));
36+
const buildInfo = path.join(dir, 'custom.tsbuildinfo');
37+
fs.writeFileSync(buildInfo, '{"version":"5.9.3"}');
3838

39-
try {
40-
expect(ts.sys.readFile(buildInfo)).toBe('{"version":"5.9.3"}');
41-
} finally {
42-
fs.rmSync(dir, { recursive: true, force: true });
43-
}
44-
});
39+
try {
40+
expect(ts.sys.readFile(buildInfo)).toBe('{"version":"5.9.3"}');
41+
} finally {
42+
fs.rmSync(dir, { recursive: true, force: true });
43+
}
44+
});
4545
});

0 commit comments

Comments
 (0)