Create createHash and getModifiedTime under sys, and refactor implementation into compiler host

This commit is contained in:
vilicvane
2016-02-09 22:23:43 +08:00
parent c7e80e19f0
commit 63c690813f
2 changed files with 48 additions and 37 deletions

View File

@@ -559,6 +559,12 @@ namespace ts {
sourceMap: false,
};
interface OutputFingerprint {
hash: string;
byteOrderMark: boolean;
mtime: Date;
}
export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost {
const existingDirectories: Map<boolean> = {};
@@ -609,11 +615,42 @@ namespace ts {
}
}
const outputFingerprints: Map<OutputFingerprint> =
options.watch && sys.createHash && sys.getModifiedTime ? {} : undefined;
const fileWriter: typeof sys.writeFile = outputFingerprints ?
(fileName, data, writeByteOrderMark) => {
const hash = sys.createHash(data);
const mtimeBefore = sys.getModifiedTime(fileName);
if (mtimeBefore && outputFingerprints.hasOwnProperty(fileName)) {
const fingerprint = outputFingerprints[fileName];
// If output has not been changed, and the file has no external modification
if (fingerprint.byteOrderMark === writeByteOrderMark &&
fingerprint.hash === hash &&
fingerprint.mtime.getTime() === mtimeBefore.getTime()) {
return;
}
}
sys.writeFile(fileName, data, writeByteOrderMark);
const mtimeAfter = sys.getModifiedTime(fileName);
outputFingerprints[fileName] = {
hash,
byteOrderMark: writeByteOrderMark,
mtime: mtimeAfter
};
} :
(fileName, data, writeByteOrderMark) => sys.writeFile(fileName, data, writeByteOrderMark);
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
try {
const start = new Date().getTime();
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
sys.writeFile(fileName, data, writeByteOrderMark);
fileWriter(fileName, data, writeByteOrderMark);
ioWriteTime += new Date().getTime() - start;
}
catch (e) {

View File

@@ -20,6 +20,8 @@ namespace ts {
getExecutingFilePath(): string;
getCurrentDirectory(): string;
readDirectory(path: string, extension?: string, exclude?: string[]): string[];
getModifiedTime?(path: string): Date;
createHash?(data: string): string;
getMemoryUsage?(): number;
exit(exitCode?: number): void;
}
@@ -39,15 +41,6 @@ namespace ts {
referenceCount: number;
}
interface OutputFingerprint {
hash: string;
mtime: Date;
}
interface OutputFingerprintMap {
[fileName: string]: OutputFingerprint;
}
declare var require: any;
declare var module: any;
declare var process: any;
@@ -449,26 +442,12 @@ namespace ts {
return buffer.toString("utf8");
}
const outputFingerprintMap: OutputFingerprintMap = {};
function writeFile(fileName: string, data: string, writeByteOrderMark?: boolean): void {
// If a BOM is required, emit one
if (writeByteOrderMark) {
data = "\uFEFF" + data;
}
const md5 = getMd5(data);
const mtimeBefore = _fs.existsSync(fileName) && _fs.statSync(fileName).mtime;
if (mtimeBefore && outputFingerprintMap.hasOwnProperty(fileName)) {
const fingerprint = outputFingerprintMap[fileName];
// If output has not been changed, and the file has no external modification
if (fingerprint.hash === md5 && fingerprint.mtime.getTime() === mtimeBefore.getTime()) {
return;
}
}
let fd: number;
try {
@@ -480,19 +459,6 @@ namespace ts {
_fs.closeSync(fd);
}
}
const mtimeAfter = _fs.statSync(fileName).mtime;
outputFingerprintMap[fileName] = {
hash: md5,
mtime: mtimeAfter
};
}
function getMd5(data: string): string {
const hash = _crypto.createHash("md5");
hash.update(data);
return hash.digest("hex");
}
function getCanonicalPath(path: string): string {
@@ -593,6 +559,14 @@ namespace ts {
return process.cwd();
},
readDirectory,
getModifiedTime(path) {
return _fs.existsSync(path) && _fs.statSync(path).mtime;
},
createHash(data) {
const hash = _crypto.createHash("md5");
hash.update(data);
return hash.digest("hex");
},
getMemoryUsage() {
if (global.gc) {
global.gc();