diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 6a697b9c180..0be96b7d55f 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -103,31 +103,20 @@ namespace ts { return false; } - function ensureDirectoriesExist(directoryPath: string) { - if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) { - const parentDirectory = getDirectoryPath(directoryPath); - ensureDirectoriesExist(parentDirectory); - (compilerHost.createDirectory || system.createDirectory)(directoryPath); - } - } - function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) { try { performance.mark("beforeIOWrite"); - // PERF: Checking for directory existence is expensive. - // Instead, assume the directory exists and fall back - // to creating it if the file write fails. // NOTE: If patchWriteFileEnsuringDirectory has been called, - // the file write will do its own directory creation and + // the system.writeFile will do its own directory creation and // the ensureDirectoriesExist call will always be redundant. - try { - writeFileWorker(fileName, data, writeByteOrderMark); - } - catch { - ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName))); - writeFileWorker(fileName, data, writeByteOrderMark); - } + writeFileEnsuringDirectories( + fileName, + data, + writeByteOrderMark, + writeFileWorker, + compilerHost.createDirectory || system.createDirectory, + directoryExists); performance.mark("afterIOWrite"); performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite"); diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index c4a5012b265..9de6193d734 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -522,17 +522,6 @@ namespace ts { } } - function recursiveCreateDirectory(directoryPath: string, sys: System) { - const basePath = getDirectoryPath(directoryPath); - const shouldCreateParent = basePath !== "" && directoryPath !== basePath && !sys.directoryExists(basePath); - if (shouldCreateParent) { - recursiveCreateDirectory(basePath, sys); - } - if (shouldCreateParent || !sys.directoryExists(directoryPath)) { - sys.createDirectory(directoryPath); - } - } - /** * patch writefile to create folder before writing the file */ @@ -540,22 +529,14 @@ namespace ts { export function patchWriteFileEnsuringDirectory(sys: System) { // patch writefile to create folder before writing the file const originalWriteFile = sys.writeFile; - sys.writeFile = (path, data, writeBom) => { - // PERF: Checking for directory existence is expensive. - // Instead, assume the directory exists and fall back - // to creating it if the file write fails. - try { - originalWriteFile.call(sys, path, data, writeBom); - } - catch { - const directoryPath = getDirectoryPath(normalizeSlashes(path)); - if (directoryPath && !sys.directoryExists(directoryPath)) { - recursiveCreateDirectory(directoryPath, sys); - } - - originalWriteFile.call(sys, path, data, writeBom); - } - }; + sys.writeFile = (path, data, writeBom) => + writeFileEnsuringDirectories( + path, + data, + writeBom, + (p, d, w) => originalWriteFile.call(sys, p, d, w), + sys.createDirectory, + sys.directoryExists); } /*@internal*/ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 2fb1173deef..8f7602cbe2a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3700,6 +3700,36 @@ namespace ts { }, sourceFiles); } + function ensureDirectoriesExist( + directoryPath: string, + createDirectory: (path: string) => void, + directoryExists: (path: string) => boolean): void { + if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) { + const parentDirectory = getDirectoryPath(directoryPath); + ensureDirectoriesExist(parentDirectory, createDirectory, directoryExists); + createDirectory(directoryPath); + } + } + + export function writeFileEnsuringDirectories( + path: string, + data: string, + writeByteOrderMark: boolean | undefined, + writeFile: (path: string, data: string, writeByteOrderMark?: boolean) => void, + createDirectory: (path: string) => void, + directoryExists: (path: string) => boolean): void { + + // PERF: Checking for directory existence is expensive. Instead, assume the directory exists + // and fall back to creating it if the file write fails. + try { + writeFile(path, data, writeByteOrderMark); + } + catch { + ensureDirectoriesExist(getDirectoryPath(normalizePath(path)), createDirectory, directoryExists); + writeFile(path, data, writeByteOrderMark); + } + } + export function getLineOfLocalPosition(currentSourceFile: SourceFile, pos: number) { return getLineAndCharacterOfPosition(currentSourceFile, pos).line; } diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index f6e334aa47a..cc6bd0bcced 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -296,31 +296,14 @@ namespace ts { readDirectory: maybeBind(host, host.readDirectory), }; - function ensureDirectoriesExist(directoryPath: string) { - if (directoryPath.length > getRootLength(directoryPath) && !host.directoryExists!(directoryPath)) { - const parentDirectory = getDirectoryPath(directoryPath); - ensureDirectoriesExist(parentDirectory); - if (host.createDirectory) host.createDirectory(directoryPath); - } - } - function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, onError: (message: string) => void) { try { performance.mark("beforeIOWrite"); - // PERF: Checking for directory existence is expensive. - // Instead, assume the directory exists and fall back - // to creating it if the file write fails. // NOTE: If patchWriteFileEnsuringDirectory has been called, - // the file write will do its own directory creation and + // the host.writeFile will do its own directory creation and // the ensureDirectoriesExist call will always be redundant. - try { - host.writeFile!(fileName, text, writeByteOrderMark); - } - catch { - ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName))); - host.writeFile!(fileName, text, writeByteOrderMark); - } + writeFileEnsuringDirectories(fileName, text, writeByteOrderMark, host.writeFile!, host.createDirectory!, host.directoryExists!); performance.mark("afterIOWrite"); performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");