From b087b5da3c1520c1c7f79358f4a49d90e69e86a4 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Thu, 14 Mar 2019 19:37:06 -0700 Subject: [PATCH 1/3] feat(eslint-plugin): Regenerate recommended config Also fix the bugs in the generation script. --- packages/eslint-plugin/package.json | 2 +- .../src/configs/recommended.json | 3 ++ packages/eslint-plugin/src/util/misc.ts | 4 ++- .../eslint-plugin/tools/update-recommended.ts | 34 +++++++++---------- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 95c90865e32d..12e0a7baf358 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -28,7 +28,7 @@ "docs": "eslint-docs", "docs:check": "eslint-docs check", "test": "jest --coverage", - "recommended:update": "ts-node tools/update-recommended.ts", + "recommended:update": "ts-node --files tools/update-recommended.ts", "prebuild": "npm run clean", "build": "tsc -p tsconfig.build.json", "clean": "rimraf dist/", diff --git a/packages/eslint-plugin/src/configs/recommended.json b/packages/eslint-plugin/src/configs/recommended.json index e107a6457248..1032727f5765 100644 --- a/packages/eslint-plugin/src/configs/recommended.json +++ b/packages/eslint-plugin/src/configs/recommended.json @@ -7,6 +7,7 @@ "rules": { "@typescript-eslint/adjacent-overload-signatures": "error", "@typescript-eslint/array-type": "error", + "@typescript-eslint/ban-ts-ignore": "error", "@typescript-eslint/ban-types": "error", "camelcase": "off", "@typescript-eslint/camelcase": "error", @@ -28,6 +29,7 @@ "@typescript-eslint/no-non-null-assertion": "error", "@typescript-eslint/no-object-literal-type-assertion": "error", "@typescript-eslint/no-parameter-properties": "error", + "@typescript-eslint/no-require-imports": "error", "@typescript-eslint/no-triple-slash-reference": "error", "no-unused-vars": "off", "@typescript-eslint/no-unused-vars": "warn", @@ -35,6 +37,7 @@ "@typescript-eslint/no-var-requires": "error", "@typescript-eslint/prefer-interface": "error", "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/promise-function-async": "error", "@typescript-eslint/type-annotation-spacing": "error" } } diff --git a/packages/eslint-plugin/src/util/misc.ts b/packages/eslint-plugin/src/util/misc.ts index ab56cd4e694e..9279f2a7c3ab 100644 --- a/packages/eslint-plugin/src/util/misc.ts +++ b/packages/eslint-plugin/src/util/misc.ts @@ -77,7 +77,9 @@ export function getNameFromClassMember( return getNameFromPropertyName(methodDefinition.key); } - return sourceCode.text.slice(...methodDefinition.key.range); + return sourceCode.text.slice( + ...(methodDefinition.key as TSESTree.Expression).range, + ); } /** diff --git a/packages/eslint-plugin/tools/update-recommended.ts b/packages/eslint-plugin/tools/update-recommended.ts index 39861d35ee74..cc4a2d8c5bd7 100644 --- a/packages/eslint-plugin/tools/update-recommended.ts +++ b/packages/eslint-plugin/tools/update-recommended.ts @@ -3,6 +3,7 @@ import path from 'path'; import fs from 'fs'; import requireIndex from 'requireindex'; +import RuleModule from 'ts-eslint'; const bannedRecommendedRules = new Set([ 'camelcase', @@ -10,7 +11,7 @@ const bannedRecommendedRules = new Set([ 'no-array-constructor', 'no-unused-vars', ]); -const MAX_RULE_NAME_LENGTH = 32 + 'typescript/'.length; +const MAX_RULE_NAME_LENGTH = 40 + 'typescript/'.length; function padEnd(str: string, length: number): string { while (str.length < length) { @@ -24,29 +25,28 @@ function padEnd(str: string, length: number): string { */ function generate(): void { // replace this with Object.entries when node > 8 - const allRules = requireIndex(path.resolve(__dirname, '../dist/lib/rules')); + const allRules: Record< + string, + { default: RuleModule } + > = requireIndex(path.resolve(__dirname, '../dist/rules')); const rules = Object.keys(allRules) - .filter(key => !!allRules[key].meta.docs.recommended) - .reduce>((config, key) => { + .map(key => ({ ...allRules[key].default, name: key })) + .filter(rule => { + return !!rule.meta.docs.recommended; + }) + .reduce>((config, rule) => { // having this here is just for output niceness (the keys will be ordered) - if (bannedRecommendedRules.has(key)) { - console.log(padEnd(key, MAX_RULE_NAME_LENGTH), '= off'); - config[key] = 'off'; + if (bannedRecommendedRules.has(rule.name)) { + console.log(padEnd(rule.name, MAX_RULE_NAME_LENGTH), '= off'); + config[rule.name] = 'off'; } - const ruleName = `@typescript-eslint/${key}`; - const setting = allRules[key].meta.docs.recommended; + const ruleName = `@typescript-eslint/${rule.name}`; + const setting = rule.meta.docs.recommended as string; - if (!['error', 'warn'].includes(setting)) { - console.log(`ERR! Invalid level for rule ${key}: "${setting}"`); - // Don't want to throw an error since ^ explains what happened. - // eslint-disable-next-line no-process-exit - process.exit(1); - } - - console.log(padEnd(ruleName, MAX_RULE_NAME_LENGTH), '=', setting); config[ruleName] = setting; + console.log(padEnd(ruleName, MAX_RULE_NAME_LENGTH), '=', setting); return config; }, {}); From 47cbcd92f9271d1cb45662d60f7744eb1bd53854 Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 15 Mar 2019 09:53:10 -0700 Subject: [PATCH 2/3] fix lint errors, remove promise-function-async from recommended so we don't force project config yet --- .eslintrc.js | 75 +++++++++++++++++++ .eslintrc.json | 66 ---------------- .../src/configs/recommended.json | 1 - .../src/rules/promise-function-async.ts | 2 +- packages/eslint-plugin/src/util/createRule.ts | 1 + packages/parser/src/parser.ts | 1 + packages/typescript-estree/src/parser.ts | 2 + .../tests/ast-alignment/parse.ts | 1 + .../utils/generate-package-json.js | 2 + 9 files changed, 83 insertions(+), 68 deletions(-) create mode 100644 .eslintrc.js delete mode 100644 .eslintrc.json diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000000..ffd3e7f460c6 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,75 @@ +module.exports = { + root: true, + plugins: ['eslint-plugin', '@typescript-eslint', 'jest'], + env: { + es6: true, + node: true, + }, + extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + rules: { + 'comma-dangle': ['error', 'always-multiline'], + 'no-mixed-operators': 'error', + 'no-console': 'off', + 'no-undef': 'off', + + // TODO - enable these rules as we clean up the codebase + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-member-accessibility': 'off', + '@typescript-eslint/indent': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-object-literal-type-assertion': 'off', + '@typescript-eslint/no-parameter-properties': 'off', + '@typescript-eslint/no-use-before-define': 'off', + '@typescript-eslint/no-var-requires': 'off', + }, + parserOptions: { + sourceType: 'module', + ecmaFeatures: { + jsx: false, + }, + // TODO - when we enable rules with typechecking + // project: [ + // './packages/eslint-plugin/tsconfig.json', + // './packages/eslint-plugin-tslint/tsconfig.json', + // './packages/parser/tsconfig.json', + // './packages/typescript-estree/tsconfig.json', + // ], + }, + overrides: [ + { + files: [ + 'packages/eslint-plugin-tslint/tests/**/*.ts', + 'packages/eslint-plugin/tests/**/*.test.ts', + 'packages/parser/tests/**/*.ts', + 'packages/typescript-estree/tests/**/*.ts', + ], + env: { + 'jest/globals': true, + }, + rules: { + 'jest/no-disabled-tests': 'warn', + 'jest/no-focused-tests': 'error', + 'jest/no-alias-methods': 'error', + 'jest/no-identical-title': 'error', + 'jest/no-jasmine-globals': 'error', + 'jest/no-jest-import': 'error', + 'jest/no-test-prefixes': 'error', + 'jest/no-test-callback': 'error', + 'jest/no-test-return-statement': 'error', + 'jest/prefer-to-have-length': 'warn', + 'jest/prefer-spy-on': 'error', + 'jest/valid-expect': 'error', + }, + }, + { + files: [ + 'packages/eslint-plugin/test/**/*.ts', + 'packages/eslint-plugin-tslint/tests/**/*.spec.ts', + ], + rules: { + 'eslint-plugin/no-identical-tests': 'error', + }, + }, + ], +}; diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index e3abc256901a..000000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "root": true, - "plugins": ["eslint-plugin", "@typescript-eslint", "jest"], - "env": { - "es6": true, - "node": true - }, - "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], - "rules": { - "comma-dangle": ["error", "always-multiline"], - "no-mixed-operators": "error", - "no-console": "off", - "no-undef": "off", - "@typescript-eslint/indent": "off", - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-non-null-assertion": "off", - "@typescript-eslint/explicit-function-return-type": "off", - "@typescript-eslint/explicit-member-accessibility": "off", - "@typescript-eslint/no-var-requires": "off", - "@typescript-eslint/no-use-before-define": "off", - "@typescript-eslint/no-object-literal-type-assertion": "off", - "@typescript-eslint/no-parameter-properties": "off" - }, - "parserOptions": { - "sourceType": "module", - "ecmaFeatures": { - "jsx": false - } - }, - "overrides": [ - { - "files": [ - "packages/eslint-plugin-tslint/tests/**/*.ts", - "packages/eslint-plugin/tests/**/*.test.ts", - "packages/parser/tests/**/*.ts", - "packages/typescript-estree/tests/**/*.ts" - ], - "env": { - "jest/globals": true - }, - "rules": { - "jest/no-disabled-tests": "warn", - "jest/no-focused-tests": "error", - "jest/no-alias-methods": "error", - "jest/no-identical-title": "error", - "jest/no-jasmine-globals": "error", - "jest/no-jest-import": "error", - "jest/no-test-prefixes": "error", - "jest/no-test-callback": "error", - "jest/no-test-return-statement": "error", - "jest/prefer-to-have-length": "warn", - "jest/prefer-spy-on": "error", - "jest/valid-expect": "error" - } - }, - { - "files": [ - "packages/eslint-plugin/test/**/*.ts", - "packages/eslint-plugin-tslint/tests/**/*.spec.ts" - ], - "rules": { - "eslint-plugin/no-identical-tests": "error" - } - } - ] -} diff --git a/packages/eslint-plugin/src/configs/recommended.json b/packages/eslint-plugin/src/configs/recommended.json index 1032727f5765..7acf51fccca9 100644 --- a/packages/eslint-plugin/src/configs/recommended.json +++ b/packages/eslint-plugin/src/configs/recommended.json @@ -37,7 +37,6 @@ "@typescript-eslint/no-var-requires": "error", "@typescript-eslint/prefer-interface": "error", "@typescript-eslint/prefer-namespace-keyword": "error", - "@typescript-eslint/promise-function-async": "error", "@typescript-eslint/type-annotation-spacing": "error" } } diff --git a/packages/eslint-plugin/src/rules/promise-function-async.ts b/packages/eslint-plugin/src/rules/promise-function-async.ts index 75d2ccdacc7e..18236b046cb6 100644 --- a/packages/eslint-plugin/src/rules/promise-function-async.ts +++ b/packages/eslint-plugin/src/rules/promise-function-async.ts @@ -21,7 +21,7 @@ export default util.createRule({ 'Requires any function or method that returns a Promise to be marked async.', tslintName: 'promise-function-async', category: 'Best Practices', - recommended: 'error', + recommended: false, }, messages: { missingAsync: 'Functions that return promises must be async.', diff --git a/packages/eslint-plugin/src/util/createRule.ts b/packages/eslint-plugin/src/util/createRule.ts index 97b0f18c51e1..8af046e8f30e 100644 --- a/packages/eslint-plugin/src/util/createRule.ts +++ b/packages/eslint-plugin/src/util/createRule.ts @@ -7,6 +7,7 @@ import RuleModule, { import { applyDefault } from './applyDefault'; // note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder +// eslint-disable-next-line @typescript-eslint/no-require-imports const version = require('../../package.json').version; // Utility type to remove a list of properties from an object diff --git a/packages/parser/src/parser.ts b/packages/parser/src/parser.ts index fa5aa39dfdc4..5259e2ab1ed2 100644 --- a/packages/parser/src/parser.ts +++ b/packages/parser/src/parser.ts @@ -10,6 +10,7 @@ import { ParserOptions } from './parser-options'; import { visitorKeys } from './visitor-keys'; // note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder +// eslint-disable-next-line @typescript-eslint/no-require-imports const packageJSON = require('../package.json'); interface ParseForESLintResult { diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index 28a0c157a29e..5691a23236df 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -278,6 +278,8 @@ export interface ParseAndGenerateServicesResult { // Public //------------------------------------------------------------------------------ +// note - cannot migrate this to an import statement because it will make TSC copy the package.json to the dist folder +// eslint-disable-next-line @typescript-eslint/no-require-imports export const version: string = require('../package.json').version; export function parse( diff --git a/packages/typescript-estree/tests/ast-alignment/parse.ts b/packages/typescript-estree/tests/ast-alignment/parse.ts index 6113f4ab5b80..397b76a2d4c4 100644 --- a/packages/typescript-estree/tests/ast-alignment/parse.ts +++ b/packages/typescript-estree/tests/ast-alignment/parse.ts @@ -14,6 +14,7 @@ function createError(message: string, line: number, column: number) { } function parseWithBabelParser(text: string, jsx: boolean = true) { + // eslint-disable-next-line @typescript-eslint/no-require-imports const babel = require('@babel/parser'); const plugins: ParserPlugin[] = [ 'typescript', diff --git a/tests/integration/utils/generate-package-json.js b/tests/integration/utils/generate-package-json.js index bf173d5e35c4..60b734f9012e 100644 --- a/tests/integration/utils/generate-package-json.js +++ b/tests/integration/utils/generate-package-json.js @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ + const fs = require('fs'); const rootPackageJSON = require('/usr/root-package.json'); From 886eff76f9b31071ba2a5925a77507f57f42ff1c Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Fri, 15 Mar 2019 09:59:13 -0700 Subject: [PATCH 3/3] fix ts-ignore lint errors --- packages/parser/src/analyze-scope.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/parser/src/analyze-scope.ts b/packages/parser/src/analyze-scope.ts index 92390dbf0d34..b3cbb2c8123d 100644 --- a/packages/parser/src/analyze-scope.ts +++ b/packages/parser/src/analyze-scope.ts @@ -118,7 +118,6 @@ class Referencer extends OriginalReferencer { visitor.visit(node); if (options.processRightHandNodes) { - // @ts-ignore visitor.rightHandNodes.forEach(this.visit, this); } } @@ -151,7 +150,6 @@ class Referencer extends OriginalReferencer { const def = defs[i]; if ( def.type === 'FunctionName' && - // @ts-ignore def.node.type === 'TSDeclareFunction' ) { defs.splice(i, 1);