diff --git a/.prettierignore b/.prettierignore index 2578aad23b7c..5155a78aa504 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,6 +5,7 @@ **/shared-fixtures **/.vscode **/.nyc_output +**/.vs packages/eslint-plugin-tslint/tests/test-tslint-rules-directory/alwaysFailRule.js .github packages/eslint-plugin/src/configs/*.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 258812bf53ff..19e2f00eaf38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,23 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.3.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.2.0...v3.3.0) (2020-06-15) + + +### Bug Fixes + +* **eslint-plugin:** [no-unused-expressions] handle ternary and short-circuit options ([#2194](https://github.com/typescript-eslint/typescript-eslint/issues/2194)) ([ee9f100](https://github.com/typescript-eslint/typescript-eslint/commit/ee9f100a2f9a874c2b361482742686eeaa9bdac7)) +* **typescript-estree:** handle TS4.0 breaking change in TupleType ([#2197](https://github.com/typescript-eslint/typescript-eslint/issues/2197)) ([5d68129](https://github.com/typescript-eslint/typescript-eslint/commit/5d6812914831a386997b453b4db1e3283e26005d)) + + +### Features + +* **eslint-plugin:** [naming-convention] better error message and docs for prefix/suffix ([#2195](https://github.com/typescript-eslint/typescript-eslint/issues/2195)) ([a2ffe55](https://github.com/typescript-eslint/typescript-eslint/commit/a2ffe5568df0f7224bfe9141d298e538383d5f09)) + + + + + # [3.2.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.1.0...v3.2.0) (2020-06-08) diff --git a/lerna.json b/lerna.json index f800ef645007..72afa49c8eb2 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "3.2.0", + "version": "3.3.0", "npmClient": "yarn", "useWorkspaces": true, "stream": true diff --git a/packages/eslint-plugin-internal/CHANGELOG.md b/packages/eslint-plugin-internal/CHANGELOG.md index cf4d207c638d..173a97a02190 100644 --- a/packages/eslint-plugin-internal/CHANGELOG.md +++ b/packages/eslint-plugin-internal/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.3.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.2.0...v3.3.0) (2020-06-15) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal + + + + + # [3.2.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.1.0...v3.2.0) (2020-06-08) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal diff --git a/packages/eslint-plugin-internal/package.json b/packages/eslint-plugin-internal/package.json index fcfca81cae40..aaa9957fe8ce 100644 --- a/packages/eslint-plugin-internal/package.json +++ b/packages/eslint-plugin-internal/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-internal", - "version": "3.2.0", + "version": "3.3.0", "private": true, "main": "dist/index.js", "scripts": { @@ -13,7 +13,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "3.2.0", + "@typescript-eslint/experimental-utils": "3.3.0", "prettier": "*" } } diff --git a/packages/eslint-plugin-tslint/CHANGELOG.md b/packages/eslint-plugin-tslint/CHANGELOG.md index 97ae091cf011..434977a40190 100644 --- a/packages/eslint-plugin-tslint/CHANGELOG.md +++ b/packages/eslint-plugin-tslint/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.3.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.2.0...v3.3.0) (2020-06-15) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint + + + + + # [3.2.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.1.0...v3.2.0) (2020-06-08) diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index 518c69780c54..97d415083aad 100644 --- a/packages/eslint-plugin-tslint/package.json +++ b/packages/eslint-plugin-tslint/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin-tslint", - "version": "3.2.0", + "version": "3.3.0", "main": "dist/index.js", "typings": "src/index.ts", "description": "TSLint wrapper plugin for ESLint", @@ -32,7 +32,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "3.2.0", + "@typescript-eslint/experimental-utils": "3.3.0", "lodash": "^4.17.15" }, "peerDependencies": { @@ -42,6 +42,6 @@ }, "devDependencies": { "@types/lodash": "^4.14.149", - "@typescript-eslint/parser": "3.2.0" + "@typescript-eslint/parser": "3.3.0" } } diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 23f88f63dcf7..42e7e147f901 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.3.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.2.0...v3.3.0) (2020-06-15) + + +### Bug Fixes + +* **eslint-plugin:** [no-unused-expressions] handle ternary and short-circuit options ([#2194](https://github.com/typescript-eslint/typescript-eslint/issues/2194)) ([ee9f100](https://github.com/typescript-eslint/typescript-eslint/commit/ee9f100a2f9a874c2b361482742686eeaa9bdac7)) + + +### Features + +* **eslint-plugin:** [naming-convention] better error message and docs for prefix/suffix ([#2195](https://github.com/typescript-eslint/typescript-eslint/issues/2195)) ([a2ffe55](https://github.com/typescript-eslint/typescript-eslint/commit/a2ffe5568df0f7224bfe9141d298e538383d5f09)) + + + + + # [3.2.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.1.0...v3.2.0) (2020-06-08) diff --git a/packages/eslint-plugin/docs/rules/naming-convention.md b/packages/eslint-plugin/docs/rules/naming-convention.md index 43874c6b0089..ec21837594f2 100644 --- a/packages/eslint-plugin/docs/rules/naming-convention.md +++ b/packages/eslint-plugin/docs/rules/naming-convention.md @@ -150,6 +150,8 @@ The `prefix` / `suffix` options control which prefix/suffix strings must exist f If these are provided, the identifier must start with one of the provided values. For example, if you provide `{ prefix: ['IFace', 'Class', 'Type'] }`, then the following names are valid: `IFaceFoo`, `ClassBar`, `TypeBaz`, but the name `Bang` is not valid, as it contains none of the prefixes. +**Note:** As [documented above](#format-options), the prefix is trimmed before format is validated, therefore PascalCase must be used to allow variables such as `isEnabled` using the prefix `is`. + ### Selector Options - `selector` (see "Allowed Selectors, Modifiers and Types" below). @@ -277,6 +279,8 @@ Group Selectors are provided for convenience, and essentially bundle up sets of ### Enforce that boolean variables are prefixed with an allowed verb +**Note:** As [documented above](#format-options), the prefix is trimmed before format is validated, thus PascalCase must be used to allow variables such as `isEnabled`. + ```json { "@typescript-eslint/naming-convention": [ diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index a70d608a8dc1..8ba7451b3889 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "3.2.0", + "version": "3.3.0", "description": "TypeScript plugin for ESLint", "keywords": [ "eslint", @@ -42,7 +42,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "3.2.0", + "@typescript-eslint/experimental-utils": "3.3.0", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", "semver": "^7.3.2", diff --git a/packages/eslint-plugin/src/rules/naming-convention.ts b/packages/eslint-plugin/src/rules/naming-convention.ts index d5ea49463bd3..bdbedc625ea1 100644 --- a/packages/eslint-plugin/src/rules/naming-convention.ts +++ b/packages/eslint-plugin/src/rules/naming-convention.ts @@ -12,7 +12,8 @@ type MessageIds = | 'missingUnderscore' | 'missingAffix' | 'satisfyCustom' - | 'doesNotMatchFormat'; + | 'doesNotMatchFormat' + | 'doesNotMatchFormatTrimmed'; // #region Options Type Config @@ -355,6 +356,8 @@ export default util.createRule({ '{{type}} name `{{name}}` must {{regexMatch}} the RegExp: {{regex}}', doesNotMatchFormat: '{{type}} name `{{name}}` must match one of the following formats: {{formats}}', + doesNotMatchFormatTrimmed: + '{{type}} name `{{name}}` trimmed as `{{processedName}}` must match one of the following formats: {{formats}}', }, schema: SCHEMA, }, @@ -869,18 +872,21 @@ function createValidator( affixes, formats, originalName, + processedName, position, custom, }: { affixes?: string[]; formats?: PredefinedFormats[]; originalName: string; + processedName?: string; position?: 'leading' | 'trailing' | 'prefix' | 'suffix'; custom?: NonNullable; }): Record { return { type: selectorTypeToMessageString(type), name: originalName, + processedName, position, affixes: affixes?.join(', '), formats: formats?.map(f => PredefinedFormats[f]).join(', '), @@ -1052,9 +1058,13 @@ function createValidator( context.report({ node, - messageId: 'doesNotMatchFormat', + messageId: + originalName === name + ? 'doesNotMatchFormat' + : 'doesNotMatchFormatTrimmed', data: formatReportData({ originalName, + processedName: name, formats, }), }); diff --git a/packages/eslint-plugin/src/rules/no-unused-expressions.ts b/packages/eslint-plugin/src/rules/no-unused-expressions.ts index 151b8611c247..692b484f45dc 100644 --- a/packages/eslint-plugin/src/rules/no-unused-expressions.ts +++ b/packages/eslint-plugin/src/rules/no-unused-expressions.ts @@ -1,4 +1,7 @@ -import { AST_NODE_TYPES } from '@typescript-eslint/experimental-utils'; +import { + AST_NODE_TYPES, + TSESTree, +} from '@typescript-eslint/experimental-utils'; import baseRule from 'eslint/lib/rules/no-unused-expressions'; import * as util from '../util'; @@ -18,17 +21,36 @@ export default util.createRule({ schema: baseRule.meta.schema, messages: baseRule.meta.messages, }, - defaultOptions: [], - create(context) { + defaultOptions: [ + { + allowShortCircuit: false, + allowTernary: false, + allowTaggedTemplates: false, + }, + ], + create(context, options) { const rules = baseRule.create(context); + const { allowShortCircuit = false, allowTernary = false } = options[0]; + + function isValidExpression(node: TSESTree.Node): boolean { + if (allowShortCircuit && node.type === AST_NODE_TYPES.LogicalExpression) { + return isValidExpression(node.right); + } + if (allowTernary && node.type === AST_NODE_TYPES.ConditionalExpression) { + return ( + isValidExpression(node.alternate) && + isValidExpression(node.consequent) + ); + } + return ( + node.type === AST_NODE_TYPES.OptionalCallExpression || + node.type === AST_NODE_TYPES.ImportExpression + ); + } return { ExpressionStatement(node): void { - if ( - node.directive || - node.expression.type === AST_NODE_TYPES.OptionalCallExpression || - node.expression.type === AST_NODE_TYPES.ImportExpression - ) { + if (node.directive || isValidExpression(node.expression)) { return; } diff --git a/packages/eslint-plugin/tests/rules/naming-convention.test.ts b/packages/eslint-plugin/tests/rules/naming-convention.test.ts index 13f67f6c9887..e907f26e8a66 100644 --- a/packages/eslint-plugin/tests/rules/naming-convention.test.ts +++ b/packages/eslint-plugin/tests/rules/naming-convention.test.ts @@ -864,7 +864,7 @@ ruleTester.run('naming-convention', rule, { }, ], parserOptions, - errors: Array(16).fill({ messageId: 'doesNotMatchFormat' }), + errors: Array(16).fill({ messageId: 'doesNotMatchFormatTrimmed' }), }, { code: ` @@ -886,7 +886,7 @@ ruleTester.run('naming-convention', rule, { }, ], parserOptions, - errors: Array(4).fill({ messageId: 'doesNotMatchFormat' }), + errors: Array(4).fill({ messageId: 'doesNotMatchFormatTrimmed' }), }, { code: ` @@ -918,7 +918,7 @@ ruleTester.run('naming-convention', rule, { }, ], parserOptions, - errors: Array(8).fill({ messageId: 'doesNotMatchFormat' }), + errors: Array(8).fill({ messageId: 'doesNotMatchFormatTrimmed' }), }, { code: ` diff --git a/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts b/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts index d1b782348d82..55264e918e71 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-expressions.test.ts @@ -71,6 +71,18 @@ ruleTester.run('no-unused-expressions', rule, { ` import('./foo').then(() => {}); `, + { + code: 'foo && foo?.();', + options: [{ allowShortCircuit: true }], + }, + { + code: "foo && import('./foo');", + options: [{ allowShortCircuit: true }], + }, + { + code: "foo ? import('./foo') : import('./bar');", + options: [{ allowTernary: true }], + }, ], invalid: [ { @@ -259,5 +271,29 @@ function foo() { }, ]), }, + { + code: 'foo && foo?.bar;', + options: [{ allowShortCircuit: true }], + errors: error([ + { + line: 1, + endLine: 1, + column: 1, + endColumn: 17, + }, + ]), + }, + { + code: 'foo ? foo?.bar : bar.baz;', + options: [{ allowTernary: true }], + errors: error([ + { + line: 1, + endLine: 1, + column: 1, + endColumn: 26, + }, + ]), + }, ], }); diff --git a/packages/eslint-plugin/typings/eslint-rules.d.ts b/packages/eslint-plugin/typings/eslint-rules.d.ts index c27e620399ee..31a752878b88 100644 --- a/packages/eslint-plugin/typings/eslint-rules.d.ts +++ b/packages/eslint-plugin/typings/eslint-rules.d.ts @@ -411,15 +411,13 @@ declare module 'eslint/lib/rules/no-unused-expressions' { const rule: TSESLint.RuleModule< 'expected', - ( - | 'all' - | 'local' - | { - allowShortCircuit?: boolean; - allowTernary?: boolean; - allowTaggedTemplates?: boolean; - } - )[], + [ + { + allowShortCircuit?: boolean; + allowTernary?: boolean; + allowTaggedTemplates?: boolean; + }, + ], { ExpressionStatement(node: TSESTree.ExpressionStatement): void; } diff --git a/packages/experimental-utils/CHANGELOG.md b/packages/experimental-utils/CHANGELOG.md index a394181063cf..91e2035933e6 100644 --- a/packages/experimental-utils/CHANGELOG.md +++ b/packages/experimental-utils/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.3.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.2.0...v3.3.0) (2020-06-15) + +**Note:** Version bump only for package @typescript-eslint/experimental-utils + + + + + # [3.2.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.1.0...v3.2.0) (2020-06-08) diff --git a/packages/experimental-utils/package.json b/packages/experimental-utils/package.json index d54d7dcbf6d2..e94079f0996e 100644 --- a/packages/experimental-utils/package.json +++ b/packages/experimental-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/experimental-utils", - "version": "3.2.0", + "version": "3.3.0", "description": "(Experimental) Utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -40,7 +40,7 @@ }, "dependencies": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "3.2.0", + "@typescript-eslint/typescript-estree": "3.3.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" }, diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index 889fb162a9fe..bf6cf0a44377 100644 --- a/packages/parser/CHANGELOG.md +++ b/packages/parser/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.3.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.2.0...v3.3.0) (2020-06-15) + +**Note:** Version bump only for package @typescript-eslint/parser + + + + + # [3.2.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.1.0...v3.2.0) (2020-06-08) diff --git a/packages/parser/package.json b/packages/parser/package.json index e15c62c2645a..b9ca23514946 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "3.2.0", + "version": "3.3.0", "description": "An ESLint custom parser which leverages TypeScript ESTree", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -44,13 +44,13 @@ }, "dependencies": { "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "3.2.0", - "@typescript-eslint/typescript-estree": "3.2.0", + "@typescript-eslint/experimental-utils": "3.3.0", + "@typescript-eslint/typescript-estree": "3.3.0", "eslint-visitor-keys": "^1.1.0" }, "devDependencies": { "@types/glob": "^7.1.1", - "@typescript-eslint/shared-fixtures": "3.2.0", + "@typescript-eslint/shared-fixtures": "3.3.0", "glob": "*" }, "peerDependenciesMeta": { diff --git a/packages/shared-fixtures/CHANGELOG.md b/packages/shared-fixtures/CHANGELOG.md index 7bb7bcc604ff..c3f5fcda81e9 100644 --- a/packages/shared-fixtures/CHANGELOG.md +++ b/packages/shared-fixtures/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.3.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.2.0...v3.3.0) (2020-06-15) + +**Note:** Version bump only for package @typescript-eslint/shared-fixtures + + + + + # [3.2.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.1.0...v3.2.0) (2020-06-08) **Note:** Version bump only for package @typescript-eslint/shared-fixtures diff --git a/packages/shared-fixtures/package.json b/packages/shared-fixtures/package.json index 9718dda21950..b19dae20fe3a 100644 --- a/packages/shared-fixtures/package.json +++ b/packages/shared-fixtures/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/shared-fixtures", - "version": "3.2.0", + "version": "3.3.0", "private": true, "scripts": { "build": "tsc -b tsconfig.build.json", diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index 6bb1f7b57f7f..e6b50349ca67 100644 --- a/packages/typescript-estree/CHANGELOG.md +++ b/packages/typescript-estree/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [3.3.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.2.0...v3.3.0) (2020-06-15) + + +### Bug Fixes + +* **typescript-estree:** handle TS4.0 breaking change in TupleType ([#2197](https://github.com/typescript-eslint/typescript-eslint/issues/2197)) ([5d68129](https://github.com/typescript-eslint/typescript-eslint/commit/5d6812914831a386997b453b4db1e3283e26005d)) + + + + + # [3.2.0](https://github.com/typescript-eslint/typescript-eslint/compare/v3.1.0...v3.2.0) (2020-06-08) diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index dd0a4a8ebd97..a83b562bb417 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "3.2.0", + "version": "3.3.0", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -59,7 +59,7 @@ "@types/lodash": "^4.14.149", "@types/semver": "^7.1.0", "@types/tmp": "^0.2.0", - "@typescript-eslint/shared-fixtures": "3.2.0", + "@typescript-eslint/shared-fixtures": "3.3.0", "tmp": "^0.2.1", "typescript": "*" }, diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 44279a76d97e..2a6db370570b 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -2617,9 +2617,16 @@ export class Converter { }); } case SyntaxKind.TupleType: { + // In TS 4.0, the `elementTypes` property was changed to `elements`. + // To support both at compile time, we cast to access the newer version + // if the former does not exist. + const elementTypes = node.elementTypes + ? node.elementTypes.map(el => this.convertType(el)) + : (node as any).elements.map((el: ts.Node) => this.convertType(el)); + return this.createNode(node, { type: AST_NODE_TYPES.TSTupleType, - elementTypes: node.elementTypes.map(el => this.convertType(el)), + elementTypes, }); } case SyntaxKind.UnionType: {