Skip to content

Commit 944f8b8

Browse files
committed
Instead of using system as object on WatchHost, create WatchCompilerHost that combines the functionality
1 parent f046d82 commit 944f8b8

9 files changed

Lines changed: 87 additions & 72 deletions

File tree

src/compiler/core.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,9 +3023,7 @@ namespace ts {
30233023
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
30243024
return {
30253025
useCaseSensitiveFileNames: host.useCaseSensitiveFileNames,
3026-
newLine: host.newLine,
30273026
readFile: (path, encoding) => host.readFile(path, encoding),
3028-
write: s => host.write(s),
30293027
writeFile,
30303028
fileExists,
30313029
directoryExists,

src/compiler/sys.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ namespace ts {
3434
* Partial interface of the System thats needed to support the caching of directory structure
3535
*/
3636
export interface DirectoryStructureHost {
37-
newLine: string;
3837
useCaseSensitiveFileNames: boolean;
39-
write(s: string): void;
4038
readFile(path: string, encoding?: string): string | undefined;
4139
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
4240
fileExists(path: string): boolean;
@@ -49,7 +47,9 @@ namespace ts {
4947
}
5048

5149
export interface System extends DirectoryStructureHost {
50+
newLine: string;
5251
args: string[];
52+
write(s: string): void;
5353
getFileSize?(path: string): number;
5454
/**
5555
* @pollingInterval - this parameter is used in polling-based watchers and ignored in watchers that

src/compiler/tsc.ts

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -150,37 +150,34 @@ namespace ts {
150150
return sys.exit(exitStatus);
151151
}
152152

153-
function createProgramCompilerWithBuilderState() {
154-
const compilerWithBuilderState = ts.createProgramCompilerWithBuilderState(sys, reportDiagnostic);
155-
return (host: DirectoryStructureHost, program: Program) => {
153+
function createWatchCompilerHost(): WatchCompilerHost {
154+
const watchCompilerHost = ts.createWatchCompilerHost(sys, reportDiagnostic);
155+
const compilerWithBuilderState = watchCompilerHost.afterProgramCreate;
156+
watchCompilerHost.beforeProgramCreate = enableStatistics;
157+
watchCompilerHost.afterProgramCreate = (host, program) => {
156158
compilerWithBuilderState(host, program);
157159
reportStatistics(program);
158160
};
161+
return watchCompilerHost;
159162
}
160163

161164
function createWatchOfConfigFile(configParseResult: ParsedCommandLine, optionsToExtend: CompilerOptions) {
162-
createWatch({
163-
system: sys,
164-
beforeProgramCreate: enableStatistics,
165-
afterProgramCreate: createProgramCompilerWithBuilderState(),
166-
onConfigFileDiagnostic: reportDiagnostic,
167-
rootFiles: configParseResult.fileNames,
168-
options: configParseResult.options,
169-
configFileName: configParseResult.options.configFilePath,
170-
optionsToExtend,
171-
configFileSpecs: configParseResult.configFileSpecs,
172-
configFileWildCardDirectories: configParseResult.wildcardDirectories
173-
});
165+
const watchCompilerHost = createWatchCompilerHost() as WatchCompilerHostOfConfigFile;
166+
watchCompilerHost.onConfigFileDiagnostic = reportDiagnostic;
167+
watchCompilerHost.rootFiles = configParseResult.fileNames;
168+
watchCompilerHost.options = configParseResult.options;
169+
watchCompilerHost.configFileName = configParseResult.options.configFilePath;
170+
watchCompilerHost.optionsToExtend = optionsToExtend;
171+
watchCompilerHost.configFileSpecs = configParseResult.configFileSpecs;
172+
watchCompilerHost.configFileWildCardDirectories = configParseResult.wildcardDirectories;
173+
createWatch(watchCompilerHost);
174174
}
175175

176176
function createWatchOfFilesAndCompilerOptions(rootFiles: string[], options: CompilerOptions) {
177-
createWatch({
178-
system: sys,
179-
beforeProgramCreate: enableStatistics,
180-
afterProgramCreate: createProgramCompilerWithBuilderState(),
181-
rootFiles,
182-
options
183-
});
177+
const watchCompilerHost = createWatchCompilerHost() as WatchCompilerHostOfFilesAndCompilerOptions;
178+
watchCompilerHost.rootFiles = rootFiles;
179+
watchCompilerHost.options = options;
180+
createWatch(watchCompilerHost);
184181
}
185182

186183
function compileProgram(program: Program): ExitStatus {

src/compiler/utilities.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3306,14 +3306,14 @@ namespace ts {
33063306

33073307
const carriageReturnLineFeed = "\r\n";
33083308
const lineFeed = "\n";
3309-
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, system?: { newLine: string }): string {
3309+
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, getNewLine?: () => string): string {
33103310
switch (options.newLine) {
33113311
case NewLineKind.CarriageReturnLineFeed:
33123312
return carriageReturnLineFeed;
33133313
case NewLineKind.LineFeed:
33143314
return lineFeed;
33153315
}
3316-
return system ? system.newLine : sys ? sys.newLine : carriageReturnLineFeed;
3316+
return getNewLine ? getNewLine() : sys ? sys.newLine : carriageReturnLineFeed;
33173317
}
33183318

33193319
/**

src/compiler/watch.ts

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ namespace ts {
161161
};
162162
}
163163

164-
export interface WatchHost {
164+
export interface WatchCompilerHost {
165165
/** FS system to use */
166166
system: System;
167167

@@ -170,14 +170,18 @@ namespace ts {
170170
/** If provided, callback to invoke after every new program creation */
171171
afterProgramCreate?(host: DirectoryStructureHost, program: Program): void;
172172

173-
/** Optional module name resolver */
173+
// Sub set of compiler host methods to read and generate new program
174+
useCaseSensitiveFileNames(): boolean;
175+
getNewLine(): string;
176+
177+
/** If provided this function would be used to resolve the module names, otherwise typescript's default module resolution */
174178
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
175179
}
176180

177181
/**
178182
* Host to create watch with root files and options
179183
*/
180-
export interface WatchOfFilesAndCompilerOptionsHost extends WatchHost {
184+
export interface WatchCompilerHostOfFilesAndCompilerOptions extends WatchCompilerHost {
181185
/** root files to use to generate program */
182186
rootFiles: string[];
183187

@@ -188,7 +192,7 @@ namespace ts {
188192
/**
189193
* Host to create watch with config file
190194
*/
191-
export interface WatchOfConfigFileHost extends WatchHost {
195+
export interface WatchCompilerHostOfConfigFile extends WatchCompilerHost {
192196
/** Name of the config file to compile */
193197
configFileName: string;
194198

@@ -199,11 +203,11 @@ namespace ts {
199203
onConfigFileDiagnostic(diagnostic: Diagnostic): void;
200204
}
201205

202-
/*@internal*/
203206
/**
204207
* Host to create watch with config file that is already parsed (from tsc)
205208
*/
206-
export interface WatchOfConfigFileHost extends WatchHost {
209+
/*@internal*/
210+
export interface WatchCompilerHostOfConfigFile extends WatchCompilerHost {
207211
rootFiles?: string[];
208212
options?: CompilerOptions;
209213
optionsToExtend?: CompilerOptions;
@@ -234,39 +238,48 @@ namespace ts {
234238
}
235239

236240
/**
237-
* Create the watched program for config file
241+
* Creates the watch compiler host that can be extended with config file or root file names and options host
238242
*/
239-
export function createWatchOfConfigFile(configFileName: string, optionsToExtend?: CompilerOptions, system = sys, reportDiagnostic?: DiagnosticReporter): WatchOfConfigFile {
240-
return createWatch({
243+
/*@internal*/
244+
export function createWatchCompilerHost(system = sys, reportDiagnostic?: DiagnosticReporter): WatchCompilerHost {
245+
return {
246+
useCaseSensitiveFileNames: () => system.useCaseSensitiveFileNames,
247+
getNewLine: () => system.newLine,
241248
system,
242-
afterProgramCreate: createProgramCompilerWithBuilderState(system, reportDiagnostic),
243-
onConfigFileDiagnostic: reportDiagnostic || createDiagnosticReporter(system),
244-
configFileName,
245-
optionsToExtend
246-
});
249+
afterProgramCreate: createProgramCompilerWithBuilderState(system, reportDiagnostic)
250+
};
251+
}
252+
253+
/**
254+
* Create the watched program for config file
255+
*/
256+
export function createWatchOfConfigFile(configFileName: string, optionsToExtend?: CompilerOptions, system?: System, reportDiagnostic?: DiagnosticReporter): WatchOfConfigFile {
257+
const host = createWatchCompilerHost(system) as WatchCompilerHostOfConfigFile;
258+
host.onConfigFileDiagnostic = reportDiagnostic || createDiagnosticReporter(system);
259+
host.configFileName = configFileName;
260+
host.optionsToExtend = optionsToExtend;
261+
return createWatch(host);
247262
}
248263

249264
/**
250265
* Create the watched program for root files and compiler options
251266
*/
252267
export function createWatchOfFilesAndCompilerOptions(rootFiles: string[], options: CompilerOptions, system = sys, reportDiagnostic?: DiagnosticReporter): WatchOfFilesAndCompilerOptions {
253-
return createWatch({
254-
system,
255-
afterProgramCreate: createProgramCompilerWithBuilderState(system, reportDiagnostic),
256-
rootFiles,
257-
options
258-
});
268+
const host = createWatchCompilerHost(system, reportDiagnostic) as WatchCompilerHostOfFilesAndCompilerOptions;
269+
host.rootFiles = rootFiles;
270+
host.options = options;
271+
return createWatch(host);
259272
}
260273

261274
/**
262275
* Creates the watch from the host for root files and compiler options
263276
*/
264-
export function createWatch(host: WatchOfFilesAndCompilerOptionsHost): WatchOfFilesAndCompilerOptions;
277+
export function createWatch(host: WatchCompilerHostOfFilesAndCompilerOptions): WatchOfFilesAndCompilerOptions;
265278
/**
266279
* Creates the watch from the host for config file
267280
*/
268-
export function createWatch(host: WatchOfConfigFileHost): WatchOfConfigFile;
269-
export function createWatch(host: WatchOfFilesAndCompilerOptionsHost | WatchOfConfigFileHost): WatchOfFilesAndCompilerOptions | WatchOfConfigFile {
281+
export function createWatch(host: WatchCompilerHostOfConfigFile): WatchOfConfigFile;
282+
export function createWatch(host: WatchCompilerHostOfFilesAndCompilerOptions | WatchCompilerHostOfConfigFile): WatchOfFilesAndCompilerOptions | WatchOfConfigFile {
270283
interface HostFileInfo {
271284
version: number;
272285
sourceFile: SourceFile;
@@ -284,10 +297,10 @@ namespace ts {
284297
let hasChangedCompilerOptions = false; // True if the compiler options have changed between compilations
285298
let hasChangedAutomaticTypeDirectiveNames = false; // True if the automatic type directives have changed
286299

287-
const { system, configFileName, onConfigFileDiagnostic, optionsToExtend: optionsToExtendForConfigFile = {} } = host as WatchOfConfigFileHost;
288-
const beforeProgramCreate: WatchHost["beforeProgramCreate"] = host.beforeProgramCreate ? host.beforeProgramCreate.bind(host) : noop;
289-
const afterProgramCreate: WatchHost["afterProgramCreate"] = host.afterProgramCreate ? host.afterProgramCreate.bind(host) : noop;
290-
let { rootFiles: rootFileNames, options: compilerOptions, configFileSpecs, configFileWildCardDirectories } = host as WatchOfConfigFileHost;
300+
const { system, configFileName, onConfigFileDiagnostic, optionsToExtend: optionsToExtendForConfigFile = {} } = host as WatchCompilerHostOfConfigFile;
301+
const beforeProgramCreate: WatchCompilerHost["beforeProgramCreate"] = host.beforeProgramCreate ? host.beforeProgramCreate.bind(host) : noop;
302+
const afterProgramCreate: WatchCompilerHost["afterProgramCreate"] = host.afterProgramCreate ? host.afterProgramCreate.bind(host) : noop;
303+
let { rootFiles: rootFileNames, options: compilerOptions, configFileSpecs, configFileWildCardDirectories } = host as WatchCompilerHostOfConfigFile;
291304

292305
// From tsc we want to get already parsed result and hence check for rootFileNames
293306
const directoryStructureHost = configFileName ? createCachedDirectoryStructureHost(system) : system;
@@ -296,7 +309,7 @@ namespace ts {
296309
}
297310

298311
const loggingEnabled = compilerOptions.diagnostics || compilerOptions.extendedDiagnostics;
299-
const writeLog: (s: string) => void = loggingEnabled ? s => { system.write(s); system.write(system.newLine); } : noop;
312+
const writeLog: (s: string) => void = loggingEnabled ? s => { system.write(s); system.write(newLine); } : noop;
300313
const watchFile = compilerOptions.extendedDiagnostics ? ts.addFileWatcherWithLogging : loggingEnabled ? ts.addFileWatcherWithOnlyTriggerLogging : ts.addFileWatcher;
301314
const watchFilePath = compilerOptions.extendedDiagnostics ? ts.addFilePathWatcherWithLogging : ts.addFilePathWatcher;
302315
const watchDirectoryWorker = compilerOptions.extendedDiagnostics ? ts.addDirectoryWatcherWithLogging : ts.addDirectoryWatcher;
@@ -308,8 +321,9 @@ namespace ts {
308321
const getCurrentDirectory = memoize(() => directoryStructureHost.getCurrentDirectory());
309322
const realpath = system.realpath && ((path: string) => system.realpath(path));
310323
const getCachedDirectoryStructureHost = configFileName && (() => directoryStructureHost as CachedDirectoryStructureHost);
311-
const getCanonicalFileName = createGetCanonicalFileName(system.useCaseSensitiveFileNames);
312-
let newLine = getNewLineCharacter(compilerOptions, system);
324+
const useCaseSensitiveFileNames = memoize(() => host.useCaseSensitiveFileNames());
325+
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames());
326+
let newLine = updateNewLine();
313327

314328
const compilerHost: CompilerHost & ResolutionCacheHost = {
315329
// Members for CompilerHost
@@ -319,7 +333,7 @@ namespace ts {
319333
getDefaultLibFileName: options => combinePaths(getDefaultLibLocation(), getDefaultLibFileName(options)),
320334
writeFile: notImplemented,
321335
getCurrentDirectory,
322-
useCaseSensitiveFileNames: () => system.useCaseSensitiveFileNames,
336+
useCaseSensitiveFileNames,
323337
getCanonicalFileName,
324338
getNewLine: () => newLine,
325339
fileExists,
@@ -370,7 +384,7 @@ namespace ts {
370384
writeLog(`Synchronizing program`);
371385

372386
if (hasChangedCompilerOptions) {
373-
newLine = getNewLineCharacter(compilerOptions, system);
387+
newLine = updateNewLine();
374388
if (program && changesAffectModuleResolution(program.getCompilerOptions(), compilerOptions)) {
375389
resolutionCache.clear();
376390
}
@@ -423,6 +437,10 @@ namespace ts {
423437
scheduleProgramUpdate();
424438
}
425439

440+
function updateNewLine() {
441+
return getNewLineCharacter(compilerOptions, () => host.getNewLine());
442+
}
443+
426444
function toPath(fileName: string) {
427445
return ts.toPath(fileName, getCurrentDirectory(), getCanonicalFileName);
428446
}

src/server/project.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ namespace ts.server {
266266
}
267267

268268
getNewLine() {
269-
return this.directoryStructureHost.newLine;
269+
return this.projectService.host.newLine;
270270
}
271271

272272
getProjectVersion() {

src/services/services.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,7 @@ namespace ts {
12551255
getCancellationToken: () => cancellationToken,
12561256
getCanonicalFileName,
12571257
useCaseSensitiveFileNames: () => useCaseSensitivefileNames,
1258-
getNewLine: () => getNewLineCharacter(newSettings, { newLine: getNewLineOrDefaultFromHost(host) }),
1258+
getNewLine: () => getNewLineCharacter(newSettings, () => getNewLineOrDefaultFromHost(host)),
12591259
getDefaultLibFileName: (options) => host.getDefaultLibFileName(options),
12601260
writeFile: noop,
12611261
getCurrentDirectory: () => currentDirectory,

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2729,9 +2729,7 @@ declare namespace ts {
27292729
* Partial interface of the System thats needed to support the caching of directory structure
27302730
*/
27312731
interface DirectoryStructureHost {
2732-
newLine: string;
27332732
useCaseSensitiveFileNames: boolean;
2734-
write(s: string): void;
27352733
readFile(path: string, encoding?: string): string | undefined;
27362734
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
27372735
fileExists(path: string): boolean;
@@ -2743,7 +2741,9 @@ declare namespace ts {
27432741
exit(exitCode?: number): void;
27442742
}
27452743
interface System extends DirectoryStructureHost {
2744+
newLine: string;
27462745
args: string[];
2746+
write(s: string): void;
27472747
getFileSize?(path: string): number;
27482748
/**
27492749
* @pollingInterval - this parameter is used in polling-based watchers and ignored in watchers that

0 commit comments

Comments
 (0)