diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index f119481ac08..76a93afc478 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -206,51 +206,6 @@ namespace ts { type ResolvedConfigFilePath = ResolvedConfigFileName & Path; - /** - * A FileMap maintains a normalized-key to value relationship - */ - function createFileMap(toPath: (fileName: ResolvedConfigFileName) => ResolvedConfigFilePath): ConfigFileMap { - // tslint:disable-next-line:no-null-keyword - const lookup = createMap(); - - return { - setValue, - getValue, - removeKey, - forEach, - hasKey, - getSize, - clear - }; - - function forEach(action: (value: T, key: ResolvedConfigFilePath) => void) { - lookup.forEach(action); - } - - function hasKey(fileName: ResolvedConfigFileName) { - return lookup.has(toPath(fileName)); - } - - function removeKey(fileName: ResolvedConfigFileName) { - lookup.delete(toPath(fileName)); - } - - function setValue(fileName: ResolvedConfigFileName, value: T) { - lookup.set(toPath(fileName), value); - } - - function getValue(fileName: ResolvedConfigFileName): T | undefined { - return lookup.get(toPath(fileName)); - } - - function getSize() { - return lookup.size; - } - - function clear() { - lookup.clear(); - } - } function getOrCreateValueFromConfigFileMap(configFileMap: ConfigFileMap, resolved: ResolvedConfigFileName, createT: () => T): T { const existingValue = configFileMap.getValue(resolved); @@ -378,10 +333,11 @@ namespace ts { // State of the solution let options = defaultOptions; let baseCompilerOptions = getCompilerOptionsOfBuildOptions(options); + const resolvedConfigFilePaths = createMap(); type ConfigFileCacheEntry = ParsedCommandLine | Diagnostic; - const configFileCache = createFileMap(toPath); + const configFileCache = createFileMap(); /** Map from config file name to up-to-date status */ - const projectStatus = createFileMap(toPath); + const projectStatus = createFileMap(); let buildOrder: readonly ResolvedConfigFileName[] | undefined; const writeFileName = host.trace ? (s: string) => host.trace!(s) : undefined; let readFileWithCache = (f: string) => host.readFile(f); @@ -393,21 +349,21 @@ namespace ts { compilerHost.resolveTypeReferenceDirectives = maybeBind(host, host.resolveTypeReferenceDirectives); let moduleResolutionCache = !compilerHost.resolveModuleNames ? createModuleResolutionCache(currentDirectory, getCanonicalFileName) : undefined; - const buildInfoChecked = createFileMap(toPath); + const buildInfoChecked = createFileMap(); // Watch state - const builderPrograms = createFileMap(toPath); - const diagnostics = createFileMap>(toPath); - const projectPendingBuild = createFileMap(toPath); - const projectErrorsReported = createFileMap(toPath); + const builderPrograms = createFileMap(); + const diagnostics = createFileMap>(); + const projectPendingBuild = createFileMap(); + const projectErrorsReported = createFileMap(); let timerToBuildInvalidatedProject: any; let reportFileChangeDetected = false; const { watchFile, watchFilePath, watchDirectory, writeLog } = createWatchFactory(host, options); // Watches for the solution - const allWatchedWildcardDirectories = createFileMap>(toPath); - const allWatchedInputFiles = createFileMap>(toPath); - const allWatchedConfigFiles = createFileMap(toPath); + const allWatchedWildcardDirectories = createFileMap>(); + const allWatchedInputFiles = createFileMap>(); + const allWatchedConfigFiles = createFileMap(); return { buildAllProjects, @@ -423,15 +379,67 @@ namespace ts { startWatching }; - function toPath(fileName: ResolvedConfigFileName): ResolvedConfigFilePath; - function toPath(fileName: string): Path; function toPath(fileName: string) { return ts.toPath(fileName, currentDirectory, getCanonicalFileName); } + function toResolvedConfigFilePath(fileName: ResolvedConfigFileName): ResolvedConfigFilePath { + const path = resolvedConfigFilePaths.get(fileName); + if (path !== undefined) return path; + + const resolvedPath = toPath(fileName) as ResolvedConfigFilePath; + resolvedConfigFilePaths.set(fileName, resolvedPath); + return resolvedPath; + } + + + // TODO remove this and use normal map so we arent transforming paths constantly + function createFileMap(): ConfigFileMap { + const lookup = createMap(); + return { + setValue, + getValue, + removeKey, + forEach, + hasKey, + getSize, + clear + }; + + function forEach(action: (value: T, key: ResolvedConfigFilePath) => void) { + lookup.forEach(action); + } + + function hasKey(fileName: ResolvedConfigFileName) { + return lookup.has(toResolvedConfigFilePath(fileName)); + } + + function removeKey(fileName: ResolvedConfigFileName) { + lookup.delete(toResolvedConfigFilePath(fileName)); + } + + function setValue(fileName: ResolvedConfigFileName, value: T) { + lookup.set(toResolvedConfigFilePath(fileName), value); + } + + function getValue(fileName: ResolvedConfigFileName): T | undefined { + return lookup.get(toResolvedConfigFilePath(fileName)); + } + + function getSize() { + return lookup.size; + } + + function clear() { + lookup.clear(); + } + } + + function resetBuildContext(opts = defaultOptions) { options = opts; baseCompilerOptions = getCompilerOptionsOfBuildOptions(options); + resolvedConfigFilePaths.clear(); configFileCache.clear(); projectStatus.clear(); buildOrder = undefined; @@ -998,8 +1006,8 @@ namespace ts { } function createBuildOrder(roots: readonly ResolvedConfigFileName[]): readonly ResolvedConfigFileName[] { - const temporaryMarks = createFileMap(toPath); - const permanentMarks = createFileMap(toPath); + const temporaryMarks = createFileMap(); + const permanentMarks = createFileMap(); const circularityReportStack: string[] = []; let buildOrder: ResolvedConfigFileName[] | undefined; for (const root of roots) {