diff --git a/tools/gulp/tasks/lint.ts b/tools/gulp/tasks/lint.ts index b81ce409387..b51b84ba654 100644 --- a/tools/gulp/tasks/lint.ts +++ b/tools/gulp/tasks/lint.ts @@ -6,7 +6,6 @@ import {red} from 'chalk'; // These types lack of type definitions const madge = require('madge'); -const resolveBin = require('resolve-bin'); /** Glob that matches all SCSS or CSS files that should be linted. */ const stylesGlob = '+(tools|src)/**/!(*.bundle).+(css|scss)'; @@ -28,10 +27,10 @@ task('stylelint', execNodeTask( )); /** Task to run TSLint against the e2e/ and src/ directories. */ -task('tslint', execTsLintTask()); +task('tslint', execNodeTask('tslint', tsLintBaseFlags)); /** Task that automatically fixes TSLint warnings. */ -task('tslint:fix', execTsLintTask('--fix')); +task('tslint:fix', execNodeTask('tslint', [...tsLintBaseFlags, '--fix'])); /** Task that runs madge to detect circular dependencies. */ task('madge', ['material:clean-build'], () => { @@ -51,13 +50,3 @@ task('madge', ['material:clean-build'], () => { function formatMadgeCircularModules(circularModules: string[][]): string { return circularModules.map((modulePaths: string[]) => `\n - ${modulePaths.join(' > ')}`).join(''); } - -/** Creates a gulp task function that will run TSLint together with ts-node. */ -function execTsLintTask(...flags: string[]) { - const tslintBinPath = resolveBin.sync('tslint'); - const tsNodeOptions = ['-O', '{"module": "commonjs"}']; - - // TS-Node needs the module compiler option to be set to `commonjs` because the transpiled - // TypeScript files will be running inside of NodeJS. - return execNodeTask('ts-node', [...tsNodeOptions, tslintBinPath, ...tsLintBaseFlags, ...flags]); -} diff --git a/tools/tslint-rules/noViewEncapsulationRule.ts b/tools/tslint-rules/noViewEncapsulationRule.ts index 9b130174d50..196aa37ae34 100644 --- a/tools/tslint-rules/noViewEncapsulationRule.ts +++ b/tools/tslint-rules/noViewEncapsulationRule.ts @@ -35,17 +35,17 @@ class Walker extends Lint.RuleWalker { this._enabled = fileGlobs.some(p => minimatch(relativeFilePath, p)); } - visitClassDeclaration(node) { + visitClassDeclaration(node: ts.ClassDeclaration) { if (!this._enabled || !node.decorators) { return; } node.decorators - .map(decorator => decorator.expression) + .map(decorator => decorator.expression as any) .filter(expression => expression.expression.getText() === 'Component') .filter(expression => expression.arguments.length && expression.arguments[0].properties) .forEach(expression => { - const hasTurnedOffEncapsulation = expression.arguments[0].properties.some(prop => { + const hasTurnedOffEncapsulation = expression.arguments[0].properties.some((prop: any) => { const value = prop.initializer.getText(); return prop.name.getText() === 'encapsulation' && value.endsWith('.None'); }); diff --git a/tools/tslint-rules/tsLoaderRule.js b/tools/tslint-rules/tsLoaderRule.js new file mode 100644 index 00000000000..4ba565f1b9d --- /dev/null +++ b/tools/tslint-rules/tsLoaderRule.js @@ -0,0 +1,13 @@ +const path = require('path'); +const Lint = require('tslint'); + +// Custom rule that registers all of the custom rules, written in TypeScript, with ts-node. +// This is necessary, because `tslint` and IDEs won't execute any rules that aren't in a .js file. +require('ts-node').register({ + project: path.join(__dirname, '../gulp/tsconfig.json') +}); + +// Add a noop rule so tslint doesn't complain. +exports.Rule = class Rule extends Lint.Rules.AbstractRule { + apply() {} +} diff --git a/tslint.json b/tslint.json index 911ffe3cf7a..af2c655674a 100644 --- a/tslint.json +++ b/tslint.json @@ -85,7 +85,7 @@ "linebreak-style": [true, "LF"], // Custom Rules - + "ts-loader": true, "no-exposed-todo": true, "no-view-encapsulation": [ true,