Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,31 @@ module ts {

export function mapToArray<T>(map: Map<T>): 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<T>(array: T[], makeKey: (value: T) => string): Map<T> {
var result: Map<T> = {};

forEach(array, value => {
result[makeKey(value)] = value
});

return result;
}

Expand Down
27 changes: 16 additions & 11 deletions src/compiler/tc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,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();
}
Expand All @@ -257,8 +257,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.
Expand All @@ -278,20 +277,22 @@ 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'
// will try to reuse the SourceFiles from the last compilation cycle
// 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);
Expand All @@ -301,6 +302,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) {
Expand Down