diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 4c2f6258ddf..b5803932c4e 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -900,7 +900,7 @@ namespace ts { /** * Computing hash to for signature verification */ - const computeHash = host.createHash || generateDjb2Hash; + const computeHash = maybeBind(host, host.createHash); let state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState); let backupState: BuilderProgramState | undefined; newProgram.getProgramBuildInfo = () => getProgramBuildInfo(state, getCanonicalFileName); diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index 69b3f2558e5..72c5c37b233 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -77,7 +77,7 @@ namespace ts { /** * Compute the hash to store the shape of the file */ - export type ComputeHash = (data: string) => string; + export type ComputeHash = ((data: string) => string) | undefined; /** * Exported modules to from declaration emit being computed. @@ -337,7 +337,7 @@ namespace ts { emitOutput.outputFiles.length > 0 ? emitOutput.outputFiles[0] : undefined; if (firstDts) { Debug.assert(fileExtensionIs(firstDts.name, Extension.Dts), "File extension for signature expected to be dts", () => `Found: ${getAnyExtensionFromPath(firstDts.name)} for ${firstDts.name}:: All output files: ${JSON.stringify(emitOutput.outputFiles.map(f => f.name))}`); - latestSignature = computeHash(firstDts.text); + latestSignature = (computeHash || generateDjb2Hash)(firstDts.text); if (exportedModulesMapCache && latestSignature !== prevSignature) { updateExportedModules(sourceFile, emitOutput.exportedModulesFromDeclarationEmit, exportedModulesMapCache); } @@ -521,7 +521,7 @@ namespace ts { /** * When program emits modular code, gets the files affected by the sourceFile whose shape has changed */ - function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile, cacheToUpdateSignature: ESMap, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash | undefined, exportedModulesMapCache: ComputingExportedModulesMap | undefined) { + function getFilesAffectedByUpdatedShapeWhenModuleEmit(state: BuilderState, programOfThisState: Program, sourceFileWithUpdatedShape: SourceFile, cacheToUpdateSignature: ESMap, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache: ComputingExportedModulesMap | undefined) { if (isFileAffectingGlobalScope(sourceFileWithUpdatedShape)) { return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape); } @@ -544,7 +544,7 @@ namespace ts { if (!seenFileNamesMap.has(currentPath)) { const currentSourceFile = programOfThisState.getSourceFileByPath(currentPath)!; seenFileNamesMap.set(currentPath, currentSourceFile); - if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash!, exportedModulesMapCache)) { // TODO: GH#18217 + if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash, exportedModulesMapCache)) { queue.push(...getReferencedByPaths(state, currentSourceFile.resolvedPath)); } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 76fa4b62aab..70ea81c35d5 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -73,6 +73,7 @@ namespace ts { export function createCompilerHostWorker(options: CompilerOptions, setParentNodes?: boolean, system = sys): CompilerHost { const existingDirectories = new Map(); const getCanonicalFileName = createGetCanonicalFileName(system.useCaseSensitiveFileNames); + const computeHash = maybeBind(system, system.createHash) || generateDjb2Hash; function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile | undefined { let text: string | undefined; try { @@ -128,7 +129,7 @@ namespace ts { let outputFingerprints: ESMap; function writeFileWorker(fileName: string, data: string, writeByteOrderMark: boolean) { - if (!isWatchSet(options) || !system.createHash || !system.getModifiedTime) { + if (!isWatchSet(options) || !system.getModifiedTime) { system.writeFile(fileName, data, writeByteOrderMark); return; } @@ -137,7 +138,7 @@ namespace ts { outputFingerprints = new Map(); } - const hash = system.createHash(data); + const hash = computeHash(data); const mtimeBefore = system.getModifiedTime(fileName); if (mtimeBefore) { diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 724d57f48b2..422dc13ab22 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -345,11 +345,11 @@ namespace ts { export function setGetSourceFileAsHashVersioned(compilerHost: CompilerHost, host: { createHash?(data: string): string; }) { const originalGetSourceFile = compilerHost.getSourceFile; - const computeHash = host.createHash || generateDjb2Hash; + const computeHash = maybeBind(host, host.createHash) || generateDjb2Hash; compilerHost.getSourceFile = (...args) => { const result = originalGetSourceFile.call(compilerHost, ...args); if (result) { - result.version = computeHash.call(host, result.text); + result.version = computeHash(result.text); } return result; }; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index d0b4891c963..9c8c198e1b2 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -730,7 +730,6 @@ namespace ts.server { this.syntaxOnly = false; } - Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService"); if (this.host.realpath) { this.realpathToScriptInfos = createMultiMap(); } diff --git a/src/server/project.ts b/src/server/project.ts index e3720383543..e7bb3c857d3 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -631,8 +631,16 @@ namespace ts.server { } updateProjectIfDirty(this); this.builderState = BuilderState.create(this.program!, this.projectService.toCanonicalFileName, this.builderState); - return mapDefined(BuilderState.getFilesAffectedBy(this.builderState, this.program!, scriptInfo.path, this.cancellationToken, data => this.projectService.host.createHash!(data)), // TODO: GH#18217 - sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : undefined); + return mapDefined( + BuilderState.getFilesAffectedBy( + this.builderState, + this.program!, + scriptInfo.path, + this.cancellationToken, + maybeBind(this.projectService.host, this.projectService.host.createHash) + ), + sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : undefined + ); } /** @@ -654,7 +662,10 @@ namespace ts.server { const dtsFiles = outputFiles.filter(f => fileExtensionIs(f.name, Extension.Dts)); if (dtsFiles.length === 1) { const sourceFile = this.program!.getSourceFile(scriptInfo.fileName)!; - BuilderState.updateSignatureOfFile(this.builderState, this.projectService.host.createHash!(dtsFiles[0].text), sourceFile.resolvedPath); + const signature = this.projectService.host.createHash ? + this.projectService.host.createHash(dtsFiles[0].text) : + generateDjb2Hash(dtsFiles[0].text); + BuilderState.updateSignatureOfFile(this.builderState, signature, sourceFile.resolvedPath); } } }