diff --git a/Gulpfile.ts b/Gulpfile.ts index e025ce6eaa8..cc506c44ee9 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -2,6 +2,7 @@ import * as cp from "child_process"; import * as path from "path"; import * as fs from "fs"; +import child_process = require("child_process"); import originalGulp = require("gulp"); import helpMaker = require("gulp-help"); import runSequence = require("run-sequence"); @@ -1019,40 +1020,16 @@ function spawnLintWorker(files: {path: string}[], callback: (failures: number) = } gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: --f[iles]=regex", ["build-rules"], () => { - const fileMatcher = RegExp(cmdLineOptions["files"]); if (fold.isTravis()) console.log(fold.start("lint")); - - let files: {stat: fs.Stats, path: string}[] = []; - return gulp.src(lintTargets, { read: false }) - .pipe(through2.obj((chunk, enc, cb) => { - files.push(chunk); - cb(); - }, (cb) => { - files = files.filter(file => fileMatcher.test(file.path)).sort((filea, fileb) => filea.stat.size - fileb.stat.size); - const workerCount = cmdLineOptions["workers"]; - for (let i = 0; i < workerCount; i++) { - spawnLintWorker(files, finished); - } - - let completed = 0; - let failures = 0; - function finished(fails) { - completed++; - failures += fails; - if (completed === workerCount) { - if (fold.isTravis()) console.log(fold.end("lint")); - if (failures > 0) { - throw new Error(`Linter errors: ${failures}`); - } - else { - cb(); - } - } - } - })); + const fileMatcher = cmdLineOptions["files"]; + const files = fileMatcher + ? `src/**/${fileMatcher}` + : "Gulpfile.ts 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts' --exclude 'src/harness/unittests/services/**/*.ts'"; + const cmd = `node node_modules/tslint/bin/tslint ${files} --format stylish`; + console.log("Linting: " + cmd); + child_process.execSync(cmd, { stdio: [0, 1, 2] }); }); - gulp.task("default", "Runs 'local'", ["local"]); gulp.task("watch", "Watches the src/ directory for changes and executes runtests-parallel.", [], () => { diff --git a/Jakefile.js b/Jakefile.js index 2b0f0fe1f42..9c2b3d38d10 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -1177,43 +1177,16 @@ function spawnLintWorker(files, callback) { } desc("Runs tslint on the compiler sources. Optional arguments are: f[iles]=regex"); -task("lint", ["build-rules"], function () { +task("lint", ["build-rules"], () => { if (fold.isTravis()) console.log(fold.start("lint")); - var startTime = mark(); - var failed = 0; - var fileMatcher = RegExp(process.env.f || process.env.file || process.env.files || ""); - var done = {}; - for (var i in lintTargets) { - var target = lintTargets[i]; - if (!done[target] && fileMatcher.test(target)) { - done[target] = fs.statSync(target).size; - } - } - - var workerCount = (process.env.workerCount && +process.env.workerCount) || os.cpus().length; - - var names = Object.keys(done).sort(function (namea, nameb) { - return done[namea] - done[nameb]; + const fileMatcher = process.env.f || process.env.file || process.env.files; + const files = fileMatcher + ? `src/**/${fileMatcher}` + : "Gulpfile.ts 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts' --exclude 'src/harness/unittests/services/**/*.ts'"; + const cmd = `node node_modules/tslint/bin/tslint ${files} --format stylish`; + console.log("Linting: " + cmd); + jake.exec([cmd], { interactive: true }, () => { + if (fold.isTravis()) console.log(fold.end("lint")); + complete(); }); - - for (var i = 0; i < workerCount; i++) { - spawnLintWorker(names, finished); - } - - var completed = 0; - var failures = 0; - function finished(fails) { - completed++; - failures += fails; - if (completed === workerCount) { - measure(startTime); - if (fold.isTravis()) console.log(fold.end("lint")); - if (failures > 0) { - fail('Linter errors.', failed); - } - else { - complete(); - } - } - } -}, { async: true }); +}); diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 092c84996f1..98ebacd49b1 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -931,7 +931,7 @@ namespace FourSlash { const { isWriteAccess, isDefinition, isInString } = (r.marker && r.marker.data) || { isWriteAccess: false, isDefinition: false, isInString: undefined }; const result: ts.ReferenceEntry = { fileName: r.fileName, textSpan: { start: r.start, length: r.end - r.start }, isWriteAccess: !!isWriteAccess, isDefinition: !!isDefinition }; if (isInString !== undefined) { - result.isInString = isInString + result.isInString = isInString; } return result; } diff --git a/src/harness/unittests/services/formatting/getFormattingEditsForRange.ts b/src/harness/unittests/services/formatting/getFormattingEditsForRange.ts new file mode 100644 index 00000000000..9ad1102d2f4 --- /dev/null +++ b/src/harness/unittests/services/formatting/getFormattingEditsForRange.ts @@ -0,0 +1,88 @@ +/// + +describe('getFormattingEditsForRange', function() { + // + // Verify that formatting the typescript file "sourceFileName" results in the + // baseline file "baselineFileName". + // + function getFormattingEditsForRange(sourceFileName: string) { + var baselineFileName = "tests/cases/unittests/services/testCode/formatting/" + sourceFileName + "BaseLine.ts"; + sourceFileName = "tests/cases/unittests/services/testCode/formatting/" + sourceFileName + ".ts"; + + var typescriptLS = new Harness.TypeScriptLS(); + typescriptLS.addDefaultLibrary(); + typescriptLS.addFile(sourceFileName); + + var ls = typescriptLS.getLanguageService(); + var script = ls.languageService.getScriptAST(sourceFileName); + assert.notNull(script); + + var edits = ls.languageService.getFormattingEditsForRange(sourceFileName, 0, script.limChar, new Services.FormatCodeOptions()); + typescriptLS.checkEdits(sourceFileName, baselineFileName, edits); + } + + describe('test cases for formatting engine', function() { + it("formats typescript constructs properly", function() { + getFormattingEditsForRange('typescriptConstructs'); + }); + it("formats document ready function properly", function() { + getFormattingEditsForRange('documentReadyFunction'); + }); + it("formats on closing bracket properly", function() { + getFormattingEditsForRange('onClosingBracket'); + }); + it("formats various javascript constructs", function() { + getFormattingEditsForRange('various'); + }); + it("formats main javascript program", function() { + getFormattingEditsForRange('main'); + }); + it("formats on semicolon properly", function() { + getFormattingEditsForRange('onSemiColon'); + }); + it("formats enum with trailling tab characters properly", function() { + getFormattingEditsForRange('tabAfterCloseCurly'); + }); + it("formats object literal", function() { + getFormattingEditsForRange('objectLiteral'); + }); + it("formats with statements", function() { + getFormattingEditsForRange('withStatement'); + }); + it("formats ':' and '?' in parameters", function() { + getFormattingEditsForRange('colonAndQMark'); + }); + it("formats 'import' declaration", function() { + getFormattingEditsForRange('importDeclaration'); + }); + it("formats exported class with implicit module", function() { + //TODO: this is to force generation of implicit module in AST + var svGenTarget = TypeScript.moduleGenTarget; + try { + TypeScript.moduleGenTarget = TypeScript.ModuleGenTarget.Asynchronous; + getFormattingEditsForRange('implicitModule'); + } + finally { + TypeScript.moduleGenTarget = svGenTarget; + } + }); + it("formats constructor statements correctelly", function() { + getFormattingEditsForRange('spaceAfterConstructor'); + }); + it("formats classes and interfaces correctelly", function() { + getFormattingEditsForRange('classes'); + }); + it("formats modules correctly", function() { + getFormattingEditsForRange('modules'); + }); + it("formats fat arrow expressions correctelly", function() { + getFormattingEditsForRange('fatArrowFunctions'); + }); + it("formats empty object/interface literals correctelly", function() { + getFormattingEditsForRange('emptyInterfaceLiteral'); + }); + it("formats variable declaration lists", function() { + getFormattingEditsForRange('formatVariableDeclarationList'); + }); + }); +}); diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 97a1b6e74cb..b92d335457a 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -2,8 +2,6 @@ /// ECMAScript APIs ///////////////////////////// -// tslint:disable no-var-keyword - declare const NaN: number; declare const Infinity: number; diff --git a/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt b/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt index ed6ee0dcd87..46782aaa1d6 100644 --- a/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt +++ b/tests/baselines/reference/variableDeclarationInStrictMode1.errors.txt @@ -1,4 +1,4 @@ -lib.d.ts(34,18): error TS2300: Duplicate identifier 'eval'. +lib.d.ts(32,18): error TS2300: Duplicate identifier 'eval'. tests/cases/compiler/variableDeclarationInStrictMode1.ts(2,5): error TS1100: Invalid use of 'eval' in strict mode. tests/cases/compiler/variableDeclarationInStrictMode1.ts(2,5): error TS2300: Duplicate identifier 'eval'.