Skip to content

Commit d32cf83

Browse files
authored
refactor: simplify hosts to directly assign tsModule.sys where possible (ezolenko#349)
- no need to duplicate types this way, which can and have changed over time -- it's always the same typings this way - also reorganize `host.ts` to have similar categories of functions near each other, instead of a mix of functions wherever - similar to how I organized the tests for `host` as well - shrink the code a bit this way too - add a comment about `getDefaultLibFileName`'s confusing naming pointing to the TS issues about how this is an old mistake but changing it now would be breaking - this is also how the TS Wiki recommends setting up hosts: https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API#incremental-build-support-using-the-language-services - NOTE: because of how `tsproxy` works to support alternate TS implementations, this does require that `tsModule` _exists_ at the time of instantiation, i.e. that `setTypescriptModule` has already been called - for `host.ts`, `LanguageServiceHost` is only instantiated after `setTypescriptModule`, but for `diagnostics-format-host.ts`, it is immediately instantiated (at the bottom of the file), hence why `getCurrentDirectory` can't just be assigned to `tsModule.sys` - there is a way to fix this, but the refactoring is more complex as it would require creating in `index.ts` and then passing it as an argument -- would want to refactor more at that point too, so leaving that out for now in this otherwise small, isolated refactor - for a different, but related reason, the `host.trace` tests have to mock `console` instead of just `console.log`, since `trace` would just be set to the old, unmocked `console.log` otherwise - as it's assigned directly to `console.log` now
1 parent d9fc987 commit d32cf83

File tree

3 files changed

+24
-75
lines changed

3 files changed

+24
-75
lines changed

__tests__/host.spec.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import { LanguageServiceHost } from "../src/host";
99

1010
setTypescriptModule(ts);
1111

12+
// mock for host.trace
13+
(global as any).console = {
14+
log: jest.fn(),
15+
};
16+
1217
const defaultConfig = { fileNames: [], errors: [], options: {} };
1318

1419
const unaryFunc = "const unary = (x: string): string => x.reverse()";
@@ -72,7 +77,6 @@ test("LanguageServiceHost", async () => {
7277
expect(host.getTypeRootsVersion()).toEqual(0);
7378

7479
// mock out trace
75-
console.log = jest.fn();
7680
host.trace('test log');
7781
expect(console.log).toHaveBeenCalledWith('test log');
7882
});

src/diagnostics-format-host.ts

+2-9
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,8 @@ export class FormatHost implements tsTypes.FormatDiagnosticsHost
1010
return tsModule.sys.getCurrentDirectory();
1111
}
1212

13-
public getCanonicalFileName(fileName: string): string
14-
{
15-
return path.normalize(fileName);
16-
}
17-
18-
public getNewLine(): string
19-
{
20-
return tsModule.sys.newLine;
21-
}
13+
public getCanonicalFileName = path.normalize;
14+
public getNewLine = () => tsModule.sys.newLine;
2215
}
2316

2417
export const formatHost = new FormatHost();

src/host.ts

+17-65
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@ import { TransformerFactoryCreator } from "./ioptions";
66

77
export class LanguageServiceHost implements tsTypes.LanguageServiceHost
88
{
9-
private cwd: string;
109
private snapshots: { [fileName: string]: tsTypes.IScriptSnapshot } = {};
1110
private versions: { [fileName: string]: number } = {};
1211
private service?: tsTypes.LanguageService;
1312
private fileNames: Set<string>;
1413

15-
constructor(private parsedConfig: tsTypes.ParsedCommandLine, private transformers: TransformerFactoryCreator[], cwd: string)
14+
constructor(private parsedConfig: tsTypes.ParsedCommandLine, private transformers: TransformerFactoryCreator[], private cwd: string)
1615
{
1716
this.fileNames = new Set(parsedConfig.fileNames);
18-
this.cwd = cwd;
1917
}
2018

2119
public reset()
@@ -58,10 +56,7 @@ export class LanguageServiceHost implements tsTypes.LanguageServiceHost
5856
return undefined;
5957
}
6058

61-
public getCurrentDirectory()
62-
{
63-
return this.cwd;
64-
}
59+
public getScriptFileNames = () => Array.from(this.fileNames.values());
6560

6661
public getScriptVersion(fileName: string)
6762
{
@@ -70,61 +65,6 @@ export class LanguageServiceHost implements tsTypes.LanguageServiceHost
7065
return (this.versions[fileName] || 0).toString();
7166
}
7267

73-
public getScriptFileNames()
74-
{
75-
return Array.from(this.fileNames.values());
76-
}
77-
78-
public getCompilationSettings(): tsTypes.CompilerOptions
79-
{
80-
return this.parsedConfig.options;
81-
}
82-
83-
public getDefaultLibFileName(opts: tsTypes.CompilerOptions)
84-
{
85-
return tsModule.getDefaultLibFilePath(opts);
86-
}
87-
88-
public useCaseSensitiveFileNames(): boolean
89-
{
90-
return tsModule.sys.useCaseSensitiveFileNames;
91-
}
92-
93-
public readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[]
94-
{
95-
return tsModule.sys.readDirectory(path, extensions, exclude, include);
96-
}
97-
98-
public readFile(path: string, encoding?: string): string | undefined
99-
{
100-
return tsModule.sys.readFile(path, encoding);
101-
}
102-
103-
public fileExists(path: string): boolean
104-
{
105-
return tsModule.sys.fileExists(path);
106-
}
107-
108-
public realpath(path: string): string
109-
{
110-
return tsModule.sys.realpath!(path); // this exists in the default implementation: https://github.com/microsoft/TypeScript/blob/ab2523bbe0352d4486f67b73473d2143ad64d03d/src/compiler/sys.ts#L1288
111-
}
112-
113-
public getTypeRootsVersion(): number
114-
{
115-
return 0;
116-
}
117-
118-
public directoryExists(directoryName: string): boolean
119-
{
120-
return tsModule.sys.directoryExists(directoryName);
121-
}
122-
123-
public getDirectories(directoryName: string): string[]
124-
{
125-
return tsModule.sys.getDirectories(directoryName);
126-
}
127-
12868
public getCustomTransformers(): tsTypes.CustomTransformers | undefined
12969
{
13070
if (this.service === undefined || this.transformers === undefined || this.transformers.length === 0)
@@ -151,7 +91,19 @@ export class LanguageServiceHost implements tsTypes.LanguageServiceHost
15191
return transformer;
15292
}
15393

154-
public trace(line: string) {
155-
console.log(line)
156-
}
94+
public getCompilationSettings = () => this.parsedConfig.options;
95+
public getTypeRootsVersion = () => 0;
96+
public getCurrentDirectory = () => this.cwd;
97+
98+
public useCaseSensitiveFileNames = () => tsModule.sys.useCaseSensitiveFileNames;
99+
public getDefaultLibFileName = tsModule.getDefaultLibFilePath; // confusing naming: https://github.com/microsoft/TypeScript/issues/35318
100+
101+
public readDirectory = tsModule.sys.readDirectory;
102+
public readFile = tsModule.sys.readFile;
103+
public fileExists = tsModule.sys.fileExists;
104+
public directoryExists = tsModule.sys.directoryExists;
105+
public getDirectories = tsModule.sys.getDirectories;
106+
public realpath = tsModule.sys.realpath!; // this exists in the default implementation: https://github.com/microsoft/TypeScript/blob/ab2523bbe0352d4486f67b73473d2143ad64d03d/src/compiler/sys.ts#L1288
107+
108+
public trace = console.log;
157109
}

0 commit comments

Comments
 (0)