diff --git a/.vscode/launch.json b/.vscode/launch.json index c1786f7a2b92a..8160fb09320e1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js", "stopOnEntry": true, "args": [ - "watch-extension:json-client" + "hygiene" ], "cwd": "${workspaceFolder}" }, diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index 514de09af3238..2881697ecd81f 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -13,6 +13,8 @@ const gulpeslint = require('gulp-eslint'); const tsfmt = require('typescript-formatter'); const tslint = require('tslint'); const vfs = require('vinyl-fs'); +const path = require('path'); +const fs = require('fs'); /** * Hygiene works by creating cascading subsets of all our files and @@ -219,30 +221,57 @@ const hygiene = exports.hygiene = (some, options) => { }); }); - function reportFailures(failures) { - failures.forEach(failure => { - const name = failure.name || failure.fileName; - const position = failure.startPosition; - const line = position.lineAndCharacter ? position.lineAndCharacter.line : position.line; - const character = position.lineAndCharacter ? position.lineAndCharacter.character : position.character; + let linterForProgram = {}; // maps tslint programs to its corresponding Linter + const configuration = tslint.Configuration.findConfiguration('tslint-hygiene.json', '.'); - console.error(`${name}:${line + 1}:${character + 1}:${failure.failure}`); - }); + function createLinter(tsconfig) { + const program = tslint.Linter.createProgram(tsconfig); + const tslintOptions = { fix: false, formatter: 'json' }; + return new tslint.Linter(tslintOptions, program); } - const tsl = es.through(function (file) { - const configuration = tslint.Configuration.findConfiguration(null, '.'); - const linterOptions = { fix: false, formatter: 'json', rulesDirectory: 'build/lib/tslint' }; - const contents = file.contents.toString('utf8'); - const linter = new tslint.Linter(linterOptions); - linter.lint(file.relative, contents, configuration.results); - const result = linter.getResult(); + function findTsConfig(segments) { + let fsPath = segments.reduce((p, each) => path.join(p, each)); + let tsconfig = path.join(fsPath, 'tsconfig.json'); + if (fs.existsSync(tsconfig)) { + return tsconfig; + } else if (segments.length > 1) { + segments.splice(-1, 1); + return findTsConfig(segments); + } else { + return undefined; + } + } - if (result.failures.length > 0) { - reportFailures(result.failures); - errorCount += result.failures.length; + function getLinter(file) { + let segments = file.relative.split(path.sep); + + // hard code the location of the tsconfig.json for the source folder to eliminate the lookup for the tsconfig.json + if (segments[0] === 'src') { + if (!linterForProgram['src']) { + linterForProgram['src'] = createLinter('src/tsconfig.json'); + } + return linterForProgram['src']; + } + else { + segments.splice(-1, 1); + let tsconfig = findTsConfig(segments); + if (!tsconfig) { + return undefined; + } + if (!linterForProgram[tsconfig]) { + linterForProgram[tsconfig] = createLinter(tsconfig); + } + return linterForProgram[tsconfig]; } + } + const tsl = es.through(function (file) { + const contents = file.contents.toString('utf8'); + let linter = getLinter(file); + if (linter) { + linter.lint(file.relative, contents, configuration.results); + } this.emit('data', file); }); @@ -276,6 +305,22 @@ const hygiene = exports.hygiene = (some, options) => { this.emit('data', data); }, function () { process.stdout.write('\n'); + + for (let linter in linterForProgram) { + const tslintResult = linterForProgram[linter].getResult(); + if (tslintResult.failures.length > 0) { + for (const failure of tslintResult.failures) { + const name = failure.getFileName(); + const position = failure.getStartPosition(); + const line = position.getLineAndCharacter().line; + const character = position.getLineAndCharacter().character; + + console.error(`${name}:${line + 1}:${character + 1}:${failure.getFailure()}`); + } + errorCount += tslintResult.failures.length; + } + } + if (errorCount > 0) { this.emit('error', 'Hygiene failed with ' + errorCount + ' errors. Check \'build/gulpfile.hygiene.js\'.'); } else { diff --git a/extensions/configuration-editing/src/extension.ts b/extensions/configuration-editing/src/extension.ts index 01badfd07681e..4b7b3e678aa7b 100644 --- a/extensions/configuration-editing/src/extension.ts +++ b/extensions/configuration-editing/src/extension.ts @@ -18,7 +18,6 @@ const decoration = vscode.window.createTextEditorDecorationType({ let pendingLaunchJsonDecoration: NodeJS.Timer; export function activate(context: vscode.ExtensionContext): void { - //keybindings.json command-suggestions context.subscriptions.push(registerKeybindingsCompletions()); diff --git a/package.json b/package.json index 8fd963690f464..8e5041622cfed 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "rimraf": "^2.2.8", "sinon": "^1.17.2", "source-map": "^0.4.4", - "tslint": "^5.8.0", + "tslint": "^5.9.1", "typescript": "2.6.1", "typescript-formatter": "4.0.1", "uglify-es": "^3.0.18", diff --git a/tslint-hygiene.json b/tslint-hygiene.json new file mode 100644 index 0000000000000..926be379b869e --- /dev/null +++ b/tslint-hygiene.json @@ -0,0 +1,6 @@ +{ + "extends": "./tslint.json", + "rules": { + "no-unused-variable": true + } +} \ No newline at end of file diff --git a/tslint.json b/tslint.json index 24a7ac86d1b30..31396c2aa56af 100644 --- a/tslint.json +++ b/tslint.json @@ -6,7 +6,6 @@ "no-string-throw": true, "no-unused-expression": true, "no-duplicate-variable": true, - // "no-unused-variable": true, // requires type information in tslint > v4 "curly": true, "class-name": true, "semicolon": [ diff --git a/yarn.lock b/yarn.lock index 07d221d90f585..54f62a0a3884e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -599,7 +599,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.1.0: +chalk@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" dependencies: @@ -804,6 +804,10 @@ commander@2.8.x: dependencies: graceful-readlink ">= 1.0.0" +commander@^2.12.1: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + commandpost@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/commandpost/-/commandpost-1.2.1.tgz#2e9c4c7508b9dc704afefaa91cab92ee6054cc68" @@ -3130,7 +3134,7 @@ js-yaml@3.6.1: argparse "^1.0.7" esprima "^2.6.0" -js-yaml@3.x, js-yaml@^3.5.1: +js-yaml@3.x, js-yaml@^3.5.1, js-yaml@^3.7.0: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" dependencies: @@ -5573,20 +5577,25 @@ tslib@^1.7.1: version "1.8.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.0.tgz#dc604ebad64bcbf696d613da6c954aa0e7ea1eb6" -tslint@^5.8.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.8.0.tgz#1f49ad5b2e77c76c3af4ddcae552ae4e3612eb13" +tslib@^1.8.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" + +tslint@^5.9.1: + version "5.9.1" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.9.1.tgz#1255f87a3ff57eb0b0e1f0e610a8b4748046c9ae" dependencies: babel-code-frame "^6.22.0" builtin-modules "^1.1.1" - chalk "^2.1.0" - commander "^2.9.0" + chalk "^2.3.0" + commander "^2.12.1" diff "^3.2.0" glob "^7.1.1" + js-yaml "^3.7.0" minimatch "^3.0.4" resolve "^1.3.2" semver "^5.3.0" - tslib "^1.7.1" + tslib "^1.8.0" tsutils "^2.12.1" tsutils@^2.12.1: