diff --git a/.travis.yml b/.travis.yml index 305fad1e4a7..50ff61e20f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,8 @@ node_js: sudo: false -before_script: npm install -g codeclimate-test-reporter +before_script: + - npm install -g codeclimate-test-reporter after_script: - cat coverage/lcov.info | codeclimate diff --git a/Jakefile b/Jakefile index 324356a4af5..4c971efe0c9 100644 --- a/Jakefile +++ b/Jakefile @@ -3,7 +3,6 @@ var fs = require("fs"); var os = require("os"); var path = require("path"); -var child_process = require("child_process"); // Variables var compilerDirectory = "src/compiler/"; @@ -26,7 +25,8 @@ var thirdParty = "ThirdPartyNoticeText.txt"; var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter; if (process.env.path !== undefined) { process.env.path = nodeModulesPathPrefix + process.env.path; -} else if (process.env.PATH !== undefined) { +} +else if (process.env.PATH !== undefined) { process.env.PATH = nodeModulesPathPrefix + process.env.PATH; } @@ -203,7 +203,8 @@ function concatenateFiles(destinationFile, sourceFiles) { var useDebugMode = true; var host = (process.env.host || process.env.TYPESCRIPT_HOST || "node"); var compilerFilename = "tsc.js"; -/* Compiles a file from a list of sources + + /* 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 * @param prereqs: prerequisite tasks to compiling the file @@ -214,8 +215,9 @@ var compilerFilename = "tsc.js"; * @param outDir: true to compile using --outDir * @param keepComments: false to compile using --removeComments * @param callback: a function to execute after the compilation process ends + * @async */ -function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOutFile, generateDeclarations, outDir, preserveConstEnums, keepComments, noResolve, stripInternal, callback) { + function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOutFile, generateDeclarations, outDir, preserveConstEnums, keepComments, noResolve, stripInternal, callback) { file(outFile, prereqs, function() { var dir = useBuiltCompiler ? builtLocalDirectory : LKGDirectory; var options = "--module commonjs -noImplicitAny"; @@ -254,17 +256,9 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOu var cmd = host + " " + dir + compilerFilename + " " + options + " "; cmd = cmd + sources.join(" "); - console.log(cmd + "\n"); - var ex = jake.createExec([cmd]); - // Add listeners for output and error - ex.addListener("stdout", function(output) { - process.stdout.write(output); - }); - ex.addListener("stderr", function(error) { - process.stderr.write(error); - }); - ex.addListener("cmdEnd", function() { + exec(cmd, function() { + console.log("") if (!useDebugMode && prefixes && fs.existsSync(outFile)) { for (var i in prefixes) { prependFile(prefixes[i], outFile); @@ -274,14 +268,14 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOu if (callback) { callback(); } - - complete(); - }); - ex.addListener("error", function() { + else { + complete(); + } + }, /* errorHandler */ function() { fs.unlinkSync(outFile); fail("Compilation of " + outFile + " unsuccessful"); }); - ex.run(); + }, {async: true}); } @@ -324,19 +318,8 @@ compileFile(processDiagnosticMessagesJs, // The generated diagnostics map; built for the compiler and for the 'generate-diagnostics' task file(diagnosticInfoMapTs, [processDiagnosticMessagesJs, diagnosticMessagesJson], function () { var cmd = "node " + processDiagnosticMessagesJs + " " + diagnosticMessagesJson; - console.log(cmd); - var ex = jake.createExec([cmd]); - // Add listeners for output and error - ex.addListener("stdout", function(output) { - process.stdout.write(output); - }); - ex.addListener("stderr", function(error) { - process.stderr.write(error); - }); - ex.addListener("cmdEnd", function() { - complete(); - }); - ex.run(); + + exec(cmd); }, {async: true}) desc("Generates a diagnostic file in TypeScript based on an input JSON file"); @@ -401,6 +384,7 @@ compileFile(nodeDefinitionsFile, servicesSources,[builtLocalDirectory, copyright // Delete the temp dir jake.rmRf(tempDirPath, {silent: true}); + complete(); }); var serverFile = path.join(builtLocalDirectory, "tsserver.js"); @@ -449,10 +433,8 @@ compileFile(word2mdJs, file(specMd, [word2mdJs, specWord], function () { var specWordFullPath = path.resolve(specWord); var cmd = "cscript //nologo " + word2mdJs + ' "' + specWordFullPath + '" ' + specMd; - console.log(cmd); - child_process.exec(cmd, function () { - complete(); - }); + + exec(cmd); }, {async: true}) @@ -503,22 +485,24 @@ var refTest262Baseline = path.join(internalTests, "baselines/test262/reference") desc("Builds the test infrastructure using the built compiler"); task("tests", ["local", run].concat(libraryTargets)); -function exec(cmd, completeHandler) { - var ex = jake.createExec([cmd], {windowsVerbatimArguments: true}); - // Add listeners for output and error - ex.addListener("stdout", function(output) { - process.stdout.write(output); - }); - ex.addListener("stderr", function(error) { - process.stderr.write(error); - }); +/* Executes a command + * @param cmd: command to execute + * @param completeHandler?: a function to execute after the command ends + * @param errorHandler?: a function to execute if an error occurs + * @async + */ +function exec(cmd, completeHandler, errorHandler) { + console.log(cmd); + var ex = jake.createExec([cmd], {windowsVerbatimArguments: true, interactive: true}); ex.addListener("cmdEnd", function() { if (completeHandler) { completeHandler(); } - complete(); + else { + complete(); + } }); - ex.addListener("error", function(e, status) { + ex.addListener("error", errorHandler || function(e, status) { fail("Process exited with code " + status); }) @@ -537,7 +521,7 @@ function cleanTestDirs() { } jake.mkdirP(localRwcBaseline); - jake.mkdirP(localTest262Baseline); + jake.mkdirP(localTest262Baseline); jake.mkdirP(localBaseline); } @@ -548,10 +532,14 @@ function writeTestConfigFile(tests, testConfigFile) { fs.writeFileSync('test.config', testConfigContents); } +/* Removes project output + * @async + */ function deleteTemporaryProjectOutput() { if (fs.existsSync(path.join(localBaseline, "projectOutput/"))) { jake.rmRf(path.join(localBaseline, "projectOutput/")); } + complete(); } var testTimeout = 20000; @@ -580,14 +568,14 @@ task("runtests", ["tests", builtLocalDirectory], function() { // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer var cmd = host + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; - console.log(cmd); + exec(cmd, deleteTemporaryProjectOutput); }, {async: true}); desc("Generates code coverage data via instanbul") task("generate-code-coverage", ["tests", builtLocalDirectory], function () { var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run; - console.log(cmd); + exec(cmd); }, { async: true }); @@ -619,7 +607,6 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory], function( tests = tests ? tests : ''; var cmd = host + " tests/webTestServer.js " + port + " " + browser + " " + tests - console.log(cmd); exec(cmd); }, {async: true}); @@ -635,14 +622,12 @@ function getDiffTool() { desc("Diffs the compiler baselines using the diff tool specified by the 'DIFF' environment variable"); task('diff', function () { var cmd = '"' + getDiffTool() + '" ' + refBaseline + ' ' + localBaseline; - console.log(cmd) exec(cmd); }, {async: true}); desc("Diffs the RWC baselines using the diff tool specified by the 'DIFF' environment variable"); task('diff-rwc', function () { var cmd = '"' + getDiffTool() + '" ' + refRwcBaseline + ' ' + localRwcBaseline; - console.log(cmd) exec(cmd); }, {async: true}); @@ -689,13 +674,6 @@ task("webhost", [webhostJsPath], function() { jake.cpR(path.join(builtLocalDirectory, "lib.d.ts"), "tests/webhost/", {silent: true}); }); -// Perf compiler -var perftscPath = "tests/perftsc.ts"; -var perftscJsPath = "built/local/perftsc.js"; -compileFile(perftscJsPath, [perftscPath], [tscFile, perftscPath, "tests/perfsys.ts"].concat(libraryTargets), [], /*useBuiltCompiler*/ 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'; @@ -704,14 +682,12 @@ file(loggedIOJsPath, [builtLocalDirectory, loggedIOpath], function() { 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() { + + exec(cmd, function() { fs.renameSync(temp + '/harness/loggedIO.js', loggedIOJsPath); jake.rmRf(temp); complete(); }); - ex.run(); }, {async: true}); var instrumenterPath = harnessDirectory + 'instrumenter.ts'; @@ -721,10 +697,6 @@ compileFile(instrumenterJsPath, [instrumenterPath], [tscFile, instrumenterPath], 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("cmdEnd", function() { - complete(); - }); - ex.run(); + + exec(cmd); }, { async: true }); diff --git a/package.json b/package.json index 9261174b68f..b53916b37b3 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,6 @@ "codeclimate-test-reporter": "latest" }, "scripts": { - "test": "jake generate-code-coverage" + "test": "jake --trace generate-code-coverage" } } diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 57c2298d3d3..68507b34574 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -258,7 +258,7 @@ module ts { reportDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes)); } - function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError ?: (message: string) => void) { + function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) { // Return existing SourceFile object if one is available if (cachedProgram) { var sourceFile = cachedProgram.getSourceFile(fileName); diff --git a/tests/perfsys.ts b/tests/perfsys.ts deleted file mode 100644 index 143d0d637d4..00000000000 --- a/tests/perfsys.ts +++ /dev/null @@ -1,105 +0,0 @@ -/// -/// - -module perftest { - - interface IOLog { - resolvePath: ts.Map; - fileNames: string[]; - } - - export interface IO { - getOut(): string; - } - - export var readFile = ts.sys.readFile; - var writeFile = ts.sys.writeFile; - export var write = ts.sys.write; - var resolvePath = ts.sys.resolvePath; - export var getExecutingFilePath = ts.sys.getExecutingFilePath; - export var getCurrentDirectory = ts.sys.getCurrentDirectory; - var exit = ts.sys.exit; - - var args = ts.sys.args; - - // augment sys so first ts.executeCommandLine call will be finish silently - ts.sys.write = (s: string) => { }; - ts.sys.exit = (code: number) => { }; - ts.sys.args = [] - - export function restoreSys() { - ts.sys.args = args; - ts.sys.write = write; - } - - export function hasLogIOFlag() { - return args.length > 2 && args[0] === "--logio"; - } - - export function getArgsWithoutLogIOFlag() { - return args.slice(2); - } - - export function getArgsWithoutIOLogFile() { - return args.slice(1); - } - - var resolvePathLog: ts.Map = {}; - - export function interceptIO() { - ts.sys.resolvePath = (s) => { - var result = resolvePath(s); - resolvePathLog[s] = result; - return result; - }; - } - - export function writeIOLog(fileNames: string[]) { - var path = args[1]; - var log: IOLog = { - fileNames: fileNames, - resolvePath: resolvePathLog - }; - - writeFile(path, JSON.stringify(log)); - } - - export function prepare(): IO { - var log = JSON.parse(readFile(args[0])); - - var files: ts.Map = {}; - log.fileNames.forEach(f => { files[f] = readFile(f); }) - - ts.sys.createDirectory = (s: string) => { }; - ts.sys.directoryExists = (s: string) => true; - ts.sys.fileExists = (s: string) => true; - - var currentDirectory = ts.sys.getCurrentDirectory(); - ts.sys.getCurrentDirectory = () => currentDirectory; - - var executingFilePath = ts.sys.getExecutingFilePath(); - ts.sys.getExecutingFilePath = () => executingFilePath; - - ts.sys.readFile = (s: string) => { - return files[s]; - } - - ts.sys.resolvePath = (s: string) => { - var path = log.resolvePath[s]; - if (!path) { - throw new Error("Unexpected path '" + s + "'"); - } - return path - } - - ts.sys.writeFile = (path: string, data: string) => { }; - - var out: string = ""; - - ts.sys.write = (s: string) => { out += s; }; - - return { - getOut: () => out, - }; - } -} diff --git a/tests/perftsc.ts b/tests/perftsc.ts deleted file mode 100644 index e0189896a15..00000000000 --- a/tests/perftsc.ts +++ /dev/null @@ -1,30 +0,0 @@ -/// -/// - -// resolve all files used in this compilation -if (perftest.hasLogIOFlag()) { - perftest.interceptIO(); - - var compilerHost: ts.CompilerHost = { - getSourceFile: (s, v) => { - var content = perftest.readFile(s); - return content !== undefined ? ts.createSourceFile(s, content, v) : undefined; - }, - getDefaultLibFilename: () => ts.combinePaths(ts.getDirectoryPath(ts.normalizePath(perftest.getExecutingFilePath())), "lib.d.ts"), - writeFile: (f: string, content: string) => { throw new Error("Unexpected operation: writeFile"); }, - getCurrentDirectory: () => perftest.getCurrentDirectory(), - getCanonicalFileName: (f: string) => ts.sys.useCaseSensitiveFileNames ? f : f.toLowerCase(), - useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames, - getNewLine: () => ts.sys.newLine - }; - - var commandLine = ts.parseCommandLine(perftest.getArgsWithoutLogIOFlag()); - var program = ts.createProgram(commandLine.filenames, commandLine.options, compilerHost); - var fileNames = program.getSourceFiles().map(f => f.filename); - perftest.writeIOLog(fileNames); -} -else { - var io = perftest.prepare(); - ts.executeCommandLine(perftest.getArgsWithoutIOLogFile()); - perftest.write(io.getOut()); -}