Fixed memory leak from '--watch' flag.

As I initially feared, we were actually nesting closure environments with each new `getSourceFile`.

Fixes #366.
This commit is contained in:
Daniel Rosenwasser 2014-08-05 18:27:04 -07:00
parent afeabe8100
commit 6f563b7af9
2 changed files with 22 additions and 6 deletions

View file

@ -156,6 +156,14 @@ module ts {
return result;
}
export function arrayToMap<T>(array: T[], f: (value: T) => string): Map<T> {
var result: Map<T> = {};
forEach(array, value => { result[f(value)] = value });
return result;
}
function formatStringFromArgs(text: string, args: { [index: number]: any; }, baseIndex?: number): string {
baseIndex = baseIndex || 0;

View file

@ -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();
}
@ -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.
@ -279,7 +278,10 @@ module ts {
removeWatchers(program);
// Gets us syntactically correct files from the last compilation.
var getUnmodifiedSourceFile = program.getSourceFile;
var oldSourceFiles = arrayToMap(program.getSourceFiles(), file => getCanonicalName(file.filename));
// No longer using the old program.
program = undefined;
// We create a new compiler host for this compilation cycle.
// This new host is effectively the same except that 'getSourceFile'
@ -287,8 +289,10 @@ module ts {
// so long as they were not modified.
var newCompilerHost = clone(compilerHost);
newCompilerHost.getSourceFile = (fileName, languageVersion, onError) => {
fileName = getCanonicalName(fileName);
if (!hasProperty(changedFiles, fileName)) {
var sourceFile = getUnmodifiedSourceFile(fileName);
var sourceFile = lookUp(oldSourceFiles, fileName);
if (sourceFile) {
return sourceFile;
}
@ -301,6 +305,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) {