Skip to content

Fix issue https://github.com/Microsoft/TypeScript/issues/3277 #3780

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 1, 2015
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
11 changes: 8 additions & 3 deletions src/compiler/sys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace ts {
write(s: string): void;
readFile(path: string, encoding?: string): string;
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
watchFile?(path: string, callback: (path: string) => void): FileWatcher;
watchFile?(path: string, callback: (path: string, removed: boolean) => void): FileWatcher;
resolvePath(path: string): string;
fileExists(path: string): boolean;
directoryExists(path: string): boolean;
Expand Down Expand Up @@ -282,11 +282,16 @@ namespace ts {
};

function fileChanged(curr: any, prev: any) {
// mtime.getTime() equals 0 if file was removed
if (curr.mtime.getTime() === 0) {
callback(fileName, /* removed */ true);
return;
}
if (+curr.mtime <= +prev.mtime) {
return;
}

callback(fileName);
callback(fileName, /* removed */ false);
};
},
resolvePath: function (path: string): string {
Expand Down Expand Up @@ -331,4 +336,4 @@ namespace ts {
return undefined; // Unsupported host
}
})();
}
}
16 changes: 11 additions & 5 deletions src/compiler/tsc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ namespace ts {

function reportDiagnostic(diagnostic: Diagnostic) {
var output = "";

if (diagnostic.file) {
var loc = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);

Expand Down Expand Up @@ -257,7 +257,7 @@ namespace ts {
var sourceFile = hostGetSourceFile(fileName, languageVersion, onError);
if (sourceFile && compilerOptions.watch) {
// Attach a file watcher
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, () => sourceFileChanged(sourceFile));
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (fileName, removed) => sourceFileChanged(sourceFile, removed));
}
return sourceFile;
}
Expand All @@ -279,9 +279,15 @@ namespace ts {
}

// If a source file changes, mark it as unwatched and start the recompilation timer
function sourceFileChanged(sourceFile: SourceFile) {
function sourceFileChanged(sourceFile: SourceFile, removed: boolean) {
sourceFile.fileWatcher.close();
sourceFile.fileWatcher = undefined;
if (removed) {
var index = rootFileNames.indexOf(sourceFile.fileName);
if (index >= 0) {
rootFileNames.splice(index, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this cover referenced files?

Also, I don't know if this is the right approach. I think that if a root file is deleted, we should be removing the file from the cached program, but we should be erroring when we fail to find it.

}
}
startTimer();
}

Expand Down Expand Up @@ -354,11 +360,11 @@ namespace ts {
return { program, exitStatus };

function compileProgram(): ExitStatus {
// First get any syntactic errors.
// First get any syntactic errors.
var diagnostics = program.getSyntacticDiagnostics();
reportDiagnostics(diagnostics);

// If we didn't have any syntactic errors, then also try getting the global and
// If we didn't have any syntactic errors, then also try getting the global and
// semantic errors.
if (diagnostics.length === 0) {
var diagnostics = program.getGlobalDiagnostics();
Expand Down
20 changes: 10 additions & 10 deletions src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace ts.server {
input: process.stdin,
output: process.stdout,
terminal: false,
});
});

class Logger implements ts.server.Logger {
fd = -1;
Expand Down Expand Up @@ -58,7 +58,7 @@ namespace ts.server {
isVerbose() {
return this.loggingEnabled() && (this.level == "verbose");
}


msg(s: string, type = "Err") {
if (this.fd < 0) {
Expand All @@ -85,7 +85,7 @@ namespace ts.server {

interface WatchedFile {
fileName: string;
callback: (fileName: string) => void;
callback: (fileName: string, removed: boolean) => void;
mtime: Date;
}

Expand Down Expand Up @@ -121,11 +121,11 @@ namespace ts.server {

fs.stat(watchedFile.fileName,(err, stats) => {
if (err) {
watchedFile.callback(watchedFile.fileName);
watchedFile.callback(watchedFile.fileName, /* removed */ false);
}
else if (watchedFile.mtime.getTime() !== stats.mtime.getTime()) {
watchedFile.mtime = WatchedFileSet.getModifiedTime(watchedFile.fileName);
watchedFile.callback(watchedFile.fileName);
watchedFile.callback(watchedFile.fileName, watchedFile.mtime.getTime() === 0);
}
});
}
Expand Down Expand Up @@ -153,7 +153,7 @@ namespace ts.server {
}, this.interval);
}

addFile(fileName: string, callback: (fileName: string) => void ): WatchedFile {
addFile(fileName: string, callback: (fileName: string, removed: boolean) => void ): WatchedFile {
var file: WatchedFile = {
fileName,
callback,
Expand All @@ -170,7 +170,7 @@ namespace ts.server {
removeFile(file: WatchedFile) {
this.watchedFiles = WatchedFileSet.copyListRemovingItem(file, this.watchedFiles);
}
}
}

class IOSession extends Session {
constructor(host: ServerHost, logger: ts.server.Logger) {
Expand Down Expand Up @@ -243,11 +243,11 @@ namespace ts.server {
// TODO: check that this location is writable

var logger = createLoggerFromEnv();

// REVIEW: for now this implementation uses polling.
// The advantage of polling is that it works reliably
// on all os and with network mounted files.
// For 90 referenced files, the average time to detect
// For 90 referenced files, the average time to detect
// changes is 2*msInterval (by default 5 seconds).
// The overhead of this is .04 percent (1/2500) with
// average pause of < 1 millisecond (and max
Expand All @@ -271,4 +271,4 @@ namespace ts.server {
});
// Start listening
ioSession.listen();
}
}