Skip to content

Commit f1f6317

Browse files
committed
Merge branch 'vilic-master'
2 parents 68bdbe0 + 4b5618b commit f1f6317

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/compiler/program.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,12 @@ namespace ts {
565565
sourceMap: false,
566566
};
567567

568+
interface OutputFingerprint {
569+
hash: string;
570+
byteOrderMark: boolean;
571+
mtime: Date;
572+
}
573+
568574
export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost {
569575
const existingDirectories: Map<boolean> = {};
570576

@@ -615,11 +621,50 @@ namespace ts {
615621
}
616622
}
617623

624+
let outputFingerprints: Map<OutputFingerprint>;
625+
626+
function writeFileIfUpdated(fileName: string, data: string, writeByteOrderMark: boolean): void {
627+
if (!outputFingerprints) {
628+
outputFingerprints = {};
629+
}
630+
631+
const hash = sys.createHash(data);
632+
const mtimeBefore = sys.getModifiedTime(fileName);
633+
634+
if (mtimeBefore && hasProperty(outputFingerprints, fileName)) {
635+
const fingerprint = outputFingerprints[fileName];
636+
637+
// If output has not been changed, and the file has no external modification
638+
if (fingerprint.byteOrderMark === writeByteOrderMark &&
639+
fingerprint.hash === hash &&
640+
fingerprint.mtime.getTime() === mtimeBefore.getTime()) {
641+
return;
642+
}
643+
}
644+
645+
sys.writeFile(fileName, data, writeByteOrderMark);
646+
647+
const mtimeAfter = sys.getModifiedTime(fileName);
648+
649+
outputFingerprints[fileName] = {
650+
hash,
651+
byteOrderMark: writeByteOrderMark,
652+
mtime: mtimeAfter
653+
};
654+
}
655+
618656
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
619657
try {
620658
const start = new Date().getTime();
621659
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
622-
sys.writeFile(fileName, data, writeByteOrderMark);
660+
661+
if (options.watch && sys.createHash && sys.getModifiedTime) {
662+
writeFileIfUpdated(fileName, data, writeByteOrderMark);
663+
}
664+
else {
665+
sys.writeFile(fileName, data, writeByteOrderMark);
666+
}
667+
623668
ioWriteTime += new Date().getTime() - start;
624669
}
625670
catch (e) {

src/compiler/sys.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ namespace ts {
2020
getExecutingFilePath(): string;
2121
getCurrentDirectory(): string;
2222
readDirectory(path: string, extension?: string, exclude?: string[]): string[];
23+
getModifiedTime?(path: string): Date;
24+
createHash?(data: string): string;
2325
getMemoryUsage?(): number;
2426
exit(exitCode?: number): void;
2527
}
@@ -226,6 +228,7 @@ namespace ts {
226228
const _fs = require("fs");
227229
const _path = require("path");
228230
const _os = require("os");
231+
const _crypto = require("crypto");
229232

230233
// average async stat takes about 30 microseconds
231234
// set chunk size to do 30 files in < 1 millisecond
@@ -584,6 +587,19 @@ namespace ts {
584587
return process.cwd();
585588
},
586589
readDirectory,
590+
getModifiedTime(path) {
591+
try {
592+
return _fs.statSync(path).mtime;
593+
}
594+
catch (e) {
595+
return undefined;
596+
}
597+
},
598+
createHash(data) {
599+
const hash = _crypto.createHash("md5");
600+
hash.update(data);
601+
return hash.digest("hex");
602+
},
587603
getMemoryUsage() {
588604
if (global.gc) {
589605
global.gc();

0 commit comments

Comments
 (0)