From 82e7163214b56ccde93ba97807b161669a50a60b Mon Sep 17 00:00:00 2001 From: Gareth Jones Date: Sun, 10 May 2020 12:17:16 +1200 Subject: [PATCH] fix(typescript-estree): use `TSEmptyBodyFunctionExpression` for body-less nodes (#1289) --- .../src/rules/indent-new-do-not-use/index.ts | 2 +- .../src/rules/no-unsafe-assignment.ts | 5 ++++- .../src/util/explicitReturnTypeUtils.ts | 2 +- packages/parser/src/parser.ts | 16 -------------- packages/typescript-estree/src/convert.ts | 22 +++++++++++++------ .../src/ts-estree/ts-estree.ts | 7 +++++- .../lib/__snapshots__/typescript.ts.snap | 16 +++++++------- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/eslint-plugin/src/rules/indent-new-do-not-use/index.ts b/packages/eslint-plugin/src/rules/indent-new-do-not-use/index.ts index 3c24f29ad9e..73123355a32 100644 --- a/packages/eslint-plugin/src/rules/indent-new-do-not-use/index.ts +++ b/packages/eslint-plugin/src/rules/indent-new-do-not-use/index.ts @@ -1115,7 +1115,7 @@ export default createRule({ 'FunctionDeclaration, FunctionExpression'( node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression, ) { - const closingParen = sourceCode.getTokenBefore(node.body!)!; + const closingParen = sourceCode.getTokenBefore(node.body)!; const openingParen = sourceCode.getTokenBefore( node.params.length ? node.params[0] : closingParen, )!; diff --git a/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts b/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts index b7f339e1944..638d3036311 100644 --- a/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts +++ b/packages/eslint-plugin/src/rules/no-unsafe-assignment.ts @@ -326,7 +326,10 @@ export default util.createRule({ }, // object pattern props are checked via assignments ':not(ObjectPattern) > Property'(node: TSESTree.Property): void { - if (node.value.type === AST_NODE_TYPES.AssignmentPattern) { + if ( + node.value.type === AST_NODE_TYPES.AssignmentPattern || + node.value.type === AST_NODE_TYPES.TSEmptyBodyFunctionExpression + ) { // handled by other selector return; } diff --git a/packages/eslint-plugin/src/util/explicitReturnTypeUtils.ts b/packages/eslint-plugin/src/util/explicitReturnTypeUtils.ts index 03a2260289e..2725a6ab3d3 100644 --- a/packages/eslint-plugin/src/util/explicitReturnTypeUtils.ts +++ b/packages/eslint-plugin/src/util/explicitReturnTypeUtils.ts @@ -62,7 +62,7 @@ function getReporLoc( )!.loc.end; } - return sourceCode.getTokenBefore(node.body!)!.loc.end; + return sourceCode.getTokenBefore(node.body)!.loc.end; } return { diff --git a/packages/parser/src/parser.ts b/packages/parser/src/parser.ts index 86469cea255..00c0fe57d43 100644 --- a/packages/parser/src/parser.ts +++ b/packages/parser/src/parser.ts @@ -5,7 +5,6 @@ import { ParserServices, TSESTreeOptions, TSESTree, - simpleTraverse, visitorKeys, } from '@typescript-eslint/typescript-estree'; import { analyzeScope } from './analyze-scope'; @@ -95,21 +94,6 @@ export function parseForESLint( const { ast, services } = parseAndGenerateServices(code, parserOptions); ast.sourceType = options.sourceType; - simpleTraverse(ast, { - enter(node) { - switch (node.type) { - // Function#body cannot be null in ESTree spec. - case AST_NODE_TYPES.FunctionExpression: - if (!node.body) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - node.type = `TSEmptyBody${node.type}` as any; - } - break; - // no default - } - }, - }); - const scopeManager = analyzeScope(ast, options); return { ast, services, scopeManager, visitorKeys }; } diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 66111f48840..f6770453581 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -14,21 +14,21 @@ import { getTextForTokenKind, getTSNodeAccessibility, hasModifier, + isChildOptionalChain, isComma, isComputedProperty, isESTreeClassMember, isOptional, - isChildOptionalChain, - unescapeStringLiteralText, TSError, + unescapeStringLiteralText, } from './node-utils'; +import { ParserWeakMap, ParserWeakMapESTreeToTSNode } from './parser-options'; import { AST_NODE_TYPES, TSESTree, TSNode, TSESTreeToTSNode, } from './ts-estree'; -import { ParserWeakMap, ParserWeakMapESTreeToTSNode } from './parser-options'; const SyntaxKind = ts.SyntaxKind; @@ -999,8 +999,12 @@ export class Converter { case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: case SyntaxKind.MethodDeclaration: { - const method = this.createNode(node, { - type: AST_NODE_TYPES.FunctionExpression, + const method = this.createNode< + TSESTree.TSEmptyBodyFunctionExpression | TSESTree.FunctionExpression + >(node, { + type: !node.body + ? AST_NODE_TYPES.TSEmptyBodyFunctionExpression + : AST_NODE_TYPES.FunctionExpression, id: null, generator: !!node.asteriskToken, expression: false, // ESTreeNode as ESTreeNode here @@ -1109,8 +1113,12 @@ export class Converter { (lastModifier && findNextToken(lastModifier, node, this.ast)) || node.getFirstToken()!; - const constructor = this.createNode(node, { - type: AST_NODE_TYPES.FunctionExpression, + const constructor = this.createNode< + TSESTree.TSEmptyBodyFunctionExpression | TSESTree.FunctionExpression + >(node, { + type: !node.body + ? AST_NODE_TYPES.TSEmptyBodyFunctionExpression + : AST_NODE_TYPES.FunctionExpression, id: null, params: this.convertParameters(node.parameters), generator: false, diff --git a/packages/typescript-estree/src/ts-estree/ts-estree.ts b/packages/typescript-estree/src/ts-estree/ts-estree.ts index afccf30fefb..1bfb323e3d7 100644 --- a/packages/typescript-estree/src/ts-estree/ts-estree.ts +++ b/packages/typescript-estree/src/ts-estree/ts-estree.ts @@ -674,7 +674,11 @@ interface MethodDefinitionNonComputedNameBase extends MethodDefinitionBase { interface PropertyBase extends BaseNode { type: AST_NODE_TYPES.Property; key: PropertyName; - value: Expression | AssignmentPattern | BindingName; + value: + | Expression + | AssignmentPattern + | BindingName + | TSEmptyBodyFunctionExpression; computed: boolean; method: boolean; shorthand: boolean; @@ -928,6 +932,7 @@ export interface FunctionDeclaration extends FunctionDeclarationBase { export interface FunctionExpression extends FunctionDeclarationBase { type: AST_NODE_TYPES.FunctionExpression; + body: BlockStatement; } export interface Identifier extends BaseNode { diff --git a/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap index 5143a42c849..e71820fc060 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/typescript.ts.snap @@ -768,7 +768,7 @@ Object { 63, 66, ], - "type": "FunctionExpression", + "type": "TSEmptyBodyFunctionExpression", }, }, ], @@ -1216,7 +1216,7 @@ Object { }, }, }, - "type": "FunctionExpression", + "type": "TSEmptyBodyFunctionExpression", }, }, ], @@ -2433,7 +2433,7 @@ Object { 68, 71, ], - "type": "FunctionExpression", + "type": "TSEmptyBodyFunctionExpression", }, }, ], @@ -4034,7 +4034,7 @@ Object { }, }, }, - "type": "FunctionExpression", + "type": "TSEmptyBodyFunctionExpression", }, }, ], @@ -24208,7 +24208,7 @@ Object { 18, 21, ], - "type": "FunctionExpression", + "type": "TSEmptyBodyFunctionExpression", }, }, Object { @@ -24304,7 +24304,7 @@ Object { "type": "TSStringKeyword", }, }, - "type": "FunctionExpression", + "type": "TSEmptyBodyFunctionExpression", }, }, Object { @@ -24401,7 +24401,7 @@ Object { "type": "TSStringKeyword", }, }, - "type": "FunctionExpression", + "type": "TSEmptyBodyFunctionExpression", }, }, ], @@ -38261,7 +38261,7 @@ Object { "type": "TSAnyKeyword", }, }, - "type": "FunctionExpression", + "type": "TSEmptyBodyFunctionExpression", }, }, ],