diff --git a/Jakefile b/Jakefile
index b803f23eae8..9dfd02e257c 100644
--- a/Jakefile
+++ b/Jakefile
@@ -123,6 +123,8 @@ function concatenateFiles(destinationFile, sourceFiles) {
}
var useDebugMode = false;
+var host = (process.env.host || process.env.TYPESCRIPT_HOST || "node");
+var compilerFilename = "tsc.js";
/* Compiles a file from a list of sources
* @param outFile: the target file name
* @param sources: an array of the names of the source files
@@ -134,10 +136,9 @@ var useDebugMode = false;
function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOutFile) {
file(outFile, prereqs, function() {
var dir = useBuiltCompiler ? builtLocalDirectory : LKGDirectory;
- var compilerFilename = "tsc.js";
var options = "-removeComments --module commonjs -noImplicitAny "; //" -propagateEnumConstants "
- var cmd = (process.env.host || process.env.TYPESCRIPT_HOST || "node") + " " + dir + compilerFilename + " " + options + " ";
+ var cmd = host + " " + dir + compilerFilename + " " + options + " ";
if (useDebugMode) {
cmd = cmd + " " + path.join(harnessDirectory, "external/es5compat.ts") + " " + path.join(harnessDirectory, "external/json2.ts") + " ";
}
@@ -230,7 +231,7 @@ task("generate-diagnostics", [diagnosticInfoMapTs])
// Local target to build the compiler and services
-var tscFile = path.join(builtLocalDirectory, "tsc.js");
+var tscFile = path.join(builtLocalDirectory, compilerFilename);
compileFile(tscFile, compilerSources, [builtLocalDirectory, copyright].concat(compilerSources), [copyright], /*useBuiltCompiler:*/ false);
var servicesFile = path.join(builtLocalDirectory, "typescriptServices.js");
@@ -473,3 +474,36 @@ var perftscJsPath = "built/local/perftsc.js";
compileFile(perftscJsPath, [perftscPath], [tscFile, perftscPath, "tests/perfsys.ts"].concat(libraryTargets), [], true);
desc("Builds augmented version of the compiler for perf tests");
task("perftsc", [perftscJsPath]);
+
+// Instrumented compiler
+var loggedIOpath = harnessDirectory + 'loggedIO.ts';
+var loggedIOJsPath = builtLocalDirectory + 'loggedIO.js';
+file(loggedIOJsPath, [builtLocalDirectory], function() {
+ var temp = builtLocalDirectory + 'temp';
+ jake.mkdirP(temp);
+ var options = "--outdir " + temp + ' ' + loggedIOpath;
+ var cmd = host + " " + LKGDirectory + compilerFilename + " " + options + " ";
+ console.log(cmd + "\n");
+ var ex = jake.createExec([cmd]);
+ ex.addListener("cmdEnd", function() {
+ fs.renameSync(temp + '/harness/loggedIO.js', loggedIOJsPath);
+ jake.rmRf(temp);
+ });
+ ex.run();
+}, {async: true});
+
+var instrumenterPath = harnessDirectory + 'instrumenter.ts';
+var instrumenterJsPath = builtLocalDirectory + 'instrumenter.js';
+compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath], [], true);
+
+desc("Builds an instrumented tsc.js");
+task('tsc-instrumented', [loggedIOJsPath, instrumenterJsPath, tscFile], function() {
+ var cmd = host + ' ' + instrumenterJsPath + ' record iocapture ' + builtLocalDirectory + compilerFilename;
+ console.log(cmd);
+ var ex = jake.createExec([cmd]);
+ ex.addListener("error", function(e) {
+ console.log('error running instrumenter');
+ console.log(e);
+ });
+ ex.run();
+}, { async: true });
\ No newline at end of file
diff --git a/src/harness/instrumenter.ts b/src/harness/instrumenter.ts
new file mode 100644
index 00000000000..61f6a8f2ec3
--- /dev/null
+++ b/src/harness/instrumenter.ts
@@ -0,0 +1,53 @@
+declare var require: any, process: any;
+var fs: any = require('fs');
+var path: any = require('path');
+
+function instrumentForRecording(fn: string, tscPath: string) {
+ instrument(tscPath, 'sys = Playback.wrapSystem(sys); sys.startRecord("' + fn + '");', 'sys.endRecord();');
+}
+
+function instrumentForReplay(logFilename: string, tscPath: string) {
+ instrument(tscPath, 'sys = Playback.wrapSystem(sys); sys.startReplay("' + logFilename + '");');
+}
+
+function instrument(tscPath: string, prepareCode: string, cleanupCode: string = '') {
+ var bak = tscPath + '.bak';
+ fs.exists(bak, (backupExists: boolean) => {
+ var filename = tscPath;
+ if (backupExists) {
+ filename = bak;
+ }
+
+ fs.readFile(filename, 'utf-8', (err: any, tscContent: string) => {
+ if (err) throw err;
+
+ fs.writeFile(bak, tscContent, (err: any) => {
+ if (err) throw err;
+
+ fs.readFile(path.resolve(path.dirname(tscPath) + '/loggedIO.js'), 'utf-8', (err: any, loggerContent: string) => {
+ if (err) throw err;
+
+ var invocationLine = 'ts.executeCommandLine(sys.args);';
+ var index1 = tscContent.indexOf(invocationLine);
+ var index2 = index1 + invocationLine.length;
+ var newContent = tscContent.substr(0, index1) + loggerContent + prepareCode + invocationLine + cleanupCode + tscContent.substr(index2) + '\r\n';
+ fs.writeFile(tscPath, newContent);
+ });
+ });
+ });
+ });
+}
+
+var isJson = (arg: string) => arg.indexOf(".json") > 0;
+
+var record = process.argv.indexOf('record');
+var tscPath = process.argv[process.argv.length - 1];
+if (record >= 0) {
+ console.log('Instrumenting ' + tscPath + ' for recording');
+ instrumentForRecording(process.argv[record + 1], tscPath);
+} else if (process.argv.some(isJson)) {
+ var filename = process.argv.filter(isJson)[0];
+ instrumentForReplay(filename, tscPath);
+}
+
+
diff --git a/src/harness/loggedIO.ts b/src/harness/loggedIO.ts
index dbc3cdbec2c..3adb04adf4b 100644
--- a/src/harness/loggedIO.ts
+++ b/src/harness/loggedIO.ts
@@ -1,4 +1,6 @@
///
+///
+///
interface FileInformation {
contents: string;
@@ -258,7 +260,12 @@ module Playback {
memoize((path) => findResultByFields(replayLog.pathsResolved, { path: path }, !ts.isRootedDiskPath(ts.normalizeSlashes(path)) && replayLog.currentDirectory ? replayLog.currentDirectory + '/' + path : ts.normalizeSlashes(path))));
wrapper.readFile = recordReplay(wrapper.readFile, underlying)(
- (path) => callAndRecord(underlying.readFile(path), recordLog.filesRead, { path: path, codepage: 0 }),
+ (path) => {
+ var result = underlying.readFile(path);
+ var logEntry = { path: path, codepage: 0, result: { contents: result, codepage: 0 } };
+ recordLog.filesRead.push(logEntry);
+ return result;
+ },
memoize((path) => findResultByPath(wrapper, replayLog.filesRead, path).contents));
wrapper.writeFile = recordReplay(wrapper.writeFile, underlying)(