diff --git a/CHANGELOG.md b/CHANGELOG.md index 42c87af74e73..421b584b1b9a 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. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + + +### Bug Fixes + +* **eslint-plugin:** [consistent-type-definitions] remove fixer when the interface is within a global module declaration ([#2739](https://github.com/typescript-eslint/typescript-eslint/issues/2739)) ([2326238](https://github.com/typescript-eslint/typescript-eslint/commit/2326238738c95acfc14c17f9b16798f1de6d267f)) +* **eslint-plugin:** [no-unsafe-member-access] ignore MemberExpression's whose parents are either TSClassImplements or TSInterfaceHeritage ([#2753](https://github.com/typescript-eslint/typescript-eslint/issues/2753)) ([535db3b](https://github.com/typescript-eslint/typescript-eslint/commit/535db3bf27ee1d7824ada9acd91d1b7833064628)) + + +### Features + +* **typescript-estree:** add `parseWithNodeMaps` API ([#2760](https://github.com/typescript-eslint/typescript-eslint/issues/2760)) ([9441d50](https://github.com/typescript-eslint/typescript-eslint/commit/9441d5030211f1c32f5ae8e61d5565cab8bb6823)), closes [#1852](https://github.com/typescript-eslint/typescript-eslint/issues/1852) + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) @@ -14,7 +31,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ### Features -* **eslint-plugin:** add rule `no-void-expression` ([#2605](https://github.com/typescript-eslint/typescript-eslint/issues/2605)) ([c8a4dad](https://github.com/typescript-eslint/typescript-eslint/commit/c8a4dadeab8a64fb4768deda8f65475435dd2cad)) +* **eslint-plugin:** add rule `no-confusing-void-expression` ([#2605](https://github.com/typescript-eslint/typescript-eslint/issues/2605)) ([c8a4dad](https://github.com/typescript-eslint/typescript-eslint/commit/c8a4dadeab8a64fb4768deda8f65475435dd2cad)) * support TS4.1 features ([#2748](https://github.com/typescript-eslint/typescript-eslint/issues/2748)) ([2be354b](https://github.com/typescript-eslint/typescript-eslint/commit/2be354bb15f9013a2da1b13a0c0836e9ef057e16)), closes [#2583](https://github.com/typescript-eslint/typescript-eslint/issues/2583) diff --git a/lerna.json b/lerna.json index b57c134a4d70..5508cc016c34 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "4.7.0", + "version": "4.8.0", "npmClient": "yarn", "useWorkspaces": true, "stream": true diff --git a/packages/eslint-plugin-internal/CHANGELOG.md b/packages/eslint-plugin-internal/CHANGELOG.md index 54df34bba4fb..e414fe4ded89 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. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-internal + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) **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 11fa6e86bd8f..e5c8ba25368e 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": "4.7.0", + "version": "4.8.0", "private": true, "main": "dist/index.js", "scripts": { @@ -14,7 +14,7 @@ }, "dependencies": { "@types/prettier": "*", - "@typescript-eslint/experimental-utils": "4.7.0", + "@typescript-eslint/experimental-utils": "4.8.0", "prettier": "*" } } diff --git a/packages/eslint-plugin-tslint/CHANGELOG.md b/packages/eslint-plugin-tslint/CHANGELOG.md index eb4a5f2e9831..9b8d59344eda 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. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + +**Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) **Note:** Version bump only for package @typescript-eslint/eslint-plugin-tslint diff --git a/packages/eslint-plugin-tslint/package.json b/packages/eslint-plugin-tslint/package.json index 02cf08776107..2d835482c9ad 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": "4.7.0", + "version": "4.8.0", "main": "dist/index.js", "typings": "src/index.ts", "description": "TSLint wrapper plugin for ESLint", @@ -38,7 +38,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "4.7.0", + "@typescript-eslint/experimental-utils": "4.8.0", "lodash": "^4.17.15" }, "peerDependencies": { @@ -48,6 +48,6 @@ }, "devDependencies": { "@types/lodash": "*", - "@typescript-eslint/parser": "4.7.0" + "@typescript-eslint/parser": "4.8.0" } } diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 860f51982352..cac134eeb67f 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + + +### Bug Fixes + +* **eslint-plugin:** [consistent-type-definitions] remove fixer when the interface is within a global module declaration ([#2739](https://github.com/typescript-eslint/typescript-eslint/issues/2739)) ([2326238](https://github.com/typescript-eslint/typescript-eslint/commit/2326238738c95acfc14c17f9b16798f1de6d267f)) +* **eslint-plugin:** [no-unsafe-member-access] ignore MemberExpression's whose parents are either TSClassImplements or TSInterfaceHeritage ([#2753](https://github.com/typescript-eslint/typescript-eslint/issues/2753)) ([535db3b](https://github.com/typescript-eslint/typescript-eslint/commit/535db3bf27ee1d7824ada9acd91d1b7833064628)) + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) @@ -14,7 +26,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ### Features -* **eslint-plugin:** add rule `no-void-expression` ([#2605](https://github.com/typescript-eslint/typescript-eslint/issues/2605)) ([c8a4dad](https://github.com/typescript-eslint/typescript-eslint/commit/c8a4dadeab8a64fb4768deda8f65475435dd2cad)) +* **eslint-plugin:** add rule `no-confusing-void-expression` ([#2605](https://github.com/typescript-eslint/typescript-eslint/issues/2605)) ([c8a4dad](https://github.com/typescript-eslint/typescript-eslint/commit/c8a4dadeab8a64fb4768deda8f65475435dd2cad)) * support TS4.1 features ([#2748](https://github.com/typescript-eslint/typescript-eslint/issues/2748)) ([2be354b](https://github.com/typescript-eslint/typescript-eslint/commit/2be354bb15f9013a2da1b13a0c0836e9ef057e16)), closes [#2583](https://github.com/typescript-eslint/typescript-eslint/issues/2583) diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 6f50dbb60310..18d4e5073a8b 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/eslint-plugin", - "version": "4.7.0", + "version": "4.8.0", "description": "TypeScript plugin for ESLint", "keywords": [ "eslint", @@ -42,8 +42,8 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/experimental-utils": "4.7.0", - "@typescript-eslint/scope-manager": "4.7.0", + "@typescript-eslint/experimental-utils": "4.8.0", + "@typescript-eslint/scope-manager": "4.8.0", "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", diff --git a/packages/eslint-plugin/src/rules/consistent-type-definitions.ts b/packages/eslint-plugin/src/rules/consistent-type-definitions.ts index 794e380e389d..f5b2c48a44f4 100644 --- a/packages/eslint-plugin/src/rules/consistent-type-definitions.ts +++ b/packages/eslint-plugin/src/rules/consistent-type-definitions.ts @@ -1,4 +1,5 @@ import { + AST_NODE_TYPES, AST_TOKEN_TYPES, TSESLint, TSESTree, @@ -31,6 +32,21 @@ export default util.createRule({ create(context, [option]) { const sourceCode = context.getSourceCode(); + /** + * Iterates from the highest parent to the currently traversed node + * to determine whether any node in tree is globally declared module declaration + */ + function isCurrentlyTraversedNodeWithinModuleDeclaration(): boolean { + return context + .getAncestors() + .some( + node => + node.type === AST_NODE_TYPES.TSModuleDeclaration && + node.declare && + node.global, + ); + } + return { "TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"( node: TSESTree.TSTypeAliasDeclaration, @@ -73,32 +89,41 @@ export default util.createRule({ context.report({ node: node.id, messageId: 'typeOverInterface', - fix(fixer) { - const typeNode = node.typeParameters ?? node.id; - const fixes: TSESLint.RuleFix[] = []; + /** + * remove automatically fix when the interface is within a declare global + * @see {@link https://github.com/typescript-eslint/typescript-eslint/issues/2707} + */ + fix: isCurrentlyTraversedNodeWithinModuleDeclaration() + ? null + : (fixer): TSESLint.RuleFix[] => { + const typeNode = node.typeParameters ?? node.id; + const fixes: TSESLint.RuleFix[] = []; - const firstToken = sourceCode.getFirstToken(node); - if (firstToken) { - fixes.push(fixer.replaceText(firstToken, 'type')); - fixes.push( - fixer.replaceTextRange( - [typeNode.range[1], node.body.range[0]], - ' = ', - ), - ); - } + const firstToken = sourceCode.getFirstToken(node); + if (firstToken) { + fixes.push(fixer.replaceText(firstToken, 'type')); + fixes.push( + fixer.replaceTextRange( + [typeNode.range[1], node.body.range[0]], + ' = ', + ), + ); + } - if (node.extends) { - node.extends.forEach(heritage => { - const typeIdentifier = sourceCode.getText(heritage); - fixes.push( - fixer.insertTextAfter(node.body, ` & ${typeIdentifier}`), - ); - }); - } + if (node.extends) { + node.extends.forEach(heritage => { + const typeIdentifier = sourceCode.getText(heritage); + fixes.push( + fixer.insertTextAfter( + node.body, + ` & ${typeIdentifier}`, + ), + ); + }); + } - return fixes; - }, + return fixes; + }, }); } }, diff --git a/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts b/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts index e0bb605f0f15..b326c754136b 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-member-access.ts @@ -71,7 +71,8 @@ export default util.createRule({ } return { - MemberExpression: checkMemberExpression, + // ignore MemberExpression if it's parent is TSClassImplements or TSInterfaceHeritage + ':not(TSClassImplements, TSInterfaceHeritage) > MemberExpression': checkMemberExpression, 'MemberExpression[computed = true] > *.property'( node: TSESTree.Expression, ): void { diff --git a/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts b/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts index 78e5d3ceb018..105c25724c23 100644 --- a/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts +++ b/packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts @@ -197,5 +197,89 @@ export type W = { }, ], }, + { + code: ` +namespace JSX { + interface Array { + foo(x: (x: number) => T): T[]; + } +} + `, + output: noFormat` +namespace JSX { + type Array = { + foo(x: (x: number) => T): T[]; + } +} + `, + options: ['type'], + errors: [ + { + messageId: 'typeOverInterface', + line: 3, + column: 13, + }, + ], + }, + { + code: ` +global { + interface Array { + foo(x: (x: number) => T): T[]; + } +} + `, + output: noFormat` +global { + type Array = { + foo(x: (x: number) => T): T[]; + } +} + `, + options: ['type'], + errors: [ + { + messageId: 'typeOverInterface', + line: 3, + column: 13, + }, + ], + }, + { + code: ` +declare global { + interface Array { + foo(x: (x: number) => T): T[]; + } +} + `, + output: null, + options: ['type'], + errors: [ + { + messageId: 'typeOverInterface', + line: 3, + column: 13, + }, + ], + }, + { + code: ` +declare global { + namespace Foo { + interface Bar {} + } +} + `, + output: null, + options: ['type'], + errors: [ + { + messageId: 'typeOverInterface', + line: 4, + column: 15, + }, + ], + }, ], }); diff --git a/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts b/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts index bf6ff85c121d..a9c21f8712b9 100644 --- a/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unsafe-member-access.test.ts @@ -66,6 +66,12 @@ function foo(x?: string[]) { x?.[(1 as any)++]; } `, + ` +class B implements FG.A {} + `, + ` +interface B extends FG.A {} + `, ], invalid: [ ...batchedSingleLineTests({ diff --git a/packages/experimental-utils/CHANGELOG.md b/packages/experimental-utils/CHANGELOG.md index ae01c57dfb02..84e3a46ce67e 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. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + +**Note:** Version bump only for package @typescript-eslint/experimental-utils + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) **Note:** Version bump only for package @typescript-eslint/experimental-utils diff --git a/packages/experimental-utils/package.json b/packages/experimental-utils/package.json index 5b08a7b7a7b5..ee28cd392695 100644 --- a/packages/experimental-utils/package.json +++ b/packages/experimental-utils/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/experimental-utils", - "version": "4.7.0", + "version": "4.8.0", "description": "(Experimental) Utilities for working with TypeScript + ESLint together", "keywords": [ "eslint", @@ -40,9 +40,9 @@ }, "dependencies": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.7.0", - "@typescript-eslint/types": "4.7.0", - "@typescript-eslint/typescript-estree": "4.7.0", + "@typescript-eslint/scope-manager": "4.8.0", + "@typescript-eslint/types": "4.8.0", + "@typescript-eslint/typescript-estree": "4.8.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" }, diff --git a/packages/parser/CHANGELOG.md b/packages/parser/CHANGELOG.md index 16160c94e635..d54a268bfa3b 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. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + +**Note:** Version bump only for package @typescript-eslint/parser + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) **Note:** Version bump only for package @typescript-eslint/parser diff --git a/packages/parser/package.json b/packages/parser/package.json index 9d6e2ec84454..d42033af711a 100644 --- a/packages/parser/package.json +++ b/packages/parser/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/parser", - "version": "4.7.0", + "version": "4.8.0", "description": "An ESLint custom parser which leverages TypeScript ESTree", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -44,15 +44,15 @@ "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "dependencies": { - "@typescript-eslint/scope-manager": "4.7.0", - "@typescript-eslint/types": "4.7.0", - "@typescript-eslint/typescript-estree": "4.7.0", + "@typescript-eslint/scope-manager": "4.8.0", + "@typescript-eslint/types": "4.8.0", + "@typescript-eslint/typescript-estree": "4.8.0", "debug": "^4.1.1" }, "devDependencies": { "@types/glob": "*", - "@typescript-eslint/experimental-utils": "4.7.0", - "@typescript-eslint/shared-fixtures": "4.7.0", + "@typescript-eslint/experimental-utils": "4.8.0", + "@typescript-eslint/shared-fixtures": "4.8.0", "glob": "*", "typescript": "*" }, diff --git a/packages/scope-manager/CHANGELOG.md b/packages/scope-manager/CHANGELOG.md index 8423871370c0..fe7c8aaf227c 100644 --- a/packages/scope-manager/CHANGELOG.md +++ b/packages/scope-manager/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. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + +**Note:** Version bump only for package @typescript-eslint/scope-manager + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) diff --git a/packages/scope-manager/package.json b/packages/scope-manager/package.json index 480eaef447f1..e78fc891b66d 100644 --- a/packages/scope-manager/package.json +++ b/packages/scope-manager/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/scope-manager", - "version": "4.7.0", + "version": "4.8.0", "description": "TypeScript scope analyser for ESLint", "keywords": [ "eslint", @@ -39,12 +39,12 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "4.7.0", - "@typescript-eslint/visitor-keys": "4.7.0" + "@typescript-eslint/types": "4.8.0", + "@typescript-eslint/visitor-keys": "4.8.0" }, "devDependencies": { "@types/glob": "*", - "@typescript-eslint/typescript-estree": "4.7.0", + "@typescript-eslint/typescript-estree": "4.8.0", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/shared-fixtures/CHANGELOG.md b/packages/shared-fixtures/CHANGELOG.md index a1b0701d39e8..b4afb028c368 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. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + +**Note:** Version bump only for package @typescript-eslint/shared-fixtures + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) diff --git a/packages/shared-fixtures/package.json b/packages/shared-fixtures/package.json index 93dcf4e11880..eb78a781ee1d 100644 --- a/packages/shared-fixtures/package.json +++ b/packages/shared-fixtures/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/shared-fixtures", - "version": "4.7.0", + "version": "4.8.0", "private": true, "scripts": { "build": "tsc -b tsconfig.build.json", diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index e082c9de1062..5903be3db8ee 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/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. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + +**Note:** Version bump only for package @typescript-eslint/types + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) diff --git a/packages/types/package.json b/packages/types/package.json index fc735df29e94..9ce68de2ad77 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/types", - "version": "4.7.0", + "version": "4.8.0", "description": "Types for the TypeScript-ESTree AST spec", "keywords": [ "eslint", diff --git a/packages/typescript-estree/CHANGELOG.md b/packages/typescript-estree/CHANGELOG.md index f45f6c9734ad..2fac5c227f02 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. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + + +### Features + +* **typescript-estree:** add `parseWithNodeMaps` API ([#2760](https://github.com/typescript-eslint/typescript-eslint/issues/2760)) ([9441d50](https://github.com/typescript-eslint/typescript-eslint/commit/9441d5030211f1c32f5ae8e61d5565cab8bb6823)), closes [#1852](https://github.com/typescript-eslint/typescript-eslint/issues/1852) + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) diff --git a/packages/typescript-estree/README.md b/packages/typescript-estree/README.md index 8a59159647d0..b9d40fb1ec07 100644 --- a/packages/typescript-estree/README.md +++ b/packages/typescript-estree/README.md @@ -220,6 +220,18 @@ interface ParseAndGenerateServicesOptions extends ParseOptions { createDefaultProgram?: boolean; } +interface ParserServices { + program: ts.Program; + esTreeNodeToTSNodeMap: WeakMap; + tsNodeToESTreeNodeMap: WeakMap; + hasFullTypeInformation: boolean; +} + +interface ParseAndGenerateServicesResult { + ast: TSESTree.Program; + services: ParserServices; +} + const PARSE_AND_GENERATE_SERVICES_DEFAULT_OPTIONS: ParseOptions = { ...PARSE_DEFAULT_OPTIONS, errorOnTypeScriptSyntacticAndSemanticIssues: false, @@ -233,7 +245,7 @@ const PARSE_AND_GENERATE_SERVICES_DEFAULT_OPTIONS: ParseOptions = { declare function parseAndGenerateServices( code: string, options: ParseOptions = PARSE_DEFAULT_OPTIONS, -): TSESTree.Program; +): ParseAndGenerateServicesResult; ``` Example usage: @@ -242,7 +254,7 @@ Example usage: import { parseAndGenerateServices } from '@typescript-eslint/typescript-estree'; const code = `const hello: string = 'world';`; -const ast = parseAndGenerateServices(code, { +const { ast, services } = parseAndGenerateServices(code, { filePath: '/some/path/to/file/foo.ts', loc: true, project: './tsconfig.json', @@ -250,6 +262,39 @@ const ast = parseAndGenerateServices(code, { }); ``` +#### `parseWithNodeMaps(code, options)` + +Parses the given string of code with the options provided and returns both the ESTree-compatible AST as well as the node maps. +This allows you to work with both ASTs without the overhead of types that may come with `parseAndGenerateServices`. + +```ts +interface ParseWithNodeMapsResult { + ast: TSESTree.Program; + esTreeNodeToTSNodeMap: ParserServices['esTreeNodeToTSNodeMap']; + tsNodeToESTreeNodeMap: ParserServices['tsNodeToESTreeNodeMap']; +} + +declare function parseWithNodeMaps( + code: string, + options: ParseOptions = PARSE_DEFAULT_OPTIONS, +): ParseWithNodeMapsResult; +``` + +Example usage: + +```js +import { parseWithNodeMaps } from '@typescript-eslint/typescript-estree'; + +const code = `const hello: string = 'world';`; +const { ast, esTreeNodeToTSNodeMap, tsNodeToESTreeNodeMap } = parseWithNodeMaps( + code, + { + loc: true, + range: true, + }, +); +``` + ### `TSESTree`, `AST_NODE_TYPES` and `AST_TOKEN_TYPES` Types for the AST produced by the parse functions. diff --git a/packages/typescript-estree/package.json b/packages/typescript-estree/package.json index 76f911b5c8df..d3d8c1597dfe 100644 --- a/packages/typescript-estree/package.json +++ b/packages/typescript-estree/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/typescript-estree", - "version": "4.7.0", + "version": "4.8.0", "description": "A parser that converts TypeScript source code into an ESTree compatible form", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -41,8 +41,8 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "4.7.0", - "@typescript-eslint/visitor-keys": "4.7.0", + "@typescript-eslint/types": "4.8.0", + "@typescript-eslint/visitor-keys": "4.8.0", "debug": "^4.1.1", "globby": "^11.0.1", "is-glob": "^4.0.1", @@ -61,7 +61,7 @@ "@types/lodash": "*", "@types/semver": "^7.1.0", "@types/tmp": "^0.2.0", - "@typescript-eslint/shared-fixtures": "4.7.0", + "@typescript-eslint/shared-fixtures": "4.8.0", "glob": "*", "jest-specific-snapshot": "*", "make-dir": "*", diff --git a/packages/typescript-estree/src/index.ts b/packages/typescript-estree/src/index.ts index 88af46a20919..a619e48f679f 100644 --- a/packages/typescript-estree/src/index.ts +++ b/packages/typescript-estree/src/index.ts @@ -1,9 +1,4 @@ -export { - AST, - parse, - parseAndGenerateServices, - ParseAndGenerateServicesResult, -} from './parser'; +export * from './parser'; export { ParserServices, TSESTreeOptions } from './parser-options'; export { simpleTraverse } from './simple-traverse'; export * from './ts-estree'; diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index d2554bf61954..45dfd18cef74 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -321,11 +321,24 @@ interface ParseAndGenerateServicesResult { ast: AST; services: ParserServices; } +interface ParseWithNodeMapsResult { + ast: AST; + esTreeNodeToTSNodeMap: ParserServices['esTreeNodeToTSNodeMap']; + tsNodeToESTreeNodeMap: ParserServices['tsNodeToESTreeNodeMap']; +} function parse( code: string, options?: T, ): AST { + const { ast } = parseWithNodeMaps(code, options); + return ast; +} + +function parseWithNodeMaps( + code: string, + options?: T, +): ParseWithNodeMapsResult { /** * Reset the parse configuration */ @@ -367,8 +380,13 @@ function parse( /** * Convert the TypeScript AST to an ESTree-compatible one */ - const { estree } = astConverter(ast, extra, false); - return estree as AST; + const { estree, astMaps } = astConverter(ast, extra, false); + + return { + ast: estree as AST, + esTreeNodeToTSNodeMap: astMaps.esTreeNodeToTSNodeMap, + tsNodeToESTreeNodeMap: astMaps.tsNodeToESTreeNodeMap, + }; } function parseAndGenerateServices( @@ -450,4 +468,11 @@ function parseAndGenerateServices( }; } -export { AST, parse, parseAndGenerateServices, ParseAndGenerateServicesResult }; +export { + AST, + parse, + parseAndGenerateServices, + parseWithNodeMaps, + ParseAndGenerateServicesResult, + ParseWithNodeMapsResult, +}; diff --git a/packages/typescript-estree/tests/ast-alignment/utils.ts b/packages/typescript-estree/tests/ast-alignment/utils.ts index 9cdedb452eba..c601ebcc31fc 100644 --- a/packages/typescript-estree/tests/ast-alignment/utils.ts +++ b/packages/typescript-estree/tests/ast-alignment/utils.ts @@ -266,14 +266,6 @@ export function preprocessBabylonAST(ast: BabelTypes.File): any { node.asserts = false; } }, - ImportDeclaration(node) { - /** - * TS 3.8: import type - */ - if (!node.importKind) { - node.importKind = 'value'; - } - }, }, ); } diff --git a/packages/typescript-estree/tests/lib/__snapshots__/parse.test.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/parse.test.ts.snap index 8ea937e0cd9b..c1c63f861b61 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/parse.test.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/parse.test.ts.snap @@ -1,373 +1,62 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`parse() general output should not contain loc 1`] = ` -Object { - "body": Array [ - Object { - "declarations": Array [ - Object { - "id": Object { - "name": "foo", - "range": Array [ - 4, - 7, - ], - "type": "Identifier", - }, - "init": Object { - "name": "bar", - "range": Array [ - 10, - 13, - ], - "type": "Identifier", - }, - "range": Array [ - 4, - 13, - ], - "type": "VariableDeclarator", - }, - ], - "kind": "let", - "range": Array [ - 0, - 14, - ], - "type": "VariableDeclaration", - }, - ], - "range": Array [ - 0, - 14, - ], - "sourceType": "script", - "type": "Program", -} -`; - -exports[`parse() general output should not contain range 1`] = ` -Object { - "body": Array [ - Object { - "declarations": Array [ - Object { - "id": Object { - "loc": Object { - "end": Object { - "column": 7, - "line": 1, - }, - "start": Object { - "column": 4, - "line": 1, - }, - }, - "name": "foo", - "type": "Identifier", - }, - "init": Object { - "loc": Object { - "end": Object { - "column": 13, - "line": 1, - }, - "start": Object { - "column": 10, - "line": 1, - }, - }, - "name": "bar", - "type": "Identifier", - }, - "loc": Object { - "end": Object { - "column": 13, - "line": 1, - }, - "start": Object { - "column": 4, - "line": 1, - }, - }, - "type": "VariableDeclarator", - }, - ], - "kind": "let", - "loc": Object { - "end": Object { - "column": 14, - "line": 1, - }, - "start": Object { - "column": 0, - "line": 1, - }, - }, - "type": "VariableDeclaration", - }, - ], - "loc": Object { - "end": Object { - "column": 14, - "line": 1, - }, - "start": Object { - "column": 0, - "line": 1, - }, - }, - "sourceType": "script", - "type": "Program", -} -`; - -exports[`parse() general output tokens, comments, locs, and ranges when called with those options 1`] = ` -Object { - "body": Array [ - Object { - "declarations": Array [ - Object { - "id": Object { - "loc": Object { - "end": Object { - "column": 7, - "line": 1, - }, - "start": Object { - "column": 4, - "line": 1, - }, - }, - "name": "foo", - "range": Array [ - 4, - 7, - ], - "type": "Identifier", - }, - "init": Object { - "loc": Object { - "end": Object { - "column": 13, - "line": 1, - }, - "start": Object { - "column": 10, - "line": 1, - }, - }, - "name": "bar", - "range": Array [ - 10, - 13, - ], - "type": "Identifier", - }, - "loc": Object { - "end": Object { - "column": 13, - "line": 1, - }, - "start": Object { - "column": 4, - "line": 1, - }, - }, - "range": Array [ - 4, - 13, - ], - "type": "VariableDeclarator", - }, - ], - "kind": "let", - "loc": Object { - "end": Object { - "column": 14, - "line": 1, - }, - "start": Object { - "column": 0, - "line": 1, - }, - }, - "range": Array [ - 0, - 14, - ], - "type": "VariableDeclaration", - }, - ], - "comments": Array [], - "loc": Object { - "end": Object { - "column": 14, - "line": 1, - }, - "start": Object { - "column": 0, - "line": 1, - }, - }, - "range": Array [ - 0, - 14, - ], - "sourceType": "script", - "tokens": Array [ - Object { - "loc": Object { - "end": Object { - "column": 3, - "line": 1, - }, - "start": Object { - "column": 0, - "line": 1, - }, - }, - "range": Array [ - 0, - 3, - ], - "type": "Keyword", - "value": "let", - }, - Object { - "loc": Object { - "end": Object { - "column": 7, - "line": 1, - }, - "start": Object { - "column": 4, - "line": 1, - }, - }, - "range": Array [ - 4, - 7, - ], - "type": "Identifier", - "value": "foo", - }, - Object { - "loc": Object { - "end": Object { - "column": 9, - "line": 1, - }, - "start": Object { - "column": 8, - "line": 1, - }, - }, - "range": Array [ - 8, - 9, - ], - "type": "Punctuator", - "value": "=", - }, - Object { - "loc": Object { - "end": Object { - "column": 13, - "line": 1, - }, - "start": Object { - "column": 10, - "line": 1, - }, - }, - "range": Array [ - 10, - 13, - ], - "type": "Identifier", - "value": "bar", - }, - Object { - "loc": Object { - "end": Object { - "column": 14, - "line": 1, - }, - "start": Object { - "column": 13, - "line": 1, - }, - }, - "range": Array [ - 13, - 14, - ], - "type": "Punctuator", - "value": ";", - }, - ], - "type": "Program", -} -`; - -exports[`parse() invalid file error messages "parserOptions.extraFileExtensions" is empty the extension does not match 1`] = ` +exports[`parseAndGenerateServices invalid file error messages "parserOptions.extraFileExtensions" is empty the extension does not match 1`] = ` "\\"parserOptions.project\\" has been set for @typescript-eslint/parser. The file does not match your project config: other/unknownFileType.unknown. The extension for the file (.unknown) is non-standard. You should add \\"parserOptions.extraFileExtensions\\" to your config." `; -exports[`parse() invalid file error messages "parserOptions.extraFileExtensions" is non-empty invalid extension 1`] = ` +exports[`parseAndGenerateServices invalid file error messages "parserOptions.extraFileExtensions" is non-empty invalid extension 1`] = ` "\\"parserOptions.project\\" has been set for @typescript-eslint/parser. The file does not match your project config: other/unknownFileType.unknown. Found unexpected extension \\"unknown\\" specified with the \\"extraFileExtensions\\" option. Did you mean \\".unknown\\"? The extension for the file (.unknown) is non-standard. It should be added to your existing \\"parserOptions.extraFileExtensions\\"." `; -exports[`parse() invalid file error messages "parserOptions.extraFileExtensions" is non-empty the extension does not match 1`] = ` +exports[`parseAndGenerateServices invalid file error messages "parserOptions.extraFileExtensions" is non-empty the extension does not match 1`] = ` "\\"parserOptions.project\\" has been set for @typescript-eslint/parser. The file does not match your project config: other/unknownFileType.unknown. The extension for the file (.unknown) is non-standard. It should be added to your existing \\"parserOptions.extraFileExtensions\\"." `; -exports[`parse() invalid file error messages "parserOptions.extraFileExtensions" is non-empty the extension matches duplicate extension 1`] = ` +exports[`parseAndGenerateServices invalid file error messages "parserOptions.extraFileExtensions" is non-empty the extension matches duplicate extension 1`] = ` "\\"parserOptions.project\\" has been set for @typescript-eslint/parser. The file does not match your project config: ts/notIncluded.ts. You unnecessarily included the extension \\".ts\\" with the \\"extraFileExtensions\\" option. This extension is already handled by the parser by default. The file must be included in at least one of the projects provided." `; -exports[`parse() invalid file error messages "parserOptions.extraFileExtensions" is non-empty the extension matches the file isn't included 1`] = ` +exports[`parseAndGenerateServices invalid file error messages "parserOptions.extraFileExtensions" is non-empty the extension matches the file isn't included 1`] = ` "\\"parserOptions.project\\" has been set for @typescript-eslint/parser. The file does not match your project config: other/notIncluded.vue. The file must be included in at least one of the projects provided." `; -exports[`parse() invalid file error messages project includes errors for not included files 1`] = ` +exports[`parseAndGenerateServices invalid file error messages project includes errors for not included files 1`] = ` "\\"parserOptions.project\\" has been set for @typescript-eslint/parser. The file does not match your project config: ts/notIncluded.ts. The file must be included in at least one of the projects provided." `; -exports[`parse() invalid file error messages project includes errors for not included files 2`] = ` +exports[`parseAndGenerateServices invalid file error messages project includes errors for not included files 2`] = ` "\\"parserOptions.project\\" has been set for @typescript-eslint/parser. The file does not match your project config: ts/notIncluded.tsx. The file must be included in at least one of the projects provided." `; -exports[`parse() invalid file error messages project includes errors for not included files 3`] = ` +exports[`parseAndGenerateServices invalid file error messages project includes errors for not included files 3`] = ` "\\"parserOptions.project\\" has been set for @typescript-eslint/parser. The file does not match your project config: js/notIncluded.js. The file must be included in at least one of the projects provided." `; -exports[`parse() invalid file error messages project includes errors for not included files 4`] = ` +exports[`parseAndGenerateServices invalid file error messages project includes errors for not included files 4`] = ` "\\"parserOptions.project\\" has been set for @typescript-eslint/parser. The file does not match your project config: js/notIncluded.jsx. The file must be included in at least one of the projects provided." `; -exports[`parse() isolated parsing should parse .js file - with JSX content - parserOptions.jsx = false 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .js file - with JSX content - parserOptions.jsx = false 1`] = ` Object { "ast": Object { "body": Array [ @@ -657,7 +346,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .js file - with JSX content - parserOptions.jsx = true 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .js file - with JSX content - parserOptions.jsx = true 1`] = ` Object { "ast": Object { "body": Array [ @@ -947,7 +636,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .js file - without JSX content - parserOptions.jsx = false 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .js file - without JSX content - parserOptions.jsx = false 1`] = ` Object { "ast": Object { "body": Array [ @@ -1127,7 +816,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .js file - without JSX content - parserOptions.jsx = true 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .js file - without JSX content - parserOptions.jsx = true 1`] = ` Object { "ast": Object { "body": Array [ @@ -1307,7 +996,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .json file - without JSX content - parserOptions.jsx = false 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .json file - without JSX content - parserOptions.jsx = false 1`] = ` Object { "ast": Object { "body": Array [ @@ -1526,7 +1215,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .jsx file - with JSX content - parserOptions.jsx = false 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .jsx file - with JSX content - parserOptions.jsx = false 1`] = ` Object { "ast": Object { "body": Array [ @@ -1816,7 +1505,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .jsx file - with JSX content - parserOptions.jsx = true 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .jsx file - with JSX content - parserOptions.jsx = true 1`] = ` Object { "ast": Object { "body": Array [ @@ -2106,7 +1795,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .jsx file - without JSX content - parserOptions.jsx = false 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .jsx file - without JSX content - parserOptions.jsx = false 1`] = ` Object { "ast": Object { "body": Array [ @@ -2286,7 +1975,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .jsx file - without JSX content - parserOptions.jsx = true 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .jsx file - without JSX content - parserOptions.jsx = true 1`] = ` Object { "ast": Object { "body": Array [ @@ -2466,7 +2155,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .ts file - without JSX content - parserOptions.jsx = false 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .ts file - without JSX content - parserOptions.jsx = false 1`] = ` Object { "ast": Object { "body": Array [ @@ -2646,7 +2335,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .ts file - without JSX content - parserOptions.jsx = true 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .ts file - without JSX content - parserOptions.jsx = true 1`] = ` Object { "ast": Object { "body": Array [ @@ -2826,7 +2515,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .tsx file - with JSX content - parserOptions.jsx = false 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .tsx file - with JSX content - parserOptions.jsx = false 1`] = ` Object { "ast": Object { "body": Array [ @@ -3116,7 +2805,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .tsx file - with JSX content - parserOptions.jsx = true 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .tsx file - with JSX content - parserOptions.jsx = true 1`] = ` Object { "ast": Object { "body": Array [ @@ -3406,7 +3095,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .tsx file - without JSX content - parserOptions.jsx = false 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .tsx file - without JSX content - parserOptions.jsx = false 1`] = ` Object { "ast": Object { "body": Array [ @@ -3586,7 +3275,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .tsx file - without JSX content - parserOptions.jsx = true 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .tsx file - without JSX content - parserOptions.jsx = true 1`] = ` Object { "ast": Object { "body": Array [ @@ -3766,7 +3455,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .vue file - with JSX content - parserOptions.jsx = true 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .vue file - with JSX content - parserOptions.jsx = true 1`] = ` Object { "ast": Object { "body": Array [ @@ -3850,7 +3539,259 @@ Object { }, "loc": Object { "end": Object { - "column": 17, + "column": 17, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "range": Array [ + 6, + 17, + ], + "type": "VariableDeclarator", + }, + ], + "kind": "const", + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 18, + ], + "type": "VariableDeclaration", + }, + ], + "comments": Array [], + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 18, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 5, + ], + "type": "Keyword", + "value": "const", + }, + Object { + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "range": Array [ + 6, + 7, + ], + "type": "Identifier", + "value": "x", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "range": Array [ + 8, + 9, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "range": Array [ + 10, + 11, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 14, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 14, + ], + "type": "JSXIdentifier", + "value": "div", + }, + Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 1, + }, + "start": Object { + "column": 15, + "line": 1, + }, + }, + "range": Array [ + 15, + 16, + ], + "type": "Punctuator", + "value": "/", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 1, + }, + "start": Object { + "column": 16, + "line": 1, + }, + }, + "range": Array [ + 16, + 17, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "range": Array [ + 17, + 18, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", + }, + "services": Object { + "esTreeNodeToTSNodeMap": WeakMap {}, + "hasFullTypeInformation": false, + "program": Object {}, + "tsNodeToESTreeNodeMap": WeakMap {}, + }, +} +`; + +exports[`parseAndGenerateServices isolated parsing should parse .vue file - without JSX content - parserOptions.jsx = false 1`] = ` +Object { + "ast": Object { + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 6, + "line": 1, + }, + }, + "name": "x", + "range": Array [ + 6, + 7, + ], + "type": "Identifier", + }, + "init": Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "range": Array [ + 10, + 11, + ], + "raw": "1", + "type": "Literal", + "value": 1, + }, + "loc": Object { + "end": Object { + "column": 11, "line": 1, }, "start": Object { @@ -3860,7 +3801,7 @@ Object { }, "range": Array [ 6, - 17, + 11, ], "type": "VariableDeclarator", }, @@ -3868,7 +3809,7 @@ Object { "kind": "const", "loc": Object { "end": Object { - "column": 18, + "column": 11, "line": 1, }, "start": Object { @@ -3878,7 +3819,7 @@ Object { }, "range": Array [ 0, - 18, + 11, ], "type": "VariableDeclaration", }, @@ -3886,7 +3827,7 @@ Object { "comments": Array [], "loc": Object { "end": Object { - "column": 18, + "column": 11, "line": 1, }, "start": Object { @@ -3896,7 +3837,7 @@ Object { }, "range": Array [ 0, - 18, + 11, ], "sourceType": "script", "tokens": Array [ @@ -3969,80 +3910,8 @@ Object { 10, 11, ], - "type": "Punctuator", - "value": "<", - }, - Object { - "loc": Object { - "end": Object { - "column": 14, - "line": 1, - }, - "start": Object { - "column": 11, - "line": 1, - }, - }, - "range": Array [ - 11, - 14, - ], - "type": "JSXIdentifier", - "value": "div", - }, - Object { - "loc": Object { - "end": Object { - "column": 16, - "line": 1, - }, - "start": Object { - "column": 15, - "line": 1, - }, - }, - "range": Array [ - 15, - 16, - ], - "type": "Punctuator", - "value": "/", - }, - Object { - "loc": Object { - "end": Object { - "column": 17, - "line": 1, - }, - "start": Object { - "column": 16, - "line": 1, - }, - }, - "range": Array [ - 16, - 17, - ], - "type": "Punctuator", - "value": ">", - }, - Object { - "loc": Object { - "end": Object { - "column": 18, - "line": 1, - }, - "start": Object { - "column": 17, - "line": 1, - }, - }, - "range": Array [ - 17, - 18, - ], - "type": "Punctuator", - "value": ";", + "type": "Numeric", + "value": "1", }, ], "type": "Program", @@ -4056,7 +3925,7 @@ Object { } `; -exports[`parse() isolated parsing should parse .vue file - without JSX content - parserOptions.jsx = false 1`] = ` +exports[`parseAndGenerateServices isolated parsing should parse .vue file - without JSX content - parserOptions.jsx = true 1`] = ` Object { "ast": Object { "body": Array [ @@ -4236,187 +4105,318 @@ Object { } `; -exports[`parse() isolated parsing should parse .vue file - without JSX content - parserOptions.jsx = true 1`] = ` +exports[`parseWithNodeMaps() general output should not contain loc 1`] = ` Object { - "ast": Object { - "body": Array [ - Object { - "declarations": Array [ - Object { - "id": Object { - "loc": Object { - "end": Object { - "column": 7, - "line": 1, - }, - "start": Object { - "column": 6, - "line": 1, - }, + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "name": "foo", + "range": Array [ + 4, + 7, + ], + "type": "Identifier", + }, + "init": Object { + "name": "bar", + "range": Array [ + 10, + 13, + ], + "type": "Identifier", + }, + "range": Array [ + 4, + 13, + ], + "type": "VariableDeclarator", + }, + ], + "kind": "let", + "range": Array [ + 0, + 14, + ], + "type": "VariableDeclaration", + }, + ], + "range": Array [ + 0, + 14, + ], + "sourceType": "script", + "type": "Program", +} +`; + +exports[`parseWithNodeMaps() general output should not contain range 1`] = ` +Object { + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, }, - "name": "x", - "range": Array [ - 6, - 7, - ], - "type": "Identifier", }, - "init": Object { - "loc": Object { - "end": Object { - "column": 11, - "line": 1, - }, - "start": Object { - "column": 10, - "line": 1, - }, + "name": "foo", + "type": "Identifier", + }, + "init": Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "name": "bar", + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "type": "VariableDeclarator", + }, + ], + "kind": "let", + "loc": Object { + "end": Object { + "column": 14, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "type": "VariableDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 14, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "sourceType": "script", + "type": "Program", +} +`; + +exports[`parseWithNodeMaps() general output tokens, comments, locs, and ranges when called with those options 1`] = ` +Object { + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, }, - "range": Array [ - 10, - 11, - ], - "raw": "1", - "type": "Literal", - "value": 1, }, + "name": "foo", + "range": Array [ + 4, + 7, + ], + "type": "Identifier", + }, + "init": Object { "loc": Object { "end": Object { - "column": 11, + "column": 13, "line": 1, }, "start": Object { - "column": 6, + "column": 10, "line": 1, }, }, + "name": "bar", "range": Array [ - 6, - 11, + 10, + 13, ], - "type": "VariableDeclarator", - }, - ], - "kind": "const", - "loc": Object { - "end": Object { - "column": 11, - "line": 1, + "type": "Identifier", }, - "start": Object { - "column": 0, - "line": 1, + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, }, + "range": Array [ + 4, + 13, + ], + "type": "VariableDeclarator", + }, + ], + "kind": "let", + "loc": Object { + "end": Object { + "column": 14, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, }, - "range": Array [ - 0, - 11, - ], - "type": "VariableDeclaration", - }, - ], - "comments": Array [], - "loc": Object { - "end": Object { - "column": 11, - "line": 1, }, - "start": Object { - "column": 0, - "line": 1, + "range": Array [ + 0, + 14, + ], + "type": "VariableDeclaration", + }, + ], + "comments": Array [], + "loc": Object { + "end": Object { + "column": 14, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 14, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, }, + "range": Array [ + 0, + 3, + ], + "type": "Keyword", + "value": "let", }, - "range": Array [ - 0, - 11, - ], - "sourceType": "script", - "tokens": Array [ - Object { - "loc": Object { - "end": Object { - "column": 5, - "line": 1, - }, - "start": Object { - "column": 0, - "line": 1, - }, + Object { + "loc": Object { + "end": Object { + "column": 7, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, }, - "range": Array [ - 0, - 5, - ], - "type": "Keyword", - "value": "const", }, - Object { - "loc": Object { - "end": Object { - "column": 7, - "line": 1, - }, - "start": Object { - "column": 6, - "line": 1, - }, + "range": Array [ + 4, + 7, + ], + "type": "Identifier", + "value": "foo", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, }, - "range": Array [ - 6, - 7, - ], - "type": "Identifier", - "value": "x", }, - Object { - "loc": Object { - "end": Object { - "column": 9, - "line": 1, - }, - "start": Object { - "column": 8, - "line": 1, - }, + "range": Array [ + 8, + 9, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, }, - "range": Array [ - 8, - 9, - ], - "type": "Punctuator", - "value": "=", }, - Object { - "loc": Object { - "end": Object { - "column": 11, - "line": 1, - }, - "start": Object { - "column": 10, - "line": 1, - }, + "range": Array [ + 10, + 13, + ], + "type": "Identifier", + "value": "bar", + }, + Object { + "loc": Object { + "end": Object { + "column": 14, + "line": 1, + }, + "start": Object { + "column": 13, + "line": 1, }, - "range": Array [ - 10, - 11, - ], - "type": "Numeric", - "value": "1", }, - ], - "type": "Program", - }, - "services": Object { - "esTreeNodeToTSNodeMap": WeakMap {}, - "hasFullTypeInformation": false, - "program": Object {}, - "tsNodeToESTreeNodeMap": WeakMap {}, - }, + "range": Array [ + 13, + 14, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", } `; -exports[`parse() non string code should correctly convert code to a string for parse() 1`] = ` +exports[`parseWithNodeMaps() non string code should correctly convert code to a string for parse() 1`] = ` Object { "body": Array [ Object { @@ -4496,7 +4496,7 @@ Object { } `; -exports[`parse() non string code should correctly convert code to a string for parseAndGenerateServices() 1`] = ` +exports[`parseWithNodeMaps() non string code should correctly convert code to a string for parseAndGenerateServices() 1`] = ` Object { "body": Array [ Object { diff --git a/packages/typescript-estree/tests/lib/parse.test.ts b/packages/typescript-estree/tests/lib/parse.test.ts index 6ed6441c4e79..a1c68ce7582a 100644 --- a/packages/typescript-estree/tests/lib/parse.test.ts +++ b/packages/typescript-estree/tests/lib/parse.test.ts @@ -8,18 +8,25 @@ import { createSnapshotTestBlock } from '../../tools/test-utils'; const FIXTURES_DIR = join(__dirname, '../fixtures/simpleProject'); -describe('parse()', () => { +describe('parseWithNodeMaps()', () => { describe('basic functionality', () => { it('should parse an empty string', () => { - expect(parser.parse('').body).toEqual([]); - expect(parser.parse('', {}).body).toEqual([]); + expect(parser.parseWithNodeMaps('').ast.body).toEqual([]); + expect(parser.parseWithNodeMaps('', {}).ast.body).toEqual([]); + }); + + it('parse() should be the same as parseWithNodeMaps().ast', () => { + const code = 'const x: number = 1;'; + expect(parser.parseWithNodeMaps(code).ast).toMatchObject( + parser.parse(code), + ); }); }); describe('modules', () => { it('should have correct column number when strict mode error occurs', () => { try { - parser.parse('function fn(a, a) {\n}'); + parser.parseWithNodeMaps('function fn(a, a) {\n}'); } catch (err) { expect(err.column).toEqual(16); } @@ -85,7 +92,7 @@ describe('parse()', () => { const loggerFn = jest.fn(() => {}); - parser.parse('let foo = bar;', { + parser.parseWithNodeMaps('let foo = bar;', { loggerFn, comment: true, tokens: true, @@ -105,7 +112,9 @@ describe('parse()', () => { }); }); }); +}); +describe('parseAndGenerateServices', () => { describe('errorOnTypeScriptSyntacticAndSemanticIssues', () => { const code = '@test const foo = 2'; const options: TSESTreeOptions = { @@ -116,9 +125,9 @@ describe('parse()', () => { errorOnTypeScriptSyntacticAndSemanticIssues: true, }; - it('should throw on invalid option when used in parse', () => { + it('should throw on invalid option when used in parseWithNodeMaps', () => { expect(() => { - parser.parse(code, options); + parser.parseWithNodeMaps(code, options); }).toThrow( `"errorOnTypeScriptSyntacticAndSemanticIssues" is only supported for parseAndGenerateServices()`, ); @@ -176,6 +185,31 @@ describe('parse()', () => { ); }); + it('should not impact the use of parseWithNodeMaps()', () => { + const resultWithNoOptionSet = parser.parseWithNodeMaps(code, baseConfig); + const resultWithOptionSetToTrue = parser.parseWithNodeMaps(code, { + ...baseConfig, + preserveNodeMaps: true, + }); + const resultWithOptionSetToFalse = parser.parseWithNodeMaps(code, { + ...baseConfig, + preserveNodeMaps: false, + }); + const resultWithOptionSetExplicitlyToUndefined = parser.parseWithNodeMaps( + code, + { + ...baseConfig, + preserveNodeMaps: undefined, + }, + ); + + expect(resultWithNoOptionSet).toMatchObject(resultWithOptionSetToTrue); + expect(resultWithNoOptionSet).toMatchObject(resultWithOptionSetToFalse); + expect(resultWithNoOptionSet).toMatchObject( + resultWithOptionSetExplicitlyToUndefined, + ); + }); + it('should preserve node maps by default for parseAndGenerateServices()', () => { const noOptionSet = parser.parseAndGenerateServices(code, baseConfig); diff --git a/packages/visitor-keys/CHANGELOG.md b/packages/visitor-keys/CHANGELOG.md index 1998425b819f..270ce6157e28 100644 --- a/packages/visitor-keys/CHANGELOG.md +++ b/packages/visitor-keys/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. +# [4.8.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.7.0...v4.8.0) (2020-11-16) + +**Note:** Version bump only for package @typescript-eslint/visitor-keys + + + + + # [4.7.0](https://github.com/typescript-eslint/typescript-eslint/compare/v4.6.1...v4.7.0) (2020-11-09) diff --git a/packages/visitor-keys/package.json b/packages/visitor-keys/package.json index 3af54d385939..cf5f994aaada 100644 --- a/packages/visitor-keys/package.json +++ b/packages/visitor-keys/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-eslint/visitor-keys", - "version": "4.7.0", + "version": "4.8.0", "description": "Visitor keys used to help traverse the TypeScript-ESTree AST", "keywords": [ "eslint", @@ -38,7 +38,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { - "@typescript-eslint/types": "4.7.0", + "@typescript-eslint/types": "4.8.0", "eslint-visitor-keys": "^2.0.0" }, "devDependencies": {