diff --git a/src/compiler/core.ts b/src/compiler/core.ts index c492ab9c43..58cf33c6fd 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -152,7 +152,31 @@ module ts { export function mapToArray(map: Map): T[] { var result: T[] = []; - for (var id in map) result.push(map[id]); + + for (var id in map) { + result.push(map[id]); + } + + return result; + } + + /** + * Creates a map from the elements of an array. + * + * @param array the array of input elements. + * @param makeKey a function that produces a key for a given element. + * + * This function makes no effort to avoid collisions; if any two elements produce + * the same key with the given 'makeKey' function, then the element with the higher + * index in the array will be the one associated with the produced key. + */ + export function arrayToMap(array: T[], makeKey: (value: T) => string): Map { + var result: Map = {}; + + forEach(array, value => { + result[makeKey(value)] = value + }); + return result; } diff --git a/src/compiler/tc.ts b/src/compiler/tc.ts index 5009e4c7a9..9c77211525 100644 --- a/src/compiler/tc.ts +++ b/src/compiler/tc.ts @@ -245,14 +245,14 @@ module ts { function addWatchers(program: Program) { forEach(program.getSourceFiles(), f => { - var filename = f.filename; + var filename = getCanonicalName(f.filename); watchers[filename] = sys.watchFile(filename, fileUpdated); }); } function removeWatchers(program: Program) { forEach(program.getSourceFiles(), f => { - var filename = f.filename; + var filename = getCanonicalName(f.filename); if (hasProperty(watchers, filename)) { watchers[filename].close(); } @@ -264,8 +264,7 @@ module ts { // Fired off whenever a file is changed. function fileUpdated(filename: string) { var firstNotification = isEmpty(updatedFiles); - - updatedFiles[filename] = true; + updatedFiles[getCanonicalName(filename)] = true; // Only start this off when the first file change comes in, // so that we can batch up all further changes. @@ -285,8 +284,10 @@ module ts { // specified since the last compilation cycle. removeWatchers(program); - // Gets us syntactically correct files from the last compilation. - var getUnmodifiedSourceFile = program.getSourceFile; + // Reuse source files from the last compilation so long as they weren't changed. + var oldSourceFiles = arrayToMap( + filter(program.getSourceFiles(), file => !hasProperty(changedFiles, getCanonicalName(file.filename))), + file => getCanonicalName(file.filename)); // We create a new compiler host for this compilation cycle. // This new host is effectively the same except that 'getSourceFile' @@ -294,11 +295,11 @@ module ts { // so long as they were not modified. var newCompilerHost = clone(compilerHost); newCompilerHost.getSourceFile = (fileName, languageVersion, onError) => { - if (!hasProperty(changedFiles, fileName)) { - var sourceFile = getUnmodifiedSourceFile(fileName); - if (sourceFile) { - return sourceFile; - } + fileName = getCanonicalName(fileName); + + var sourceFile = lookUp(oldSourceFiles, fileName); + if (sourceFile) { + return sourceFile; } return compilerHost.getSourceFile(fileName, languageVersion, onError); @@ -308,6 +309,10 @@ module ts { reportDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes)); addWatchers(program); } + + function getCanonicalName(fileName: string) { + return compilerHost.getCanonicalFileName(fileName); + } } function compile(commandLine: ParsedCommandLine, compilerHost: CompilerHost) {