Skip to content

Commit eb02b08

Browse files
authored
fix: file was not found error when d.ts exist (#16)
* fix: file was not found error when d.ts exist * Create honest-rice-travel.md
1 parent cfe22ff commit eb02b08

File tree

4 files changed

+135
-33
lines changed

4 files changed

+135
-33
lines changed

Diff for: .changeset/honest-rice-travel.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"typescript-eslint-parser-for-extra-files": patch
3+
---
4+
5+
fix: file was not found error when d.ts exist

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"release": "changeset publish",
4646
"test": "yarn mocha \"tests/src/**/*.ts\" --reporter dot --timeout 60000",
4747
"ts": "node -r esbuild-register",
48-
"update-fixture": "yarn mocha \"tests/src/**/*.ts\" --update --reporter dot --timeout 60000"
48+
"update-fixture": "yarn mocha \"tests/src/**/types.ts\" --update --reporter dot --timeout 60000"
4949
},
5050
"peerDependencies": {
5151
"@typescript-eslint/parser": ">=5.41.0",

Diff for: src/ts.ts

+127-32
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,14 @@ export class TSService {
5353
dirMap: new Map<string, { name: string; path: string }>(),
5454
};
5555

56-
private readonly fileWatchCallbacks = new Map<string, () => void>();
56+
private readonly fileWatchCallbacks = new Map<
57+
string,
58+
{
59+
setupTarget: () => void;
60+
resetTarget: () => void;
61+
update: () => void;
62+
}
63+
>();
5764

5865
public constructor(tsconfigPath: string, extraFileExtensions: string[]) {
5966
this.tsconfigPath = tsconfigPath;
@@ -83,18 +90,28 @@ export class TSService {
8390
if (!ts.sys.fileExists(targetPath)) {
8491
// Signal a directory change to request a re-scan of the directory
8592
// because it targets a file that does not actually exist.
86-
this.fileWatchCallbacks.get(normalizeFileName(this.tsconfigPath))?.();
93+
this.fileWatchCallbacks
94+
.get(normalizeFileName(this.tsconfigPath))
95+
?.update();
8796
}
88-
getRefreshTargetFileNames(targetPath, this.extraFileExtensions).forEach(
89-
(vFilePath) => {
90-
this.fileWatchCallbacks.get(vFilePath)?.();
91-
}
92-
);
9397
}
98+
getRefreshTargetFileNames(
99+
lastTarget.filePath,
100+
this.extraFileExtensions
101+
).forEach((vFilePath) => {
102+
this.fileWatchCallbacks.get(vFilePath)?.resetTarget();
103+
});
104+
getRefreshTargetFileNames(
105+
this.currTarget.filePath,
106+
this.extraFileExtensions
107+
).forEach((vFilePath) => {
108+
this.fileWatchCallbacks.get(vFilePath)?.setupTarget();
109+
});
94110

95111
const program = this.watch.getProgram().getProgram();
96112
// sets parent pointers in source files
97113
program.getTypeChecker();
114+
98115
return program;
99116
}
100117

@@ -168,18 +185,9 @@ export class TSService {
168185
results.push(file.path);
169186
}
170187

171-
return distinctArray(...results).map((result) => {
172-
if (!isExtra(result, extraFileExtensions)) {
173-
return result;
174-
}
175-
176-
if (original.fileExists.call(watchCompilerHost, `${result}.d.ts`)) {
177-
// If the d.ts file exists, respect it and consider the virtual file not to exist.
178-
return result;
179-
}
180-
181-
return toVirtualTSXFileName(result, extraFileExtensions);
182-
});
188+
return distinctArray(...results).map((result) =>
189+
toVirtualTSXFileName(result, extraFileExtensions)
190+
);
183191
};
184192
watchCompilerHost.readFile = (fileName, ...args) => {
185193
const realFileName = toRealFileName(fileName, extraFileExtensions);
@@ -191,6 +199,23 @@ export class TSService {
191199
current: true,
192200
});
193201
}
202+
if (isExtraDts(fileName, extraFileExtensions)) {
203+
const real = normalizeFileName(
204+
extraDtsToExtra(fileName, extraFileExtensions)
205+
);
206+
if (this.currTarget.filePath === real) {
207+
// If try to read the .d.ts of the target file,
208+
// respect the target file and consider the .d.ts doesn't exist.
209+
return undefined;
210+
}
211+
}
212+
if (isVirtualTSX(fileName, extraFileExtensions)) {
213+
const dts = toExtraDtsFileName(normalized, extraFileExtensions);
214+
if (original.fileExists.call(watchCompilerHost, dts)) {
215+
// If the .d.ts file exists, respect it and consider the virtual file not to exist.
216+
return undefined;
217+
}
218+
}
194219

195220
const code = original.readFile.call(
196221
watchCompilerHost,
@@ -251,11 +276,20 @@ export class TSService {
251276
// It is the file currently being parsed.
252277
return true;
253278
}
254-
const real = toRealFileName(fileName, extraFileExtensions);
255-
if (original.fileExists.call(watchCompilerHost, real, ...args)) {
256-
if (real !== fileName) {
279+
if (
280+
original.fileExists.call(
281+
watchCompilerHost,
282+
normalizedRealFileName,
283+
...args
284+
)
285+
) {
286+
if (isVirtualTSX(fileName, extraFileExtensions)) {
257287
if (
258-
original.fileExists.call(watchCompilerHost, `${real}.d.ts`, ...args)
288+
original.fileExists.call(
289+
watchCompilerHost,
290+
toExtraDtsFileName(normalizedRealFileName, extraFileExtensions),
291+
...args
292+
)
259293
) {
260294
// If the d.ts file exists, respect it and consider the virtual file not to exist.
261295
return false;
@@ -269,9 +303,30 @@ export class TSService {
269303
// It keeps a callback to mark the parsed file as changed so that it can be reparsed.
270304
watchCompilerHost.watchFile = (fileName, callback) => {
271305
const normalized = normalizeFileName(fileName);
272-
this.fileWatchCallbacks.set(normalized, () =>
273-
callback(fileName, ts.FileWatcherEventKind.Changed)
274-
);
306+
this.fileWatchCallbacks.set(normalized, {
307+
// The function is called when the file is targeted for parsing.
308+
setupTarget: () => {
309+
if (isExtraDts(fileName, extraFileExtensions)) {
310+
callback(fileName, ts.FileWatcherEventKind.Deleted);
311+
} else if (isVirtualTSX(fileName, extraFileExtensions)) {
312+
callback(fileName, ts.FileWatcherEventKind.Created);
313+
} else {
314+
callback(fileName, ts.FileWatcherEventKind.Changed);
315+
}
316+
},
317+
// The function is called when the file leaves the target of parsing.
318+
resetTarget: () => {
319+
if (isExtraDts(fileName, extraFileExtensions)) {
320+
// If the .d.ts file exists, it will take respect.
321+
callback(fileName, ts.FileWatcherEventKind.Created);
322+
} else if (isVirtualTSX(fileName, extraFileExtensions)) {
323+
callback(fileName, ts.FileWatcherEventKind.Deleted);
324+
} else {
325+
callback(fileName, ts.FileWatcherEventKind.Changed);
326+
}
327+
},
328+
update: () => callback(fileName, ts.FileWatcherEventKind.Changed),
329+
});
275330

276331
return {
277332
close: () => {
@@ -322,25 +377,42 @@ function getRefreshTargetFileNames(
322377
return [fileName];
323378
}
324379

325-
/** If the given filename has extra file extensions, returns the real virtual filename. */
380+
/** If the given filename has extra extensions, returns the real virtual filename. */
326381
function toVirtualTSXFileName(fileName: string, extraFileExtensions: string[]) {
327382
if (isExtra(fileName, extraFileExtensions)) {
328383
return `${fileName}.tsx`;
329384
}
330385
return fileName;
331386
}
332387

388+
/** If the given filename has extra extensions, returns the d.ts filename. */
389+
function toExtraDtsFileName(fileName: string, extraFileExtensions: string[]) {
390+
if (isExtra(fileName, extraFileExtensions)) {
391+
return `${fileName}.d.ts`;
392+
}
393+
return fileName;
394+
}
395+
333396
/** If the given filename is a virtual filename (.vue.tsx), returns the real filename. */
334397
function toRealFileName(fileName: string, extraFileExtensions: string[]) {
335-
for (const extraFileExtension of extraFileExtensions) {
336-
if (fileName.endsWith(`${extraFileExtension}.tsx`)) {
337-
return fileName.slice(0, -4);
338-
}
398+
if (isVirtualTSX(fileName, extraFileExtensions)) {
399+
return fileName.slice(0, -4);
339400
}
340401
return fileName;
341402
}
342403

343-
/** Checks the given filename has extra file extension or not. */
404+
/** If the given filename is has extra extension with d.ts, returns the real filename. */
405+
function extraDtsToExtra(
406+
fileName: string,
407+
extraFileExtensions: string[]
408+
): string {
409+
if (isExtraDts(fileName, extraFileExtensions)) {
410+
return fileName.slice(0, -5);
411+
}
412+
return fileName;
413+
}
414+
415+
/** Checks the given filename has extra extension or not. */
344416
function isExtra(fileName: string, extraFileExtensions: string[]): boolean {
345417
for (const extraFileExtension of extraFileExtensions) {
346418
if (fileName.endsWith(extraFileExtension)) {
@@ -350,6 +422,29 @@ function isExtra(fileName: string, extraFileExtensions: string[]): boolean {
350422
return false;
351423
}
352424

425+
/** Checks the given filename is virtual file tsx or not. */
426+
function isVirtualTSX(
427+
fileName: string,
428+
extraFileExtensions: string[]
429+
): boolean {
430+
for (const extraFileExtension of extraFileExtensions) {
431+
if (fileName.endsWith(`${extraFileExtension}.tsx`)) {
432+
return true;
433+
}
434+
}
435+
return false;
436+
}
437+
438+
/** Checks the given filename has extra extension with d.ts or not. */
439+
function isExtraDts(fileName: string, extraFileExtensions: string[]): boolean {
440+
for (const extraFileExtension of extraFileExtensions) {
441+
if (fileName.endsWith(`${extraFileExtension}.d.ts`)) {
442+
return true;
443+
}
444+
}
445+
return false;
446+
}
447+
353448
function formatDiagnostics(diagnostics: ts.Diagnostic[]) {
354449
return ts.formatDiagnostics(diagnostics, {
355450
getCanonicalFileName: (f) => f,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
declare const A = 42;
2+
export default A;

0 commit comments

Comments
 (0)