From 0971245005aa0b3327e231281831e6d2d5997fd3 Mon Sep 17 00:00:00 2001 From: Drew Wyatt Date: Sun, 31 May 2020 12:32:14 -0400 Subject: [PATCH 01/10] feat(eslint-plugin): add ban-tslint-comment rule add a lint rule to flag tslint rule-flags (e.g. tslint:disable) to be used when migrating from tslint to eslint --- .../src/rules/ban-tslint-comment.ts | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 packages/eslint-plugin/src/rules/ban-tslint-comment.ts diff --git a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts new file mode 100644 index 000000000000..976fd0e0d8bd --- /dev/null +++ b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts @@ -0,0 +1,60 @@ +import { AST_TOKEN_TYPES } from '@typescript-eslint/experimental-utils'; +import * as util from '../util'; + +// tslint regex +// https://github.com/palantir/tslint/blob/95d9d958833fd9dc0002d18cbe34db20d0fbf437/src/enableDisableRules.ts#L32 +const ENABLE_DISABLE_REGEX = /^\s*tslint:(enable|disable)(?:-(line|next-line))?(:|\s|$)/; + +const toText = ( + text: string, + type: AST_TOKEN_TYPES.Line | AST_TOKEN_TYPES.Block, +): string => + type === AST_TOKEN_TYPES.Line + ? ['//', text.trim()].join(' ') + : ['/*', text.trim(), '*/'].join(' '); + +export default util.createRule({ + name: 'ban-tslint-comments', + meta: { + type: 'suggestion', + docs: { + description: 'Bans `// @tslint:` comments from being used', + category: 'Stylistic Issues', + recommended: 'warn', + }, + messages: { + commentDetected: 'tslint comment detected: "{{ text }}"', + }, + schema: [], + fixable: 'code', + }, + defaultOptions: [], + create: context => { + const sourceCode = context.getSourceCode(); + return { + Program(): void { + const comments = sourceCode.getAllComments(); + comments.forEach(c => { + if (ENABLE_DISABLE_REGEX.test(c.value)) { + context.report({ + data: { text: toText(c.value, c.type) }, + node: c, + messageId: 'commentDetected', + fix(fixer) { + const rangeStart = sourceCode.getIndexFromLoc({ + column: c.loc.start.column > 0 ? c.loc.start.column - 1 : 0, + line: c.loc.start.line, + }); + const rangeEnd = sourceCode.getIndexFromLoc({ + column: c.loc.end.column, + line: c.loc.end.line, + }); + return fixer.removeRange([rangeStart, rangeEnd + 1]); + }, + }); + } + }); + }, + }; + }, +}); From f8006ebf2c1c71987b28ae51cb1db080af67e938 Mon Sep 17 00:00:00 2001 From: Drew Wyatt Date: Sun, 31 May 2020 13:13:52 -0400 Subject: [PATCH 02/10] test(eslint-plugin): add tests for ban-tslint-comment --- .../src/rules/ban-tslint-comment.ts | 2 +- .../tests/rules/ban-tslint-comment.ts | 84 +++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 packages/eslint-plugin/tests/rules/ban-tslint-comment.ts diff --git a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts index 976fd0e0d8bd..18267ae2afde 100644 --- a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts +++ b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts @@ -14,7 +14,7 @@ const toText = ( : ['/*', text.trim(), '*/'].join(' '); export default util.createRule({ - name: 'ban-tslint-comments', + name: 'ban-tslint-comment', meta: { type: 'suggestion', docs: { diff --git a/packages/eslint-plugin/tests/rules/ban-tslint-comment.ts b/packages/eslint-plugin/tests/rules/ban-tslint-comment.ts new file mode 100644 index 000000000000..654bb18c2c63 --- /dev/null +++ b/packages/eslint-plugin/tests/rules/ban-tslint-comment.ts @@ -0,0 +1,84 @@ +import rule from '../../src/rules/ban-tslint-comment'; +import { RuleTester } from '../RuleTester'; + +interface Testable { + code: string; + text?: string; + column?: number; + line?: number; + output?: string; +} + +const PALANTIR_EXAMPLES: Testable[] = [ + { code: '/* tslint:disable */' }, // Disable all rules for the rest of the file + { code: '/* tslint:enable */' }, // Enable all rules for the rest of the file + { + code: '/* tslint:disable:rule1 rule2 rule3... */', + }, // Disable the listed rules for the rest of the file + { + code: '/* tslint:enable:rule1 rule2 rule3... */', + }, // Enable the listed rules for the rest of the file + { code: '// tslint:disable-next-line' }, // Disables all rules for the following line + { + code: 'someCode(); // tslint:disable-line', + text: '// tslint:disable-line', + column: 13, + output: 'someCode();', + }, // Disables all rules for the current line + { + code: '// tslint:disable-next-line:rule1 rule2 rule3...', + }, // Disables the listed rules for the next line +]; + +// prettier-ignore +const MORE_EXAMPLES: Testable[] = [ + { + code: `const woah = doSomeStuff(); +// tslint:disable-line +console.log(woah); +`, + output: `const woah = doSomeStuff(); +console.log(woah); +`, + text: '// tslint:disable-line', + line: 2, + }, +] + +const ruleTester = new RuleTester({ + parser: '@typescript-eslint/parser', +}); + +ruleTester.run('ban-tslint-comment', rule, { + valid: [ + { + code: 'let a: readonly any[] = [];', + }, + { + code: 'let a = new Array();', + }, + { + code: '// some other comment', + }, + { + code: '// TODO: this is a comment that mentions tslint', + }, + { + code: '/* another comment that mentions tslint */', + }, + ], + invalid: [...PALANTIR_EXAMPLES, ...MORE_EXAMPLES].map( + ({ code, column, line, output, text }) => ({ + code, + output: output ?? '', + errors: [ + { + column: column ?? 1, + line: line ?? 1, + data: { text: text ?? code }, + messageId: 'commentDetected' as const, + }, + ], + }), + ), +}); From d21aa56c6bf54302f51c7cbd9dba11a9be071890 Mon Sep 17 00:00:00 2001 From: Drew Wyatt Date: Sun, 31 May 2020 13:32:40 -0400 Subject: [PATCH 03/10] fix(eslint-plugin): export ban-tslint-comment from rules/index.ts --- packages/eslint-plugin/src/rules/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/eslint-plugin/src/rules/index.ts b/packages/eslint-plugin/src/rules/index.ts index 03ebb633b008..df22a15aefd9 100644 --- a/packages/eslint-plugin/src/rules/index.ts +++ b/packages/eslint-plugin/src/rules/index.ts @@ -2,6 +2,7 @@ import adjacentOverloadSignatures from './adjacent-overload-signatures'; import arrayType from './array-type'; import awaitThenable from './await-thenable'; import banTsComment from './ban-ts-comment'; +import banTslintComment from './ban-tslint-comment'; import banTypes from './ban-types'; import braceStyle from './brace-style'; import classLiteralPropertyStyle from './class-literal-property-style'; @@ -100,6 +101,7 @@ export default { 'array-type': arrayType, 'await-thenable': awaitThenable, 'ban-ts-comment': banTsComment, + 'ban-tslint-comment': banTslintComment, 'ban-types': banTypes, 'brace-style': braceStyle, 'class-literal-property-style': classLiteralPropertyStyle, From b4761940834492db48acd1dbef1f14761559cbf0 Mon Sep 17 00:00:00 2001 From: Drew Wyatt Date: Sun, 31 May 2020 13:44:55 -0400 Subject: [PATCH 04/10] docs(eslint-plugin): add ban-tslint-comment docs --- .../docs/rules/ban-tslint-comment.md | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 packages/eslint-plugin/docs/rules/ban-tslint-comment.md diff --git a/packages/eslint-plugin/docs/rules/ban-tslint-comment.md b/packages/eslint-plugin/docs/rules/ban-tslint-comment.md new file mode 100644 index 000000000000..f917b691b8b6 --- /dev/null +++ b/packages/eslint-plugin/docs/rules/ban-tslint-comment.md @@ -0,0 +1,29 @@ +# Bans `// @tslint:` comments from being used (`ban-tslint-comment`) + +Useful when migrating from tslint to eslint. Once tslint has been removed, this rule helps locate tslint annotations (e.g. `// tslint:disable`). + +## Rule Details + +Examples of **incorrect** code for this rule: + +All tslint [rule flags](https://palantir.github.io/tslint/usage/rule-flags/) + +```js +/* tslint:disable */ +/* tslint:enable */ +/* tslint:disable:rule1 rule2 rule3... */ +/* tslint:enable:rule1 rule2 rule3... */ +// tslint:disable-next-line +someCode(); // tslint:disable-line +// tslint:disable-next-line:rule1 rule2 rule3... +``` + +Examples of **correct** code for this rule: + +```js +// This is a comment that just happens to mention tslint +``` + +## When Not To Use It + +If you are still using tslint. From cbf9fe033a408857de0e7f4f2bfa65b4cb63fdf8 Mon Sep 17 00:00:00 2001 From: Drew Wyatt Date: Sun, 31 May 2020 13:53:49 -0400 Subject: [PATCH 05/10] style(eslint-plugin): capitalize "TSLint" and "ESLint" in ban-tslint-comment docs --- packages/eslint-plugin/docs/rules/ban-tslint-comment.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/ban-tslint-comment.md b/packages/eslint-plugin/docs/rules/ban-tslint-comment.md index f917b691b8b6..c9bfc0d9ca4c 100644 --- a/packages/eslint-plugin/docs/rules/ban-tslint-comment.md +++ b/packages/eslint-plugin/docs/rules/ban-tslint-comment.md @@ -1,12 +1,12 @@ # Bans `// @tslint:` comments from being used (`ban-tslint-comment`) -Useful when migrating from tslint to eslint. Once tslint has been removed, this rule helps locate tslint annotations (e.g. `// tslint:disable`). +Useful when migrating from TSLint to ESLint. Once TSLint has been removed, this rule helps locate TSLint annotations (e.g. `// tslint:disable`). ## Rule Details Examples of **incorrect** code for this rule: -All tslint [rule flags](https://palantir.github.io/tslint/usage/rule-flags/) +All TSLint [rule flags](https://palantir.github.io/tslint/usage/rule-flags/) ```js /* tslint:disable */ @@ -26,4 +26,4 @@ Examples of **correct** code for this rule: ## When Not To Use It -If you are still using tslint. +If you are still using TSLint. From ee7222907a34a57321227401a67810911f4e0b6f Mon Sep 17 00:00:00 2001 From: Drew Wyatt Date: Sun, 31 May 2020 13:59:21 -0400 Subject: [PATCH 06/10] docs(eslint-plugin): add ban-tslint-comment to readme and remove "@" from comment texts --- packages/eslint-plugin/README.md | 1 + packages/eslint-plugin/docs/rules/ban-tslint-comment.md | 2 +- packages/eslint-plugin/src/rules/ban-tslint-comment.ts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index 975bb88f08b2..b7c6ecbe7da1 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -93,6 +93,7 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int | [`@typescript-eslint/array-type`](./docs/rules/array-type.md) | Requires using either `T[]` or `Array` for arrays | | :wrench: | | | [`@typescript-eslint/await-thenable`](./docs/rules/await-thenable.md) | Disallows awaiting a value that is not a Thenable | :heavy_check_mark: | | :thought_balloon: | | [`@typescript-eslint/ban-ts-comment`](./docs/rules/ban-ts-comment.md) | Bans `// @ts-` comments from being used or requires descriptions after directive | :heavy_check_mark: | | | +| [`@typescript-eslint/ban-tslint-comment`](./docs/rules/ban-tslint-comment.md) | Bans `// tslint:` comments from being used | :heavy_check_mark: | :wrench: | | | [`@typescript-eslint/ban-types`](./docs/rules/ban-types.md) | Bans specific types from being used | :heavy_check_mark: | :wrench: | | | [`@typescript-eslint/class-literal-property-style`](./docs/rules/class-literal-property-style.md) | Ensures that literals on classes are exposed in a consistent style | | :wrench: | | | [`@typescript-eslint/consistent-type-assertions`](./docs/rules/consistent-type-assertions.md) | Enforces consistent usage of type assertions | | | | diff --git a/packages/eslint-plugin/docs/rules/ban-tslint-comment.md b/packages/eslint-plugin/docs/rules/ban-tslint-comment.md index c9bfc0d9ca4c..6af168f4bc4e 100644 --- a/packages/eslint-plugin/docs/rules/ban-tslint-comment.md +++ b/packages/eslint-plugin/docs/rules/ban-tslint-comment.md @@ -1,4 +1,4 @@ -# Bans `// @tslint:` comments from being used (`ban-tslint-comment`) +# Bans `// tslint:` comments from being used (`ban-tslint-comment`) Useful when migrating from TSLint to ESLint. Once TSLint has been removed, this rule helps locate TSLint annotations (e.g. `// tslint:disable`). diff --git a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts index 18267ae2afde..7180e5347a74 100644 --- a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts +++ b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts @@ -18,7 +18,7 @@ export default util.createRule({ meta: { type: 'suggestion', docs: { - description: 'Bans `// @tslint:` comments from being used', + description: 'Bans `// tslint:` comments from being used', category: 'Stylistic Issues', recommended: 'warn', }, From 5b1be2474df5f55f2c317f4bf6ecdaa1f5e8f0e9 Mon Sep 17 00:00:00 2001 From: Drew Wyatt Date: Sun, 31 May 2020 14:16:56 -0400 Subject: [PATCH 07/10] feat(eslint-plugin): add ban-tslint-comment to all/recommended configs --- packages/eslint-plugin/src/configs/all.ts | 1 + packages/eslint-plugin/src/configs/recommended.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/eslint-plugin/src/configs/all.ts b/packages/eslint-plugin/src/configs/all.ts index a02d6db9d696..10c8c6e2c99d 100644 --- a/packages/eslint-plugin/src/configs/all.ts +++ b/packages/eslint-plugin/src/configs/all.ts @@ -5,6 +5,7 @@ export = { '@typescript-eslint/array-type': 'error', '@typescript-eslint/await-thenable': 'error', '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/ban-tslint-comment': 'error', '@typescript-eslint/ban-types': 'error', 'brace-style': 'off', '@typescript-eslint/brace-style': 'error', diff --git a/packages/eslint-plugin/src/configs/recommended.ts b/packages/eslint-plugin/src/configs/recommended.ts index 8aac1a8a3b01..dc09eb7f349a 100644 --- a/packages/eslint-plugin/src/configs/recommended.ts +++ b/packages/eslint-plugin/src/configs/recommended.ts @@ -3,6 +3,7 @@ export = { rules: { '@typescript-eslint/adjacent-overload-signatures': 'error', '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/ban-tslint-comment': 'warn', '@typescript-eslint/ban-types': 'error', '@typescript-eslint/explicit-module-boundary-types': 'warn', 'no-array-constructor': 'off', From 2335645bbd155e93245da774f6e76895d3a14e31 Mon Sep 17 00:00:00 2001 From: Drew Wyatt Date: Sun, 31 May 2020 15:46:28 -0400 Subject: [PATCH 08/10] Update packages/eslint-plugin/src/rules/ban-tslint-comment.ts Co-authored-by: Brad Zacher --- packages/eslint-plugin/src/rules/ban-tslint-comment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts index 7180e5347a74..4521fcb13c36 100644 --- a/packages/eslint-plugin/src/rules/ban-tslint-comment.ts +++ b/packages/eslint-plugin/src/rules/ban-tslint-comment.ts @@ -20,7 +20,7 @@ export default util.createRule({ docs: { description: 'Bans `// tslint:` comments from being used', category: 'Stylistic Issues', - recommended: 'warn', + recommended: false, }, messages: { commentDetected: 'tslint comment detected: "{{ text }}"', From c53d50c9586943c8158e713c16e3dfb199e18beb Mon Sep 17 00:00:00 2001 From: Drew Wyatt Date: Sun, 31 May 2020 15:48:11 -0400 Subject: [PATCH 09/10] test(eslint-plugin): add ".test" to file name --- packages/eslint-plugin/src/configs/recommended.ts | 1 - .../rules/{ban-tslint-comment.ts => ban-tslint-comment.test.ts} | 0 2 files changed, 1 deletion(-) rename packages/eslint-plugin/tests/rules/{ban-tslint-comment.ts => ban-tslint-comment.test.ts} (100%) diff --git a/packages/eslint-plugin/src/configs/recommended.ts b/packages/eslint-plugin/src/configs/recommended.ts index dc09eb7f349a..8aac1a8a3b01 100644 --- a/packages/eslint-plugin/src/configs/recommended.ts +++ b/packages/eslint-plugin/src/configs/recommended.ts @@ -3,7 +3,6 @@ export = { rules: { '@typescript-eslint/adjacent-overload-signatures': 'error', '@typescript-eslint/ban-ts-comment': 'error', - '@typescript-eslint/ban-tslint-comment': 'warn', '@typescript-eslint/ban-types': 'error', '@typescript-eslint/explicit-module-boundary-types': 'warn', 'no-array-constructor': 'off', diff --git a/packages/eslint-plugin/tests/rules/ban-tslint-comment.ts b/packages/eslint-plugin/tests/rules/ban-tslint-comment.test.ts similarity index 100% rename from packages/eslint-plugin/tests/rules/ban-tslint-comment.ts rename to packages/eslint-plugin/tests/rules/ban-tslint-comment.test.ts From 1f1317b4820ae145de4d74077cae7852dd213c49 Mon Sep 17 00:00:00 2001 From: Drew Wyatt Date: Sun, 31 May 2020 15:53:12 -0400 Subject: [PATCH 10/10] docs(eslint-plugin): remove recommended checkmark --- packages/eslint-plugin/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index b7c6ecbe7da1..25b412cd554e 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -93,7 +93,7 @@ Pro Tip: For larger codebases you may want to consider splitting our linting int | [`@typescript-eslint/array-type`](./docs/rules/array-type.md) | Requires using either `T[]` or `Array` for arrays | | :wrench: | | | [`@typescript-eslint/await-thenable`](./docs/rules/await-thenable.md) | Disallows awaiting a value that is not a Thenable | :heavy_check_mark: | | :thought_balloon: | | [`@typescript-eslint/ban-ts-comment`](./docs/rules/ban-ts-comment.md) | Bans `// @ts-` comments from being used or requires descriptions after directive | :heavy_check_mark: | | | -| [`@typescript-eslint/ban-tslint-comment`](./docs/rules/ban-tslint-comment.md) | Bans `// tslint:` comments from being used | :heavy_check_mark: | :wrench: | | +| [`@typescript-eslint/ban-tslint-comment`](./docs/rules/ban-tslint-comment.md) | Bans `// tslint:` comments from being used | | :wrench: | | | [`@typescript-eslint/ban-types`](./docs/rules/ban-types.md) | Bans specific types from being used | :heavy_check_mark: | :wrench: | | | [`@typescript-eslint/class-literal-property-style`](./docs/rules/class-literal-property-style.md) | Ensures that literals on classes are exposed in a consistent style | | :wrench: | | | [`@typescript-eslint/consistent-type-assertions`](./docs/rules/consistent-type-assertions.md) | Enforces consistent usage of type assertions | | | |