diff --git a/Jakefile.js b/Jakefile.js index a786fb16ed3..ccb7ce497ca 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -726,7 +726,7 @@ compileFile( // Appending exports at the end of the server library var tsserverLibraryDefinitionFileContents = - fs.readFileSync(tsserverLibraryDefinitionFile).toString() + + fs.readFileSync(tsserverLibraryDefinitionFile).toString() + "\r\nexport = ts;" + "\r\nexport as namespace ts;"; @@ -851,24 +851,36 @@ 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, errorHandler) { +function exec(cmd, completeHandler, errorHandler, opts) { + var stdio = opts && opts.stdio || {}; + if (typeof stdio === "string") stdio = { stdout: stdio, stderr: stdio }; + if (!stdio.stdout) stdio.stdout = "inherit"; + if (!stdio.stderr) stdio.stderr = "inherit"; + var stdout = ""; + var stderr = ""; var ex = jake.createExec([cmd], { windowsVerbatimArguments: true }); // Add listeners for output and error ex.addListener("stdout", function (output) { - process.stdout.write(output); + stdout += output; + if (stdio.stdout === "inherit") { + process.stdout.write(output); + } }); ex.addListener("stderr", function (error) { - process.stderr.write(error); + stderr += error; + if (stdio.stderr === "inherit") { + process.stderr.write(error); + } }); ex.addListener("cmdEnd", function () { if (completeHandler) { - completeHandler(); + completeHandler(stdout, stderr); } complete(); }); ex.addListener("error", function (e, status) { if (errorHandler) { - errorHandler(e, status); + errorHandler(e, status, stdout, stderr); } else { fail("Process exited with code " + status); } @@ -1070,27 +1082,61 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFi exec(cmd); }, { async: true }); -function getDiffTool() { +function getDiffTool(cb) { var program = process.env['DIFF']; - if (!program) { + if (program) return cb(program); + return exec("git config diff.tool", onGetDiffTool, onError, { stdio: "redirect" }); + + function onGetDiffTool(stdout) { + if (stdout) stdout = stdout.trim(); + if (stdout) return exec("git config difftool." + stdout + ".cmd", onGetDifftoolCmd, onError, { stdio: "redirect" }); + return onError(); + } + + function onGetDifftoolCmd(stdout) { + if (stdout) stdout = stdout.trim(); + if (stdout) return cb(stdout.trim()); + return onError(); + } + + function onError() { fail("Add the 'DIFF' environment variable to the path of the program you want to use."); } - return program; +} + +function formatDiffTool(toolPath, leftPath, rightPath) { + return /\$(local|remote)/i.test(toolPath) + ? toolPath.replace(/(\$local)|(\$remote)/gi, function (_, left, right) { return left ? leftPath : rightPath; }) + : '"' + toolPath + '" "' + leftPath + '" "' + rightPath + '"'; +} + +function parseCommand(text) { + var re = /"([^"]*)"|[^"\s]+/g, args = [], m; + while (m = re.exec(text)) args.push(m[1] || m[0]); + return { cmd: args.shift(), args: args }; } // Baseline Diff 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); + getDiffTool(function (tool) { + var cmd = formatDiffTool(tool, refBaseline, localBaseline); + console.log(cmd); + var opts = parseCommand(cmd); + child_process.spawn(opts.cmd, opts.args, { detached: true }).unref(); + complete(); + }); }, { 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); + getDiffTool(function (tool) { + var cmd = formatDiffTool(tool, refRwcBaseline, localRwcBaseline); + console.log(cmd); + var opts = parseCommand(cmd); + child_process.spawn(opts.cmd, opts.args, { detached: true }).unref(); + complete(); + }); }, { async: true }); desc("Builds the test sources and automation in debug mode"); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7c0fa8fa612..06939a0e9e2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21457,7 +21457,7 @@ namespace ts { return grammarErrorOnFirstToken(heritageClause, Diagnostics._0_clause_already_seen, "extends"); } if (seenImplementsClause) { - return grammarErrorOnFirstToken(heritageClause, Diagnostics._0_clause_must_precede_0_clause, "extends", "implements"); + return grammarErrorOnFirstToken(heritageClause, Diagnostics._0_clause_must_precede_1_clause, "extends", "implements"); } if (heritageClause.types.length > 1) { return grammarErrorOnFirstToken(heritageClause.types[1], Diagnostics.Classes_can_only_extend_a_single_class); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ff732e7d83d..df220375077 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -515,7 +515,7 @@ "category": "Error", "code": 1172 }, - "'{0}' clause must precede '{0}' clause.": { + "'{0}' clause must precede '{1}' clause.": { "category": "Error", "code": 1173 }, diff --git a/tests/baselines/reference/implementsClauseAlreadySeen.errors.txt b/tests/baselines/reference/implementsClauseAlreadySeen.errors.txt index 80265c0802f..cd5a90cf548 100644 --- a/tests/baselines/reference/implementsClauseAlreadySeen.errors.txt +++ b/tests/baselines/reference/implementsClauseAlreadySeen.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/implementsClauseAlreadySeen.ts(4,22): error TS1175: 'implements' clause already seen. +tests/cases/compiler/implementsClauseAlreadySeen.ts(4,22): error TS1172: 'implements' clause already seen. ==== tests/cases/compiler/implementsClauseAlreadySeen.ts (1 errors) ==== @@ -7,6 +7,6 @@ tests/cases/compiler/implementsClauseAlreadySeen.ts(4,22): error TS1175: 'implem } class D implements C implements C { ~~~~~~~~~~ -!!! error TS1175: 'implements' clause already seen. +!!! error TS1172: 'implements' clause already seen. baz() { } } \ No newline at end of file diff --git a/tests/baselines/reference/parserClassDeclaration2.errors.txt b/tests/baselines/reference/parserClassDeclaration2.errors.txt index 18b4e2a0ff2..101e83dfbf8 100644 --- a/tests/baselines/reference/parserClassDeclaration2.errors.txt +++ b/tests/baselines/reference/parserClassDeclaration2.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclaration2.ts(1,20): error TS2304: Cannot find name 'A'. -tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclaration2.ts(1,22): error TS1175: 'implements' clause already seen. +tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclaration2.ts(1,22): error TS1172: 'implements' clause already seen. ==== tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclaration2.ts (2 errors) ==== @@ -7,5 +7,5 @@ tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclarat ~ !!! error TS2304: Cannot find name 'A'. ~~~~~~~~~~ -!!! error TS1175: 'implements' clause already seen. +!!! error TS1172: 'implements' clause already seen. } \ No newline at end of file diff --git a/tests/baselines/reference/parserClassDeclaration5.errors.txt b/tests/baselines/reference/parserClassDeclaration5.errors.txt index fca4b0f8fdf..72c0ae0f72e 100644 --- a/tests/baselines/reference/parserClassDeclaration5.errors.txt +++ b/tests/baselines/reference/parserClassDeclaration5.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclaration5.ts(1,17): error TS2304: Cannot find name 'A'. tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclaration5.ts(1,30): error TS2304: Cannot find name 'B'. -tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclaration5.ts(1,32): error TS1175: 'implements' clause already seen. +tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclaration5.ts(1,32): error TS1172: 'implements' clause already seen. ==== tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclaration5.ts (3 errors) ==== @@ -10,5 +10,5 @@ tests/cases/conformance/parser/ecmascript5/ClassDeclarations/parserClassDeclarat ~ !!! error TS2304: Cannot find name 'B'. ~~~~~~~~~~ -!!! error TS1175: 'implements' clause already seen. +!!! error TS1172: 'implements' clause already seen. } \ No newline at end of file