Skip to content

Commit b1e064b

Browse files
authored
feat: remove tsconfig patch and virtual filename (#34)
* feat: remove tsconfig patch and virtual filename * Create .changeset/violet-experts-swim.md
1 parent ae0da94 commit b1e064b

File tree

3 files changed

+115
-60
lines changed

3 files changed

+115
-60
lines changed

Diff for: .changeset/violet-experts-swim.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"typescript-eslint-parser-for-extra-files": minor
3+
---
4+
5+
feat: remove tsconfig patch and virtual filename

Diff for: src/index.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,7 @@ export function parseForESLint(
2222
for (const option of iterateOptions(options)) {
2323
programs.push(tsServiceManager.getProgram(code, option));
2424
}
25-
let filePath = options.filePath;
26-
if (
27-
filePath &&
28-
extraFileExtensions.some((ext) => options.filePath?.endsWith(ext))
29-
) {
30-
filePath = `${filePath}.tsx`;
31-
}
25+
const filePath = options.filePath;
3226
const parserOptions = {
3327
...options,
3428
filePath,

Diff for: src/ts.ts

+109-53
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,18 @@ export class TSServiceManager {
4343
export class TSService {
4444
private readonly watch: ts.WatchOfConfigFile<ts.BuilderProgram>;
4545

46+
private readonly patchedHostSet = new WeakSet<ts.CompilerHost>();
47+
4648
private readonly tsconfigPath: string;
4749

4850
public readonly extraFileExtensions: string[];
4951

50-
private currTarget = {
52+
private currTarget: {
53+
code: string;
54+
filePath: string;
55+
sourceFile?: ts.SourceFile;
56+
dirMap: Map<string, { name: string; path: string }>;
57+
} = {
5158
code: "",
5259
filePath: "",
5360
dirMap: new Map<string, { name: string; path: string }>(),
@@ -119,7 +126,90 @@ export class TSService {
119126
tsconfigPath: string,
120127
extraFileExtensions: string[]
121128
): ts.WatchOfConfigFile<ts.BuilderProgram> {
122-
const normalizedTsconfigPaths = new Set([normalizeFileName(tsconfigPath)]);
129+
type CreateProgram = ts.CreateProgram<ts.BuilderProgram>;
130+
131+
const createAbstractBuilder = (
132+
...args: Parameters<CreateProgram>
133+
): ReturnType<CreateProgram> => {
134+
const [
135+
rootNames,
136+
options,
137+
argHost,
138+
oldProgram,
139+
configFileParsingDiagnostics,
140+
projectReferences,
141+
] = args;
142+
143+
const host: ts.CompilerHost = argHost!;
144+
if (!this.patchedHostSet.has(host)) {
145+
this.patchedHostSet.add(host);
146+
147+
const getTargetSourceFile = (
148+
fileName: string,
149+
languageVersionOrOptions: ts.ScriptTarget | ts.CreateSourceFileOptions
150+
) => {
151+
if (
152+
this.currTarget.filePath === normalizeFileName(fileName) &&
153+
isExtra(fileName, extraFileExtensions)
154+
) {
155+
return (this.currTarget.sourceFile ??= ts.createSourceFile(
156+
this.currTarget.filePath,
157+
this.currTarget.code,
158+
languageVersionOrOptions,
159+
true,
160+
ts.ScriptKind.TSX
161+
));
162+
}
163+
return null;
164+
};
165+
166+
/* eslint-disable @typescript-eslint/unbound-method -- ignore */
167+
const original = {
168+
getSourceFile: host.getSourceFile,
169+
getSourceFileByPath: host.getSourceFileByPath!,
170+
};
171+
/* eslint-enable @typescript-eslint/unbound-method -- ignore */
172+
host.getSourceFile = (fileName, languageVersionOrOptions, ...args) => {
173+
const originalSourceFile = original.getSourceFile.call(
174+
host,
175+
fileName,
176+
languageVersionOrOptions,
177+
...args
178+
);
179+
return (
180+
getTargetSourceFile(fileName, languageVersionOrOptions) ??
181+
originalSourceFile
182+
);
183+
};
184+
host.getSourceFileByPath = (
185+
fileName,
186+
path,
187+
languageVersionOrOptions,
188+
...args
189+
) => {
190+
const originalSourceFile = original.getSourceFileByPath.call(
191+
host,
192+
fileName,
193+
path,
194+
languageVersionOrOptions,
195+
...args
196+
);
197+
return (
198+
getTargetSourceFile(fileName, languageVersionOrOptions) ??
199+
originalSourceFile
200+
);
201+
};
202+
}
203+
return ts.createAbstractBuilder(
204+
rootNames,
205+
options,
206+
host,
207+
oldProgram,
208+
configFileParsingDiagnostics,
209+
projectReferences
210+
);
211+
};
212+
123213
const watchCompilerHost = ts.createWatchCompilerHost(
124214
tsconfigPath,
125215
{
@@ -132,19 +222,19 @@ export class TSService {
132222
allowNonTsExtensions: true,
133223
},
134224
ts.sys,
135-
ts.createAbstractBuilder,
225+
createAbstractBuilder,
136226
(diagnostic) => {
137227
throw new Error(formatDiagnostics([diagnostic]));
138228
},
139229
() => {
140230
// Not reported in reportWatchStatus.
141231
},
142-
undefined
143-
// extraFileExtensions.map((extension) => ({
144-
// extension,
145-
// isMixedContent: true,
146-
// scriptKind: ts.ScriptKind.Deferred,
147-
// }))
232+
undefined,
233+
extraFileExtensions.map((extension) => ({
234+
extension,
235+
isMixedContent: true,
236+
scriptKind: ts.ScriptKind.Deferred,
237+
}))
148238
);
149239
const original = {
150240
// eslint-disable-next-line @typescript-eslint/unbound-method -- Store original
@@ -159,11 +249,12 @@ export class TSService {
159249
getDirectories: watchCompilerHost.getDirectories!,
160250
};
161251
watchCompilerHost.getDirectories = (dirName, ...args) => {
162-
return distinctArray(
252+
const result = distinctArray(
163253
...original.getDirectories.call(watchCompilerHost, dirName, ...args),
164254
// Include the path to the target file if the target file does not actually exist.
165255
this.currTarget.dirMap.get(normalizeFileName(dirName))?.name
166256
);
257+
return result;
167258
};
168259
watchCompilerHost.directoryExists = (dirName, ...args) => {
169260
return (
@@ -173,21 +264,23 @@ export class TSService {
173264
);
174265
};
175266
watchCompilerHost.readDirectory = (dirName, ...args) => {
176-
const results = original.readDirectory.call(
267+
let results = original.readDirectory.call(
177268
watchCompilerHost,
178269
dirName,
179270
...args
180271
);
181272

182273
// Include the target file if the target file does not actually exist.
183274
const file = this.currTarget.dirMap.get(normalizeFileName(dirName));
184-
if (file && file.path === this.currTarget.filePath) {
185-
results.push(file.path);
275+
if (file) {
276+
if (file.path === this.currTarget.filePath) {
277+
results.push(file.path);
278+
} else {
279+
results = results.filter((f) => file.path !== f && file.name !== f);
280+
}
186281
}
187282

188-
return distinctArray(...results).map((result) =>
189-
toVirtualTSXFileName(result, extraFileExtensions)
190-
);
283+
return distinctArray(...results);
191284
};
192285
watchCompilerHost.readFile = (fileName, ...args) => {
193286
const realFileName = toRealFileName(fileName, extraFileExtensions);
@@ -225,35 +318,6 @@ export class TSService {
225318
if (!code) {
226319
return code;
227320
}
228-
// If it's tsconfig, it will take care of rewriting the `include`.
229-
if (normalizedTsconfigPaths.has(normalized)) {
230-
const configJson = ts.parseConfigFileTextToJson(realFileName, code);
231-
if (!configJson.config) {
232-
return code;
233-
}
234-
if (configJson.config.extends) {
235-
// If it references another tsconfig, rewrite the `include` for that file as well.
236-
for (const extendConfigPath of [configJson.config.extends].flat()) {
237-
normalizedTsconfigPaths.add(
238-
normalizeFileName(
239-
toAbsolutePath(extendConfigPath, path.dirname(normalized))
240-
)
241-
);
242-
}
243-
}
244-
245-
if (!configJson.config.include) {
246-
return code;
247-
}
248-
const include = [configJson.config.include]
249-
.flat()
250-
.map((s) => toVirtualTSXFileName(s, extraFileExtensions));
251-
252-
return JSON.stringify({
253-
...configJson.config,
254-
include,
255-
});
256-
}
257321
return transformExtraFile(code, {
258322
filePath: normalized,
259323
current: false,
@@ -377,14 +441,6 @@ function getRefreshTargetFileNames(
377441
return [fileName];
378442
}
379443

380-
/** If the given filename has extra extensions, returns the real virtual filename. */
381-
function toVirtualTSXFileName(fileName: string, extraFileExtensions: string[]) {
382-
if (isExtra(fileName, extraFileExtensions)) {
383-
return `${fileName}.tsx`;
384-
}
385-
return fileName;
386-
}
387-
388444
/** If the given filename has extra extensions, returns the d.ts filename. */
389445
function toExtraDtsFileName(fileName: string, extraFileExtensions: string[]) {
390446
if (isExtra(fileName, extraFileExtensions)) {

0 commit comments

Comments
 (0)