From 04488c2b081a0cce1b8b8ef66d34e96b3ed0ca60 Mon Sep 17 00:00:00 2001 From: Armano Date: Wed, 26 Oct 2022 02:42:06 +0200 Subject: [PATCH] feat: create TSTypeQuery node when TSImportType has isTypeOf (#3076) * feat: update TSImportType node * fix: update visitor keys * chore: document and refactor 'extra' to 'parserSettings' (#5834) * chore(website): fix renamed Sponsorship docs link (#5882) * docs: Mention wide globs performance implications in monorepos docs and parser README (#5864) * docs: Mention wide globs performance implications in monorepos docs and parser readme * Update docs/linting/typed-linting/MONOREPOS.md Co-authored-by: Josh Goldberg Co-authored-by: Josh Goldberg Co-authored-by: Adnan Hashmi <56730784+adnanhashmi09@users.noreply.github.com> --- .../ast-spec/src/type/TSImportType/spec.ts | 3 +- .../ast-spec/src/type/TSTypeQuery/spec.ts | 3 +- .../src/referencer/TypeVisitor.ts | 9 +- .../typescript/basics/type-import-type.src.ts | 2 +- packages/typescript-estree/src/convert.ts | 21 ++++- .../src/ts-estree/estree-to-ts-node-types.ts | 2 +- .../tests/ast-alignment/fixtures-to-test.ts | 5 - .../tests/ast-alignment/utils.ts | 22 +++++ ...e-parameters-in-type-reference.src.ts.shot | 23 +++-- .../basics/type-import-type.src.ts.shot | 91 +++++++++++-------- packages/visitor-keys/src/visitor-keys.ts | 2 +- 11 files changed, 117 insertions(+), 66 deletions(-) diff --git a/packages/ast-spec/src/type/TSImportType/spec.ts b/packages/ast-spec/src/type/TSImportType/spec.ts index b2eea1a78e0..fb2d33bfe11 100644 --- a/packages/ast-spec/src/type/TSImportType/spec.ts +++ b/packages/ast-spec/src/type/TSImportType/spec.ts @@ -6,8 +6,7 @@ import type { TypeNode } from '../../unions/TypeNode'; export interface TSImportType extends BaseNode { type: AST_NODE_TYPES.TSImportType; - isTypeOf: boolean; - parameter: TypeNode; + argument: TypeNode; qualifier: EntityName | null; typeParameters: TSTypeParameterInstantiation | null; } diff --git a/packages/ast-spec/src/type/TSTypeQuery/spec.ts b/packages/ast-spec/src/type/TSTypeQuery/spec.ts index 634c307ad2c..bc9cb7e68d0 100644 --- a/packages/ast-spec/src/type/TSTypeQuery/spec.ts +++ b/packages/ast-spec/src/type/TSTypeQuery/spec.ts @@ -2,9 +2,10 @@ import type { AST_NODE_TYPES } from '../../ast-node-types'; import type { BaseNode } from '../../base/BaseNode'; import type { TSTypeParameterInstantiation } from '../../special/spec'; import type { EntityName } from '../../unions/EntityName'; +import type { TSImportType } from '../TSImportType/spec'; export interface TSTypeQuery extends BaseNode { type: AST_NODE_TYPES.TSTypeQuery; - exprName: EntityName; + exprName: EntityName | TSImportType; typeParameters?: TSTypeParameterInstantiation; } diff --git a/packages/scope-manager/src/referencer/TypeVisitor.ts b/packages/scope-manager/src/referencer/TypeVisitor.ts index 70d4f86d55a..367fe3d3f23 100644 --- a/packages/scope-manager/src/referencer/TypeVisitor.ts +++ b/packages/scope-manager/src/referencer/TypeVisitor.ts @@ -260,7 +260,10 @@ class TypeVisitor extends Visitor { // a type query `typeof foo` is a special case that references a _non-type_ variable, protected TSTypeQuery(node: TSESTree.TSTypeQuery): void { - let entityName: TSESTree.Identifier | TSESTree.ThisExpression; + let entityName: + | TSESTree.Identifier + | TSESTree.ThisExpression + | TSESTree.TSImportType; if (node.exprName.type === AST_NODE_TYPES.TSQualifiedName) { let iter = node.exprName; while (iter.left.type === AST_NODE_TYPES.TSQualifiedName) { @@ -269,6 +272,10 @@ class TypeVisitor extends Visitor { entityName = iter.left; } else { entityName = node.exprName; + + if (node.exprName.type === AST_NODE_TYPES.TSImportType) { + this.visit(node.exprName); + } } if (entityName.type === AST_NODE_TYPES.Identifier) { this.#referencer.currentScope().referenceValue(entityName); diff --git a/packages/shared-fixtures/fixtures/typescript/basics/type-import-type.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/type-import-type.src.ts index 00e3ba6afc1..5166c214216 100644 --- a/packages/shared-fixtures/fixtures/typescript/basics/type-import-type.src.ts +++ b/packages/shared-fixtures/fixtures/typescript/basics/type-import-type.src.ts @@ -1,2 +1,2 @@ type A = typeof import('A'); -type B = import("B").X; +type B = import('B').X; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 30c33050d42..ecaeed7edd8 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -2730,11 +2730,15 @@ export class Converter { return result; } - case SyntaxKind.ImportType: - return this.createNode(node, { + case SyntaxKind.ImportType: { + const range = getRange(node, this.ast); + if (node.isTypeOf) { + const token = findNextToken(node.getFirstToken()!, node, this.ast)!; + range[0] = token.getStart(this.ast); + } + const result = this.createNode(node, { type: AST_NODE_TYPES.TSImportType, - isTypeOf: !!node.isTypeOf, - parameter: this.convertChild(node.argument), + argument: this.convertChild(node.argument), qualifier: this.convertChild(node.qualifier), typeParameters: node.typeArguments ? this.convertTypeArgumentsToTypeParameters( @@ -2742,7 +2746,16 @@ export class Converter { node, ) : null, + range: range, }); + if (node.isTypeOf) { + return this.createNode(node, { + type: AST_NODE_TYPES.TSTypeQuery, + exprName: result, + }); + } + return result; + } case SyntaxKind.EnumDeclaration: { const result = this.createNode(node, { diff --git a/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts b/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts index 3b80ab0a958..575a1e9a244 100644 --- a/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts +++ b/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts @@ -225,7 +225,7 @@ export interface EstreeToTsNodeTypes { | ts.CallExpression | ts.TypeQueryNode; [AST_NODE_TYPES.TSTypePredicate]: ts.TypePredicateNode; - [AST_NODE_TYPES.TSTypeQuery]: ts.TypeQueryNode; + [AST_NODE_TYPES.TSTypeQuery]: ts.TypeQueryNode | ts.ImportTypeNode; [AST_NODE_TYPES.TSTypeReference]: ts.TypeReferenceNode; [AST_NODE_TYPES.TSUnionType]: ts.UnionTypeNode; [AST_NODE_TYPES.UpdateExpression]: diff --git a/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts b/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts index 6abab590b77..ab3e9118268 100644 --- a/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts +++ b/packages/typescript-estree/tests/ast-alignment/fixtures-to-test.ts @@ -341,11 +341,6 @@ tester.addFixturePatternConfig('typescript/basics', { * @see https://github.com/babel/babel/issues/12884 */ 'interface-with-extends-member-expression', - /** - * @see https://github.com/typescript-eslint/typescript-eslint/issues/2998 - */ - 'type-import-type', - 'type-import-type-with-type-parameters-in-type-reference', /** * Not yet supported in Babel * Directive field is not added to module and namespace diff --git a/packages/typescript-estree/tests/ast-alignment/utils.ts b/packages/typescript-estree/tests/ast-alignment/utils.ts index 717a74837b5..d92e70541aa 100644 --- a/packages/typescript-estree/tests/ast-alignment/utils.ts +++ b/packages/typescript-estree/tests/ast-alignment/utils.ts @@ -292,6 +292,28 @@ export function preprocessBabylonAST(ast: File): any { delete node.loc.start.index; } }, + TSImportType(node: any) { + if (!node.typeParameters) { + node.typeParameters = null; + } + if (!node.qualifier) { + node.qualifier = null; + } + /** + * https://github.com/babel/babel/issues/12833 + */ + if (node.argument) { + node.argument = { + type: AST_NODE_TYPES.TSLiteralType, + literal: node.argument, + loc: { + start: { ...node.argument.loc.start }, + end: { ...node.argument.loc.end }, + }, + range: [...node.argument.range], + }; + } + }, TSTypePredicate(node: any) { if (node.loc?.start?.index) { delete node.loc.start.index; diff --git a/packages/typescript-estree/tests/snapshots/typescript/basics/type-import-type-with-type-parameters-in-type-reference.src.ts.shot b/packages/typescript-estree/tests/snapshots/typescript/basics/type-import-type-with-type-parameters-in-type-reference.src.ts.shot index 3d1549888bc..2e2104b59f3 100644 --- a/packages/typescript-estree/tests/snapshots/typescript/basics/type-import-type-with-type-parameters-in-type-reference.src.ts.shot +++ b/packages/typescript-estree/tests/snapshots/typescript/basics/type-import-type-with-type-parameters-in-type-reference.src.ts.shot @@ -84,18 +84,7 @@ Object { }, "params": Array [ Object { - "isTypeOf": false, - "loc": Object { - "end": Object { - "column": 28, - "line": 1, - }, - "start": Object { - "column": 11, - "line": 1, - }, - }, - "parameter": Object { + "argument": Object { "literal": Object { "loc": Object { "end": Object { @@ -131,6 +120,16 @@ Object { ], "type": "TSLiteralType", }, + "loc": Object { + "end": Object { + "column": 28, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, "qualifier": Object { "loc": Object { "end": Object { diff --git a/packages/typescript-estree/tests/snapshots/typescript/basics/type-import-type.src.ts.shot b/packages/typescript-estree/tests/snapshots/typescript/basics/type-import-type.src.ts.shot index 1afe1ff0424..010427ef271 100644 --- a/packages/typescript-estree/tests/snapshots/typescript/basics/type-import-type.src.ts.shot +++ b/packages/typescript-estree/tests/snapshots/typescript/basics/type-import-type.src.ts.shot @@ -38,19 +38,27 @@ Object { ], "type": "TSTypeAliasDeclaration", "typeAnnotation": Object { - "isTypeOf": true, - "loc": Object { - "end": Object { - "column": 27, - "line": 1, - }, - "start": Object { - "column": 9, - "line": 1, - }, - }, - "parameter": Object { - "literal": Object { + "exprName": Object { + "argument": Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 26, + "line": 1, + }, + "start": Object { + "column": 23, + "line": 1, + }, + }, + "range": Array [ + 23, + 26, + ], + "raw": "'A'", + "type": "Literal", + "value": "A", + }, "loc": Object { "end": Object { "column": 26, @@ -65,33 +73,41 @@ Object { 23, 26, ], - "raw": "'A'", - "type": "Literal", - "value": "A", + "type": "TSLiteralType", }, "loc": Object { "end": Object { - "column": 26, + "column": 27, "line": 1, }, "start": Object { - "column": 23, + "column": 16, "line": 1, }, }, + "qualifier": null, "range": Array [ - 23, - 26, + 16, + 27, ], - "type": "TSLiteralType", + "type": "TSImportType", + "typeParameters": null, + }, + "loc": Object { + "end": Object { + "column": 27, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, }, - "qualifier": null, "range": Array [ 9, 27, ], - "type": "TSImportType", - "typeParameters": null, + "type": "TSTypeQuery", }, }, Object { @@ -129,18 +145,7 @@ Object { ], "type": "TSTypeAliasDeclaration", "typeAnnotation": Object { - "isTypeOf": false, - "loc": Object { - "end": Object { - "column": 25, - "line": 2, - }, - "start": Object { - "column": 9, - "line": 2, - }, - }, - "parameter": Object { + "argument": Object { "literal": Object { "loc": Object { "end": Object { @@ -156,7 +161,7 @@ Object { 45, 48, ], - "raw": "\\"B\\"", + "raw": "'B'", "type": "Literal", "value": "B", }, @@ -176,6 +181,16 @@ Object { ], "type": "TSLiteralType", }, + "loc": Object { + "end": Object { + "column": 25, + "line": 2, + }, + "start": Object { + "column": 9, + "line": 2, + }, + }, "qualifier": Object { "loc": Object { "end": Object { @@ -542,7 +557,7 @@ Object { 48, ], "type": "String", - "value": "\\"B\\"", + "value": "'B'", }, Object { "loc": Object { diff --git a/packages/visitor-keys/src/visitor-keys.ts b/packages/visitor-keys/src/visitor-keys.ts index a1898e92246..21648193b38 100644 --- a/packages/visitor-keys/src/visitor-keys.ts +++ b/packages/visitor-keys/src/visitor-keys.ts @@ -96,7 +96,7 @@ const additionalKeys: AdditionalKeys = { TSExternalModuleReference: ['expression'], TSFunctionType: ['typeParameters', 'params', 'returnType'], TSImportEqualsDeclaration: ['id', 'moduleReference'], - TSImportType: ['parameter', 'qualifier', 'typeParameters'], + TSImportType: ['argument', 'qualifier', 'typeParameters'], TSIndexedAccessType: ['indexType', 'objectType'], TSIndexSignature: ['parameters', 'typeAnnotation'], TSInferType: ['typeParameter'],