From 8433bbe1c6cb8e58e18d7295c6fdcb179b2a0939 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 01:37:05 +0100 Subject: [PATCH 01/15] fix: improve TSNode types --- packages/typescript-estree/src/convert.ts | 8 +- .../src/ts-estree/estree-to-ts-node-types.ts | 5 +- .../src/ts-estree/ts-nodes.ts | 103 ++++++++++-------- 3 files changed, 63 insertions(+), 53 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index f8819a33c9e..2f6cab37a93 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -244,11 +244,7 @@ export class Converter { ): T { const result = data; if (!result.range) { - result.range = getRange( - // this is completely valid, but TS hates it - node as never, - this.ast, - ); + result.range = getRange(node, this.ast); } if (!result.loc) { result.loc = getLocFor(result.range[0], result.range[1], this.ast); @@ -469,7 +465,7 @@ export class Converter { throw new Error(`Unknown AST_NODE_TYPE: "${customType}"`); } - const result = this.createNode(node, { + const result = this.createNode(node as any, { type: customType, }); 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 62053920280..896b2212968 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 @@ -1,6 +1,6 @@ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/types'; import * as ts from 'typescript'; -import { TSNode } from './ts-nodes'; +import { TSNode, TSNodeUnsupported, TSNodeSkipped } from './ts-nodes'; export interface EstreeToTsNodeTypes { [AST_NODE_TYPES.ArrayExpression]: ts.ArrayLiteralExpression; @@ -279,7 +279,8 @@ export interface EstreeToTsNodeTypes { * This mapping is based on the internal logic of the parser. */ export type TSESTreeToTSNode = Extract< - TSNode | ts.Token, + | Exclude + | ts.Token, // if this errors, it means that one of the AST_NODE_TYPES is not defined in the above interface EstreeToTsNodeTypes[T['type']] >; diff --git a/packages/typescript-estree/src/ts-estree/ts-nodes.ts b/packages/typescript-estree/src/ts-estree/ts-nodes.ts index 80a7b34e0c8..85ffa45af9f 100644 --- a/packages/typescript-estree/src/ts-estree/ts-nodes.ts +++ b/packages/typescript-estree/src/ts-estree/ts-nodes.ts @@ -11,11 +11,67 @@ declare module 'typescript' { export type TSToken = ts.Token; +export type TSNodeSkipped = + | ts.OmittedExpression + | ts.ComputedPropertyName // we are skipping this node + | ts.CaseBlock + | ts.HeritageClause + | ts.NamedImports + | ts.NamedExports + | ts.TemplateSpan; + +export type TSNodeUnsupported = + | ts.PartiallyEmittedExpression + | ts.SyntheticExpression + | ts.ParenthesizedExpression + | ts.NotEmittedStatement + | ts.CommaListExpression + | ts.MissingDeclaration + | ts.Bundle + | ts.InputFiles + | ts.UnparsedNode + | ts.UnparsedSource + | ts.SemicolonClassElement + + // Modifiers + | ts.ConstKeyword + | ts.DefaultKeyword + + // JSON: Unsupported + | ts.JsonMinusNumericLiteral + + // JSDoc: Unsupported + | ts.JSDoc + | ts.JSDocTypeExpression + | ts.JSDocUnknownTag + | ts.JSDocAugmentsTag + | ts.JSDocClassTag + | ts.JSDocEnumTag + | ts.JSDocThisTag + | ts.JSDocTemplateTag + | ts.JSDocReturnTag + | ts.JSDocTypeTag + | ts.JSDocTypedefTag + | ts.JSDocCallbackTag + | ts.JSDocSignature + | ts.JSDocPropertyTag + | ts.JSDocParameterTag + | ts.JSDocTypeLiteral + | ts.JSDocFunctionType + | ts.JSDocAllType + | ts.JSDocUnknownType + | ts.JSDocNullableType + | ts.JSDocNonNullableType + | ts.JSDocOptionalType + | ts.JSDocVariadicType + | ts.JSDocAuthorTag; + export type TSNode = + | TSNodeUnsupported + | TSNodeSkipped | ts.Modifier | ts.Identifier | ts.QualifiedName - | ts.ComputedPropertyName | ts.Decorator | ts.TypeParameterDeclaration // | ts.SignatureDeclarationBase -> CallSignatureDeclaration, ConstructSignatureDeclaration @@ -36,7 +92,6 @@ export type TSNode = | ts.MethodSignature | ts.MethodDeclaration | ts.ConstructorDeclaration - | ts.SemicolonClassElement | ts.GetAccessorDeclaration | ts.SetAccessorDeclaration | ts.IndexSignatureDeclaration @@ -65,8 +120,6 @@ export type TSNode = | ts.MappedTypeNode | ts.LiteralTypeNode | ts.StringLiteral - | ts.OmittedExpression - | ts.PartiallyEmittedExpression | ts.PrefixUnaryExpression | ts.PostfixUnaryExpression | ts.NullLiteral @@ -79,7 +132,6 @@ export type TSNode = | ts.VoidExpression | ts.AwaitExpression | ts.YieldExpression - | ts.SyntheticExpression | ts.BinaryExpression | ts.ConditionalExpression | ts.FunctionExpression @@ -92,8 +144,6 @@ export type TSNode = | ts.TemplateMiddle | ts.TemplateTail | ts.TemplateExpression - | ts.TemplateSpan - | ts.ParenthesizedExpression | ts.ArrayLiteralExpression | ts.SpreadElement | ts.ObjectLiteralExpression @@ -118,11 +168,8 @@ export type TSNode = | ts.JsxClosingElement | ts.JsxExpression | ts.JsxText - | ts.NotEmittedStatement - | ts.CommaListExpression | ts.EmptyStatement | ts.DebuggerStatement - | ts.MissingDeclaration | ts.Block | ts.VariableStatement | ts.ExpressionStatement @@ -137,7 +184,6 @@ export type TSNode = | ts.ReturnStatement | ts.WithStatement | ts.SwitchStatement - | ts.CaseBlock | ts.CaseClause | ts.DefaultClause | ts.LabeledStatement @@ -148,7 +194,6 @@ export type TSNode = | ts.ClassDeclaration | ts.ClassExpression | ts.InterfaceDeclaration - | ts.HeritageClause | ts.TypeAliasDeclaration | ts.EnumMember | ts.EnumDeclaration @@ -161,40 +206,8 @@ export type TSNode = | ts.NamespaceImport | ts.NamespaceExportDeclaration | ts.ExportDeclaration - | ts.NamedImports - | ts.NamedExports | ts.ImportSpecifier | ts.ExportSpecifier | ts.ExportAssignment | ts.SourceFile - | ts.Bundle - | ts.InputFiles - | ts.UnparsedSource - | ts.JsonMinusNumericLiteral - | ts.TemplateLiteralTypeNode - - // JSDoc: Unsupported - | ts.JSDoc - | ts.JSDocTypeExpression - | ts.JSDocUnknownTag - | ts.JSDocAugmentsTag - | ts.JSDocClassTag - | ts.JSDocEnumTag - | ts.JSDocThisTag - | ts.JSDocTemplateTag - | ts.JSDocReturnTag - | ts.JSDocTypeTag - | ts.JSDocTypedefTag - | ts.JSDocCallbackTag - | ts.JSDocSignature - | ts.JSDocPropertyTag - | ts.JSDocParameterTag - | ts.JSDocTypeLiteral - | ts.JSDocFunctionType - | ts.JSDocAllType - | ts.JSDocUnknownType - | ts.JSDocNullableType - | ts.JSDocNonNullableType - | ts.JSDocOptionalType - | ts.JSDocVariadicType - | ts.JSDocAuthorTag; + | ts.TemplateLiteralTypeNode; From 2782ac7b6a0685a9ee7a8939d6609631030eb580 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 08:04:45 +0100 Subject: [PATCH 02/15] fix: small patch to AST --- packages/types/src/ts-estree.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/types/src/ts-estree.ts b/packages/types/src/ts-estree.ts index 4dd89c962be..775c9d94e19 100644 --- a/packages/types/src/ts-estree.ts +++ b/packages/types/src/ts-estree.ts @@ -1077,7 +1077,7 @@ export interface JSXOpeningElement extends BaseNode { typeParameters?: TSTypeParameterInstantiation; selfClosing: boolean; name: JSXTagNameExpression; - attributes: JSXAttribute[]; + attributes: (JSXAttribute | JSXSpreadAttribute)[]; } export interface JSXOpeningFragment extends BaseNode { @@ -1186,7 +1186,7 @@ export interface PropertyNonComputedName extends PropertyBase { export interface RegExpLiteral extends LiteralBase { type: AST_NODE_TYPES.Literal; - value: RegExp; + value: RegExp | null; } export interface RestElement extends BaseNode { From 2d4b5d90e818eda7749df73ad6d00a95a3923bfb Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 08:18:38 +0100 Subject: [PATCH 03/15] fix: add basic type guards --- .../typescript-estree/src/convert-guards.ts | 279 ++++++++++++++++++ packages/typescript-estree/src/convert.ts | 73 +++-- .../src/ts-estree/ts-nodes.ts | 32 +- 3 files changed, 353 insertions(+), 31 deletions(-) create mode 100644 packages/typescript-estree/src/convert-guards.ts diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts new file mode 100644 index 00000000000..92bfcbbb010 --- /dev/null +++ b/packages/typescript-estree/src/convert-guards.ts @@ -0,0 +1,279 @@ +import { TSESTree } from '@typescript-eslint/types'; +import * as ts from 'typescript'; +import { + TSNodeClassElement, + TSNodeExpression, + TSNodeSupported, + TSNodeStatement, + TSNodeTypeElement, + TSNodeTypeNode, +} from './ts-estree/ts-nodes'; + +/** + * this is not correct yet, additional refining is required + */ +export interface TSESTreeToTSNodeTypes { + [ts.SyntaxKind.SourceFile]: TSESTree.Program; + [ts.SyntaxKind.Block]: TSESTree.BlockStatement; + [ts.SyntaxKind.Identifier]: TSESTree.Identifier; + [ts.SyntaxKind.WithStatement]: TSESTree.WithStatement; + [ts.SyntaxKind.ReturnStatement]: TSESTree.ReturnStatement; + [ts.SyntaxKind.LabeledStatement]: TSESTree.LabeledStatement; + [ts.SyntaxKind.ContinueStatement]: TSESTree.ContinueStatement; + [ts.SyntaxKind.BreakStatement]: TSESTree.BreakStatement; + [ts.SyntaxKind.IfStatement]: TSESTree.IfStatement; + [ts.SyntaxKind.SwitchStatement]: TSESTree.SwitchStatement; + [ts.SyntaxKind.CaseClause]: TSESTree.SwitchCase; + [ts.SyntaxKind.DefaultClause]: TSESTree.SwitchCase; + [ts.SyntaxKind.ThrowStatement]: TSESTree.ThrowStatement; + [ts.SyntaxKind.TryStatement]: TSESTree.TryStatement; + [ts.SyntaxKind.CatchClause]: TSESTree.CatchClause; + [ts.SyntaxKind.WhileStatement]: TSESTree.WhileStatement; + [ts.SyntaxKind.DoStatement]: TSESTree.DoWhileStatement; + [ts.SyntaxKind.ForStatement]: TSESTree.ForStatement; + [ts.SyntaxKind.ForInStatement]: TSESTree.ForInStatement; + [ts.SyntaxKind.ForOfStatement]: TSESTree.ForOfStatement; + [ts.SyntaxKind.FunctionDeclaration]: + | TSESTree.TSDeclareFunction + | TSESTree.FunctionDeclaration; + [ts.SyntaxKind.VariableDeclaration]: TSESTree.VariableDeclarator; + [ts.SyntaxKind.VariableStatement]: TSESTree.VariableDeclaration; + [ts.SyntaxKind.VariableDeclarationList]: TSESTree.VariableDeclaration; + [ts.SyntaxKind.ExpressionStatement]: TSESTree.ExpressionStatement; + [ts.SyntaxKind.ThisKeyword]: TSESTree.ThisExpression; + // TODO: conditional + [ts.SyntaxKind.ArrayLiteralExpression]: + | TSESTree.ArrayPattern + | TSESTree.ArrayExpression; + // TODO: conditional + [ts.SyntaxKind.ObjectLiteralExpression]: + | TSESTree.ObjectPattern + | TSESTree.ObjectExpression; + [ts.SyntaxKind.PropertyAssignment]: TSESTree.Property; + [ts.SyntaxKind.ShorthandPropertyAssignment]: TSESTree.Property; + // TODO: skipped node + [ts.SyntaxKind.ComputedPropertyName]: null; + [ts.SyntaxKind.PropertyDeclaration]: + | TSESTree.TSAbstractClassProperty + | TSESTree.ClassProperty; + // TODO: conditional + [ts.SyntaxKind.GetAccessor]: + | TSESTree.TSEmptyBodyFunctionExpression + | TSESTree.TSAbstractMethodDefinition + | TSESTree.MethodDefinition + | TSESTree.FunctionExpression + | TSESTree.Property; + [ts.SyntaxKind.SetAccessor]: + | TSESTree.TSEmptyBodyFunctionExpression + | TSESTree.TSAbstractMethodDefinition + | TSESTree.MethodDefinition + | TSESTree.FunctionExpression + | TSESTree.Property; + [ts.SyntaxKind.MethodDeclaration]: + | TSESTree.TSEmptyBodyFunctionExpression + | TSESTree.TSAbstractMethodDefinition + | TSESTree.MethodDefinition + | TSESTree.FunctionExpression + | TSESTree.Property; + [ts.SyntaxKind.Constructor]: + | TSESTree.TSAbstractMethodDefinition + | TSESTree.MethodDefinition; + [ts.SyntaxKind.FunctionExpression]: TSESTree.FunctionExpression; + [ts.SyntaxKind.SuperKeyword]: TSESTree.Super; + [ts.SyntaxKind.ArrayBindingPattern]: TSESTree.ArrayPattern; + [ts.SyntaxKind.OmittedExpression]: null; + [ts.SyntaxKind.ObjectBindingPattern]: TSESTree.ObjectPattern; + [ts.SyntaxKind.BindingElement]: + | TSESTree.AssignmentPattern + | TSESTree.RestElement + | TSESTree.Property; + [ts.SyntaxKind.ArrowFunction]: TSESTree.ArrowFunctionExpression; + [ts.SyntaxKind.YieldExpression]: TSESTree.YieldExpression; + [ts.SyntaxKind.AwaitExpression]: TSESTree.AwaitExpression; + [ts.SyntaxKind.NoSubstitutionTemplateLiteral]: TSESTree.TemplateLiteral; + [ts.SyntaxKind.TemplateExpression]: TSESTree.TemplateLiteral; + [ts.SyntaxKind.TaggedTemplateExpression]: TSESTree.TaggedTemplateExpression; + [ts.SyntaxKind.TemplateHead]: TSESTree.TemplateElement; + [ts.SyntaxKind.TemplateMiddle]: TSESTree.TemplateElement; + [ts.SyntaxKind.TemplateTail]: TSESTree.TemplateElement; + [ts.SyntaxKind.SpreadAssignment]: + | TSESTree.RestElement + | TSESTree.SpreadElement; + [ts.SyntaxKind.SpreadElement]: TSESTree.RestElement | TSESTree.SpreadElement; + [ts.SyntaxKind.Parameter]: + | TSESTree.RestElement + | TSESTree.AssignmentPattern + | TSESTree.TSParameterProperty; + [ts.SyntaxKind.ClassDeclaration]: TSESTree.ClassDeclaration; + [ts.SyntaxKind.ClassExpression]: TSESTree.ClassExpression; + [ts.SyntaxKind.ModuleBlock]: TSESTree.TSModuleBlock; + [ts.SyntaxKind.ImportDeclaration]: TSESTree.ImportDeclaration; + [ts.SyntaxKind.NamespaceImport]: TSESTree.ImportNamespaceSpecifier; + [ts.SyntaxKind.ImportSpecifier]: TSESTree.ImportSpecifier; + [ts.SyntaxKind.ImportClause]: TSESTree.ImportDefaultSpecifier; + [ts.SyntaxKind.ExportDeclaration]: + | TSESTree.ExportNamedDeclaration + | TSESTree.ExportAllDeclaration; + [ts.SyntaxKind.ExportSpecifier]: TSESTree.ExportSpecifier; + [ts.SyntaxKind.ExportAssignment]: + | TSESTree.TSExportAssignment + | TSESTree.ExportDefaultDeclaration; + [ts.SyntaxKind.PrefixUnaryExpression]: + | TSESTree.UpdateExpression + | TSESTree.UnaryExpression; + [ts.SyntaxKind.PostfixUnaryExpression]: + | TSESTree.UpdateExpression + | TSESTree.UnaryExpression; + [ts.SyntaxKind.DeleteExpression]: TSESTree.UnaryExpression; + [ts.SyntaxKind.VoidExpression]: TSESTree.UnaryExpression; + [ts.SyntaxKind.TypeOfExpression]: TSESTree.UnaryExpression; + [ts.SyntaxKind.TypeOperator]: TSESTree.TSTypeOperator; + [ts.SyntaxKind.BinaryExpression]: + | TSESTree.SequenceExpression + | TSESTree.AssignmentExpression + | TSESTree.LogicalExpression + | TSESTree.BinaryExpression + | TSESTree.AssignmentPattern; + [ts.SyntaxKind.PropertyAccessExpression]: + | TSESTree.MemberExpression + | TSESTree.ChainExpression; + [ts.SyntaxKind.ElementAccessExpression]: + | TSESTree.MemberExpression + | TSESTree.ChainExpression; + [ts.SyntaxKind.CallExpression]: + | TSESTree.ImportExpression + | TSESTree.CallExpression + | TSESTree.ChainExpression; + [ts.SyntaxKind.NewExpression]: TSESTree.NewExpression; + [ts.SyntaxKind.ConditionalExpression]: TSESTree.ConditionalExpression; + [ts.SyntaxKind.MetaProperty]: TSESTree.MetaProperty; + [ts.SyntaxKind.Decorator]: TSESTree.Decorator; + [ts.SyntaxKind.StringLiteral]: TSESTree.StringLiteral; + [ts.SyntaxKind.NumericLiteral]: TSESTree.NumberLiteral; + [ts.SyntaxKind.BigIntLiteral]: TSESTree.BigIntLiteral; + [ts.SyntaxKind.RegularExpressionLiteral]: TSESTree.RegExpLiteral; + [ts.SyntaxKind.TrueKeyword]: TSESTree.BooleanLiteral; + [ts.SyntaxKind.FalseKeyword]: TSESTree.BooleanLiteral; + [ts.SyntaxKind.NullKeyword]: TSESTree.NullLiteral | TSESTree.TSNullKeyword; + [ts.SyntaxKind.EmptyStatement]: TSESTree.EmptyStatement; + [ts.SyntaxKind.DebuggerStatement]: TSESTree.DebuggerStatement; + [ts.SyntaxKind.JsxElement]: TSESTree.JSXElement; + [ts.SyntaxKind.JsxFragment]: TSESTree.JSXFragment; + [ts.SyntaxKind.JsxSelfClosingElement]: TSESTree.JSXElement; + [ts.SyntaxKind.JsxOpeningElement]: TSESTree.JSXOpeningElement; + [ts.SyntaxKind.JsxClosingElement]: TSESTree.JSXClosingElement; + [ts.SyntaxKind.JsxOpeningFragment]: TSESTree.JSXOpeningFragment; + [ts.SyntaxKind.JsxClosingFragment]: TSESTree.JSXClosingFragment; + [ts.SyntaxKind.JsxExpression]: + | TSESTree.JSXSpreadChild + | TSESTree.JSXExpressionContainer; + [ts.SyntaxKind.JsxAttribute]: TSESTree.JSXAttribute; + [ts.SyntaxKind.JsxText]: TSESTree.JSXText; + [ts.SyntaxKind.JsxSpreadAttribute]: TSESTree.JSXSpreadAttribute; + [ts.SyntaxKind.QualifiedName]: TSESTree.TSQualifiedName; + [ts.SyntaxKind.TypeReference]: TSESTree.TSTypeReference; + [ts.SyntaxKind.TypeParameter]: TSESTree.TSTypeParameter; + [ts.SyntaxKind.ThisType]: TSESTree.TSThisType; + [ts.SyntaxKind.AnyKeyword]: TSESTree.TSAnyKeyword; + [ts.SyntaxKind.BigIntKeyword]: TSESTree.TSBigIntKeyword; + [ts.SyntaxKind.BooleanKeyword]: TSESTree.TSBooleanKeyword; + [ts.SyntaxKind.NeverKeyword]: TSESTree.TSNeverKeyword; + [ts.SyntaxKind.NumberKeyword]: TSESTree.TSNumberKeyword; + [ts.SyntaxKind.ObjectKeyword]: TSESTree.TSObjectKeyword; + [ts.SyntaxKind.StringKeyword]: TSESTree.TSStringKeyword; + [ts.SyntaxKind.SymbolKeyword]: TSESTree.TSSymbolKeyword; + [ts.SyntaxKind.UnknownKeyword]: TSESTree.TSUnknownKeyword; + [ts.SyntaxKind.VoidKeyword]: TSESTree.TSVoidKeyword; + [ts.SyntaxKind.UndefinedKeyword]: TSESTree.TSUndefinedKeyword; + [ts.SyntaxKind.NonNullExpression]: + | TSESTree.TSNonNullExpression + | TSESTree.ChainExpression; + [ts.SyntaxKind.TypeLiteral]: TSESTree.TSTypeLiteral; + [ts.SyntaxKind.ArrayType]: TSESTree.TSArrayType; + [ts.SyntaxKind.IndexedAccessType]: TSESTree.TSIndexedAccessType; + [ts.SyntaxKind.ConditionalType]: TSESTree.TSConditionalType; + [ts.SyntaxKind.TypeQuery]: TSESTree.TSTypeQuery; + [ts.SyntaxKind.MappedType]: TSESTree.TSMappedType; + // TODO: exports + [ts.SyntaxKind.TypeAliasDeclaration]: TSESTree.TSTypeAliasDeclaration; + [ts.SyntaxKind.MethodSignature]: TSESTree.TSMethodSignature; + [ts.SyntaxKind.PropertySignature]: TSESTree.TSPropertySignature; + [ts.SyntaxKind.IndexSignature]: TSESTree.TSIndexSignature; + [ts.SyntaxKind.ConstructorType]: TSESTree.TSConstructorType; + [ts.SyntaxKind.FunctionType]: TSESTree.TSFunctionType; + [ts.SyntaxKind.ConstructSignature]: TSESTree.TSConstructSignatureDeclaration; + [ts.SyntaxKind.CallSignature]: TSESTree.TSCallSignatureDeclaration; + [ts.SyntaxKind.ExpressionWithTypeArguments]: + | TSESTree.TSInterfaceHeritage + | TSESTree.TSClassImplements; + // TODO: exports + [ts.SyntaxKind.InterfaceDeclaration]: TSESTree.TSInterfaceDeclaration; + [ts.SyntaxKind.TypePredicate]: TSESTree.TSTypePredicate; + [ts.SyntaxKind.ImportType]: TSESTree.TSImportType; + [ts.SyntaxKind.EnumDeclaration]: TSESTree.TSEnumDeclaration; + [ts.SyntaxKind.EnumMember]: TSESTree.TSEnumMember; + [ts.SyntaxKind.ModuleDeclaration]: TSESTree.TSModuleDeclaration; + [ts.SyntaxKind.ParenthesizedType]: TSESTree.TSParenthesizedType; + [ts.SyntaxKind.UnionType]: TSESTree.TSUnionType; + [ts.SyntaxKind.IntersectionType]: TSESTree.TSIntersectionType; + [ts.SyntaxKind.AsExpression]: TSESTree.TSAsExpression; + [ts.SyntaxKind.InferType]: TSESTree.TSInferType; + [ts.SyntaxKind.LiteralType]: TSESTree.TSLiteralType; + [ts.SyntaxKind.TypeAssertionExpression]: TSESTree.TSTypeAssertion; + [ts.SyntaxKind.ImportEqualsDeclaration]: TSESTree.TSImportEqualsDeclaration; + [ts.SyntaxKind.ExternalModuleReference]: TSESTree.TSExternalModuleReference; + [ts.SyntaxKind + .NamespaceExportDeclaration]: TSESTree.TSNamespaceExportDeclaration; + [ts.SyntaxKind.AbstractKeyword]: TSESTree.TSAbstractKeyword; + [ts.SyntaxKind.TupleType]: TSESTree.TSTupleType; + [ts.SyntaxKind.NamedTupleMember]: + | TSESTree.TSNamedTupleMember + | TSESTree.TSRestType; + [ts.SyntaxKind.OptionalType]: TSESTree.TSOptionalType; + [ts.SyntaxKind.RestType]: TSESTree.TSRestType; + [ts.SyntaxKind.TemplateLiteralType]: TSESTree.TSTemplateLiteralType; + + // TODO: just for testing - delete/change me + [ts.SyntaxKind.ExportKeyword]: 'ExportKeyword'; + [ts.SyntaxKind.ImportKeyword]: 'ImportKeyword'; + [ts.SyntaxKind.PrivateKeyword]: 'PrivateKeyword'; + [ts.SyntaxKind.StaticKeyword]: 'StaticKeyword'; + [ts.SyntaxKind.ProtectedKeyword]: 'ProtectedKeyword'; + [ts.SyntaxKind.AsyncKeyword]: 'AsyncKeyword'; + [ts.SyntaxKind.PublicKeyword]: 'PublicKeyword'; + [ts.SyntaxKind.DeclareKeyword]: 'DeclareKeyword'; + [ts.SyntaxKind.IntrinsicKeyword]: 'IntrinsicKeyword'; + [ts.SyntaxKind.ReadonlyKeyword]: 'ReadonlyKeyword'; + [ts.SyntaxKind.TemplateSpan]: 'TemplateSpan'; + [ts.SyntaxKind.CaseBlock]: 'CaseBlock'; + [ts.SyntaxKind.NamedImports]: 'NamedImports'; + [ts.SyntaxKind.NamedExports]: 'NamedExports'; + [ts.SyntaxKind.HeritageClause]: 'HeritageClause'; +} + +// export type TypeTest = Exclude< +// TSNodeSupported['kind'], +// keyof TSESTreeToTSNodeTypes +// >; + +export type TSESTreeToTSNode2< + T extends TSNodeSupported | undefined +> = T extends Exclude + ? TSESTreeToTSNodeTypes[T['kind']] + : T extends ts.ParenthesizedExpression + ? TSESTreeToTSNode2> + : null; + +export type TSESTreeToTSNodeGuard = T extends TSNodeSupported + ? TSESTreeToTSNode2 + : T extends ts.Expression + ? TSESTreeToTSNode2 + : T extends ts.Statement + ? TSESTreeToTSNode2 + : T extends ts.TypeNode + ? TSESTreeToTSNode2 + : T extends ts.TypeElement + ? TSESTreeToTSNode2 + : T extends ts.ClassElement + ? TSESTreeToTSNode2 + : null; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 2f6cab37a93..ebbf2a3004b 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -29,7 +29,11 @@ import { TSESTree, TSESTreeToTSNode, TSNode, + TSNodeConvertable, + TSNodeSupported, } from './ts-estree'; +import { TSESTreeToTSNode2, TSESTreeToTSNodeGuard } from './convert-guards'; + import { typescriptVersionIsAtLeast } from './version-check'; const SyntaxKind = ts.SyntaxKind; @@ -86,7 +90,7 @@ export class Converter { } convertProgram(): TSESTree.Program { - return this.converter(this.ast) as TSESTree.Program; + return this.converter(this.ast); } /** @@ -97,12 +101,12 @@ export class Converter { * @param allowPattern flag to determine if patterns are allowed * @returns the converted ESTree node */ - private converter( - node?: ts.Node, + private converter( + node: T, parent?: ts.Node, inTypeMode?: boolean, allowPattern?: boolean, - ): any { + ): TSESTreeToTSNodeGuard { /** * Exit early for null and undefined */ @@ -119,10 +123,7 @@ export class Converter { this.allowPattern = allowPattern; } - const result = this.convertNode( - node as TSNode, - (parent ?? node.parent) as TSNode, - ); + const result = this.convertNode(node, (parent ?? node.parent) as TSNode); this.registerTSNodeInNodeMap(node, result); @@ -214,8 +215,11 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - private convertPattern(child?: ts.Node, parent?: ts.Node): any | null { - return this.converter(child, parent, this.inTypeMode, true); + private convertPattern( + child: T, + parent?: ts.Node, + ): TSESTreeToTSNodeGuard { + return this.converter(child, parent, this.inTypeMode, true); } /** @@ -224,8 +228,11 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - private convertChild(child?: ts.Node, parent?: ts.Node): any | null { - return this.converter(child, parent, this.inTypeMode, false); + private convertChild( + child: T, + parent?: ts.Node, + ): TSESTreeToTSNodeGuard { + return this.converter(child, parent, this.inTypeMode, false); } /** @@ -234,8 +241,11 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - private convertType(child?: ts.Node, parent?: ts.Node): any | null { - return this.converter(child, parent, true, false); + private convertType( + child: T, + parent?: ts.Node, + ): TSESTreeToTSNodeGuard { + return this.converter(child, parent, true, false); } private createNode( @@ -313,7 +323,7 @@ export class Converter { return ( nodes - .map(statement => { + .map(statement => { const child = this.convertChild(statement); if (allowDirectives) { if ( @@ -331,7 +341,9 @@ export class Converter { return child; // child can be null, but it's filtered below }) // filter out unknown nodes for now - .filter(statement => statement) + .filter((statement): statement is TSESTree.Statement => + Boolean(statement), + ) ); } @@ -646,7 +658,10 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - private convertNode(node: TSNode, parent: TSNode): TSESTree.Node | null { + private convertNode( + node: TSNodeSupported, + parent: TSNode, + ): TSESTreeToTSNode2 { switch (node.kind) { case SyntaxKind.SourceFile: { return this.createNode(node, { @@ -828,7 +843,7 @@ export class Converter { expression: false, async: hasModifier(SyntaxKind.AsyncKeyword, node), params: this.convertParameters(node.parameters), - body: this.convertChild(node.body) || undefined, + body: this.convertChild(node.body) ?? undefined, }); // Process returnType @@ -1440,7 +1455,7 @@ export class Converter { argument: this.convertChild(node.name), }); } else if (node.initializer) { - parameter = this.convertChild(node.name) as TSESTree.BindingName; + parameter = this.convertChild(node.name); result = this.createNode(node, { type: AST_NODE_TYPES.AssignmentPattern, left: parameter, @@ -1917,7 +1932,7 @@ export class Converter { // Literals case SyntaxKind.StringLiteral: { - return this.createNode(node, { + return this.createNode(node, { type: AST_NODE_TYPES.Literal, value: parent.kind === SyntaxKind.JsxAttribute @@ -1928,7 +1943,7 @@ export class Converter { } case SyntaxKind.NumericLiteral: { - return this.createNode(node, { + return this.createNode(node, { type: AST_NODE_TYPES.Literal, value: Number(node.text), raw: node.getText(), @@ -1965,7 +1980,7 @@ export class Converter { regex = null; } - return this.createNode(node, { + return this.createNode(node, { type: AST_NODE_TYPES.Literal, value: regex, raw: node.text, @@ -1977,14 +1992,14 @@ export class Converter { } case SyntaxKind.TrueKeyword: - return this.createNode(node, { + return this.createNode(node, { type: AST_NODE_TYPES.Literal, value: true, raw: 'true', }); case SyntaxKind.FalseKeyword: - return this.createNode(node, { + return this.createNode(node, { type: AST_NODE_TYPES.Literal, value: false, raw: 'false', @@ -2114,7 +2129,9 @@ export class Converter { } case SyntaxKind.JsxAttribute: { - const attributeName = this.convertChild(node.name); + const attributeName = this.convertChild( + node.name, + ) as TSESTree.JSXIdentifier; attributeName.type = AST_NODE_TYPES.JSXIdentifier; return this.createNode(node, { @@ -2365,7 +2382,7 @@ export class Converter { typeAnnotation: node.type ? this.convertTypeAnnotation(node.type, node) : undefined, - initializer: this.convertChild(node.initializer) || undefined, + initializer: this.convertChild(node.initializer) ?? undefined, readonly: hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined, static: hasModifier(SyntaxKind.StaticKeyword, node) || undefined, export: hasModifier(SyntaxKind.ExportKeyword, node) || undefined, @@ -2691,10 +2708,10 @@ export class Converter { // if the former does not exist. const elementTypes = 'elementTypes' in node - ? (node as any).elementTypes.map((el: ts.Node) => + ? (node as any).elementTypes.map((el: ts.TypeElement) => this.convertType(el), ) - : node.elements.map((el: ts.Node) => this.convertType(el)); + : node.elements.map(el => this.convertType(el)); return this.createNode(node, { type: AST_NODE_TYPES.TSTupleType, diff --git a/packages/typescript-estree/src/ts-estree/ts-nodes.ts b/packages/typescript-estree/src/ts-estree/ts-nodes.ts index 85ffa45af9f..171f5325c6e 100644 --- a/packages/typescript-estree/src/ts-estree/ts-nodes.ts +++ b/packages/typescript-estree/src/ts-estree/ts-nodes.ts @@ -18,12 +18,12 @@ export type TSNodeSkipped = | ts.HeritageClause | ts.NamedImports | ts.NamedExports - | ts.TemplateSpan; + | ts.TemplateSpan + | ts.ParenthesizedExpression; export type TSNodeUnsupported = | ts.PartiallyEmittedExpression | ts.SyntheticExpression - | ts.ParenthesizedExpression | ts.NotEmittedStatement | ts.CommaListExpression | ts.MissingDeclaration @@ -38,7 +38,7 @@ export type TSNodeUnsupported = | ts.DefaultKeyword // JSON: Unsupported - | ts.JsonMinusNumericLiteral + // | ts.JsonMinusNumericLiteral // same node as PrefixUnaryExpression // JSDoc: Unsupported | ts.JSDoc @@ -66,6 +66,8 @@ export type TSNodeUnsupported = | ts.JSDocVariadicType | ts.JSDocAuthorTag; +// TODO: replace with code that retrieves all nodes that have kind +// export type TSNode2 = Extract export type TSNode = | TSNodeUnsupported | TSNodeSkipped @@ -211,3 +213,27 @@ export type TSNode = | ts.ExportAssignment | ts.SourceFile | ts.TemplateLiteralTypeNode; + +export type TSNodeSupported = Exclude; +export type TSNodeExpression = Exclude< + Extract, + // manual fixes + ts.OmittedExpression +>; +export type TSNodeStatement = Extract; +export type TSNodeTypeNode = Exclude< + Extract, + // manual fixes + ts.ExpressionWithTypeArguments +>; +export type TSNodeTypeElement = Extract; +export type TSNodeClassElement = Extract; + +export type TSNodeConvertable = + | TSNode + | ts.Expression + | ts.Statement + | ts.TypeNode + | ts.TypeElement + | ts.ClassElement + | undefined; From 7ca33187d3875df5bfa25cb2cc1885848d7180fa Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 15:46:21 +0100 Subject: [PATCH 04/15] fix: split pattern from non pattern guards --- .../typescript-estree/src/convert-guards.ts | 81 +++++++++++-------- .../src/ts-estree/ts-nodes.ts | 9 ++- 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index 92bfcbbb010..b78a5f3f031 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -12,7 +12,7 @@ import { /** * this is not correct yet, additional refining is required */ -export interface TSESTreeToTSNodeTypes { +export interface BaseGuard { [ts.SyntaxKind.SourceFile]: TSESTree.Program; [ts.SyntaxKind.Block]: TSESTree.BlockStatement; [ts.SyntaxKind.Identifier]: TSESTree.Identifier; @@ -41,14 +41,6 @@ export interface TSESTreeToTSNodeTypes { [ts.SyntaxKind.VariableDeclarationList]: TSESTree.VariableDeclaration; [ts.SyntaxKind.ExpressionStatement]: TSESTree.ExpressionStatement; [ts.SyntaxKind.ThisKeyword]: TSESTree.ThisExpression; - // TODO: conditional - [ts.SyntaxKind.ArrayLiteralExpression]: - | TSESTree.ArrayPattern - | TSESTree.ArrayExpression; - // TODO: conditional - [ts.SyntaxKind.ObjectLiteralExpression]: - | TSESTree.ObjectPattern - | TSESTree.ObjectExpression; [ts.SyntaxKind.PropertyAssignment]: TSESTree.Property; [ts.SyntaxKind.ShorthandPropertyAssignment]: TSESTree.Property; // TODO: skipped node @@ -83,10 +75,6 @@ export interface TSESTreeToTSNodeTypes { [ts.SyntaxKind.ArrayBindingPattern]: TSESTree.ArrayPattern; [ts.SyntaxKind.OmittedExpression]: null; [ts.SyntaxKind.ObjectBindingPattern]: TSESTree.ObjectPattern; - [ts.SyntaxKind.BindingElement]: - | TSESTree.AssignmentPattern - | TSESTree.RestElement - | TSESTree.Property; [ts.SyntaxKind.ArrowFunction]: TSESTree.ArrowFunctionExpression; [ts.SyntaxKind.YieldExpression]: TSESTree.YieldExpression; [ts.SyntaxKind.AwaitExpression]: TSESTree.AwaitExpression; @@ -96,10 +84,6 @@ export interface TSESTreeToTSNodeTypes { [ts.SyntaxKind.TemplateHead]: TSESTree.TemplateElement; [ts.SyntaxKind.TemplateMiddle]: TSESTree.TemplateElement; [ts.SyntaxKind.TemplateTail]: TSESTree.TemplateElement; - [ts.SyntaxKind.SpreadAssignment]: - | TSESTree.RestElement - | TSESTree.SpreadElement; - [ts.SyntaxKind.SpreadElement]: TSESTree.RestElement | TSESTree.SpreadElement; [ts.SyntaxKind.Parameter]: | TSESTree.RestElement | TSESTree.AssignmentPattern @@ -128,12 +112,6 @@ export interface TSESTreeToTSNodeTypes { [ts.SyntaxKind.VoidExpression]: TSESTree.UnaryExpression; [ts.SyntaxKind.TypeOfExpression]: TSESTree.UnaryExpression; [ts.SyntaxKind.TypeOperator]: TSESTree.TSTypeOperator; - [ts.SyntaxKind.BinaryExpression]: - | TSESTree.SequenceExpression - | TSESTree.AssignmentExpression - | TSESTree.LogicalExpression - | TSESTree.BinaryExpression - | TSESTree.AssignmentPattern; [ts.SyntaxKind.PropertyAccessExpression]: | TSESTree.MemberExpression | TSESTree.ChainExpression; @@ -251,29 +229,64 @@ export interface TSESTreeToTSNodeTypes { [ts.SyntaxKind.HeritageClause]: 'HeritageClause'; } +export interface NonPatternGuard extends BaseGuard { + [ts.SyntaxKind.BindingElement]: + | TSESTree.AssignmentPattern + | TSESTree.RestElement + | TSESTree.Property; + [ts.SyntaxKind.ArrayLiteralExpression]: TSESTree.ArrayExpression; + [ts.SyntaxKind.BinaryExpression]: + | TSESTree.SequenceExpression + | TSESTree.AssignmentExpression + | TSESTree.LogicalExpression + | TSESTree.BinaryExpression; + [ts.SyntaxKind.SpreadAssignment]: TSESTree.SpreadElement; + [ts.SyntaxKind.SpreadElement]: TSESTree.SpreadElement; + [ts.SyntaxKind.ObjectLiteralExpression]: TSESTree.ObjectExpression; +} + +export interface PatternGuard extends BaseGuard { + [ts.SyntaxKind.BindingElement]: TSESTree.AssignmentPattern; + [ts.SyntaxKind.ArrayLiteralExpression]: TSESTree.ArrayPattern; + [ts.SyntaxKind.BinaryExpression]: + | TSESTree.SequenceExpression + | TSESTree.AssignmentPattern; + [ts.SyntaxKind.SpreadAssignment]: TSESTree.RestElement; + [ts.SyntaxKind.SpreadElement]: TSESTree.RestElement; + [ts.SyntaxKind.ObjectLiteralExpression]: TSESTree.ObjectPattern; +} + // export type TypeTest = Exclude< // TSNodeSupported['kind'], // keyof TSESTreeToTSNodeTypes // >; export type TSESTreeToTSNode2< - T extends TSNodeSupported | undefined + T extends TSNodeSupported | undefined, + P extends boolean > = T extends Exclude - ? TSESTreeToTSNodeTypes[T['kind']] + ? P extends true + ? PatternGuard[T['kind']] + : NonPatternGuard[T['kind']] : T extends ts.ParenthesizedExpression - ? TSESTreeToTSNode2> + ? TSESTreeToTSNode2, P> : null; -export type TSESTreeToTSNodeGuard = T extends TSNodeSupported - ? TSESTreeToTSNode2 +export type TSESTreeToTSNodeGuard< + T, + P extends boolean +> = T extends TSNodeSupported + ? TSESTreeToTSNode2 : T extends ts.Expression - ? TSESTreeToTSNode2 + ? TSESTreeToTSNode2 : T extends ts.Statement - ? TSESTreeToTSNode2 + ? TSESTreeToTSNode2 : T extends ts.TypeNode - ? TSESTreeToTSNode2 + ? TSESTreeToTSNode2 : T extends ts.TypeElement - ? TSESTreeToTSNode2 + ? TSESTreeToTSNode2 : T extends ts.ClassElement - ? TSESTreeToTSNode2 - : null; + ? TSESTreeToTSNode2 + : T extends null | undefined + ? null + : T; diff --git a/packages/typescript-estree/src/ts-estree/ts-nodes.ts b/packages/typescript-estree/src/ts-estree/ts-nodes.ts index 171f5325c6e..c1a50584e99 100644 --- a/packages/typescript-estree/src/ts-estree/ts-nodes.ts +++ b/packages/typescript-estree/src/ts-estree/ts-nodes.ts @@ -11,6 +11,9 @@ declare module 'typescript' { export type TSToken = ts.Token; +/** + * List of nodes that are skipped + */ export type TSNodeSkipped = | ts.OmittedExpression | ts.ComputedPropertyName // we are skipping this node @@ -19,7 +22,8 @@ export type TSNodeSkipped = | ts.NamedImports | ts.NamedExports | ts.TemplateSpan - | ts.ParenthesizedExpression; + | ts.ParenthesizedExpression + | ts.Token; export type TSNodeUnsupported = | ts.PartiallyEmittedExpression @@ -218,7 +222,8 @@ export type TSNodeSupported = Exclude; export type TSNodeExpression = Exclude< Extract, // manual fixes - ts.OmittedExpression + | ts.OmittedExpression // there is advanced handling for this node in type guards + | ts.Token // this node can be generated only in call expression >; export type TSNodeStatement = Extract; export type TSNodeTypeNode = Exclude< From 84ca2152016222c1a66e647d2ba52c1425ab1112 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 16:49:45 +0100 Subject: [PATCH 05/15] fix: add missing intrinsic keyword type --- .../sort-type-union-intersection-members.ts | 1 + ...rt-type-union-intersection-members.test.ts | 3 + .../basics/intrinsic-keyword.src.ts | 4 + packages/types/src/ast-node-types.ts | 1 + packages/types/src/ts-estree.ts | 6 + packages/typescript-estree/src/convert.ts | 3 +- .../src/ts-estree/estree-to-ts-node-types.ts | 1 + .../semantic-diagnostics-enabled.test.ts.snap | 2 + .../basics/intrinsic-keyword.src.ts.shot | 1243 +++++++++++++++++ packages/visitor-keys/src/visitor-keys.ts | 1 + 10 files changed, 1264 insertions(+), 1 deletion(-) create mode 100644 packages/shared-fixtures/fixtures/typescript/basics/intrinsic-keyword.src.ts create mode 100644 packages/typescript-estree/tests/snapshots/typescript/basics/intrinsic-keyword.src.ts.shot diff --git a/packages/eslint-plugin/src/rules/sort-type-union-intersection-members.ts b/packages/eslint-plugin/src/rules/sort-type-union-intersection-members.ts index ff4a4d1ac80..fb83da6f318 100644 --- a/packages/eslint-plugin/src/rules/sort-type-union-intersection-members.ts +++ b/packages/eslint-plugin/src/rules/sort-type-union-intersection-members.ts @@ -49,6 +49,7 @@ function getGroup(node: TSESTree.TypeNode): Group { case AST_NODE_TYPES.TSSymbolKeyword: case AST_NODE_TYPES.TSThisType: case AST_NODE_TYPES.TSUnknownKeyword: + case AST_NODE_TYPES.TSIntrinsicKeyword: return Group.keyword; case AST_NODE_TYPES.TSNullKeyword: diff --git a/packages/eslint-plugin/tests/rules/sort-type-union-intersection-members.test.ts b/packages/eslint-plugin/tests/rules/sort-type-union-intersection-members.test.ts index bcf07490e61..7dda416d6b3 100644 --- a/packages/eslint-plugin/tests/rules/sort-type-union-intersection-members.test.ts +++ b/packages/eslint-plugin/tests/rules/sort-type-union-intersection-members.test.ts @@ -43,10 +43,13 @@ const valid = (operator: '|' | '&'): TSESLint.ValidTestCase[] => [ type T = ${operator} A ${operator} B + ${operator} intrinsic ${operator} number[] ${operator} string[] ${operator} any ${operator} string + ${operator} symbol + ${operator} this ${operator} readonly number[] ${operator} readonly string[] ${operator} 'a' diff --git a/packages/shared-fixtures/fixtures/typescript/basics/intrinsic-keyword.src.ts b/packages/shared-fixtures/fixtures/typescript/basics/intrinsic-keyword.src.ts new file mode 100644 index 00000000000..1467d1975a0 --- /dev/null +++ b/packages/shared-fixtures/fixtures/typescript/basics/intrinsic-keyword.src.ts @@ -0,0 +1,4 @@ +type Uppercase = intrinsic; +type Lowercase = intrinsic; +type Capitalize = intrinsic; +type Uncapitalize = intrinsic; diff --git a/packages/types/src/ast-node-types.ts b/packages/types/src/ast-node-types.ts index 97c630d9472..091e9d3bb94 100644 --- a/packages/types/src/ast-node-types.ts +++ b/packages/types/src/ast-node-types.ts @@ -118,6 +118,7 @@ enum AST_NODE_TYPES { TSInterfaceDeclaration = 'TSInterfaceDeclaration', TSInterfaceHeritage = 'TSInterfaceHeritage', TSIntersectionType = 'TSIntersectionType', + TSIntrinsicKeyword = 'TSIntrinsicKeyword', TSLiteralType = 'TSLiteralType', TSMappedType = 'TSMappedType', TSMethodSignature = 'TSMethodSignature', diff --git a/packages/types/src/ts-estree.ts b/packages/types/src/ts-estree.ts index 4dd89c962be..d2794f66268 100644 --- a/packages/types/src/ts-estree.ts +++ b/packages/types/src/ts-estree.ts @@ -249,6 +249,7 @@ export type Node = | TSInterfaceDeclaration | TSInterfaceHeritage | TSIntersectionType + | TSIntrinsicKeyword | TSLiteralType | TSMappedType | TSMethodSignature @@ -544,6 +545,7 @@ export type TypeNode = | TSInferType | TSInterfaceHeritage | TSIntersectionType + | TSIntrinsicKeyword | TSLiteralType | TSMappedType | TSNamedTupleMember @@ -1469,6 +1471,10 @@ export interface TSIntersectionType extends BaseNode { types: TypeNode[]; } +export interface TSIntrinsicKeyword extends BaseNode { + type: AST_NODE_TYPES.TSIntrinsicKeyword; +} + export interface TSLiteralType extends BaseNode { type: AST_NODE_TYPES.TSLiteralType; literal: LiteralExpression | UnaryExpression | UpdateExpression; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index f8819a33c9e..af197d963ce 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -2211,7 +2211,8 @@ export class Converter { case SyntaxKind.SymbolKeyword: case SyntaxKind.UnknownKeyword: case SyntaxKind.VoidKeyword: - case SyntaxKind.UndefinedKeyword: { + case SyntaxKind.UndefinedKeyword: + case SyntaxKind.IntrinsicKeyword: { return this.createNode(node, { type: AST_NODE_TYPES[`TS${SyntaxKind[node.kind]}` as AST_NODE_TYPES], }); 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 62053920280..2eebfc93b12 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 @@ -254,6 +254,7 @@ export interface EstreeToTsNodeTypes { [AST_NODE_TYPES.TSAnyKeyword]: ts.KeywordTypeNode; [AST_NODE_TYPES.TSBigIntKeyword]: ts.KeywordTypeNode; [AST_NODE_TYPES.TSBooleanKeyword]: ts.KeywordTypeNode; + [AST_NODE_TYPES.TSIntrinsicKeyword]: ts.KeywordTypeNode; [AST_NODE_TYPES.TSNeverKeyword]: ts.KeywordTypeNode; [AST_NODE_TYPES.TSNumberKeyword]: ts.KeywordTypeNode; [AST_NODE_TYPES.TSObjectKeyword]: ts.KeywordTypeNode; diff --git a/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.test.ts.snap b/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.test.ts.snap index 63bba828ae0..2aa60bf249e 100644 --- a/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.test.ts.snap +++ b/packages/typescript-estree/tests/lib/__snapshots__/semantic-diagnostics-enabled.test.ts.snap @@ -1993,6 +1993,8 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" e exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/interface-without-type-annotation.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; +exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/intrinsic-keyword.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; + exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/keyof-operator.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; exports[`Parse all fixtures with "errorOnTypeScriptSyntacticAndSemanticIssues" enabled fixtures/typescript/basics/keyword-variables.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`; diff --git a/packages/typescript-estree/tests/snapshots/typescript/basics/intrinsic-keyword.src.ts.shot b/packages/typescript-estree/tests/snapshots/typescript/basics/intrinsic-keyword.src.ts.shot new file mode 100644 index 00000000000..22d41df5f1a --- /dev/null +++ b/packages/typescript-estree/tests/snapshots/typescript/basics/intrinsic-keyword.src.ts.shot @@ -0,0 +1,1243 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`typescript basics intrinsic-keyword.src 1`] = ` +Object { + "body": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 14, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "name": "Uppercase", + "range": Array [ + 5, + 14, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 45, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 45, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 44, + "line": 1, + }, + "start": Object { + "column": 35, + "line": 1, + }, + }, + "range": Array [ + 35, + 44, + ], + "type": "TSIntrinsicKeyword", + }, + "typeParameters": Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "params": Array [ + Object { + "constraint": Object { + "loc": Object { + "end": Object { + "column": 31, + "line": 1, + }, + "start": Object { + "column": 25, + "line": 1, + }, + }, + "range": Array [ + 25, + 31, + ], + "type": "TSStringKeyword", + }, + "default": undefined, + "loc": Object { + "end": Object { + "column": 31, + "line": 1, + }, + "start": Object { + "column": 15, + "line": 1, + }, + }, + "name": Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 1, + }, + "start": Object { + "column": 15, + "line": 1, + }, + }, + "name": "S", + "range": Array [ + 15, + 16, + ], + "type": "Identifier", + }, + "range": Array [ + 15, + 31, + ], + "type": "TSTypeParameter", + }, + ], + "range": Array [ + 14, + 32, + ], + "type": "TSTypeParameterDeclaration", + }, + }, + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 14, + "line": 2, + }, + "start": Object { + "column": 5, + "line": 2, + }, + }, + "name": "Lowercase", + "range": Array [ + 51, + 60, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 45, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 2, + }, + }, + "range": Array [ + 46, + 91, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 44, + "line": 2, + }, + "start": Object { + "column": 35, + "line": 2, + }, + }, + "range": Array [ + 81, + 90, + ], + "type": "TSIntrinsicKeyword", + }, + "typeParameters": Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 2, + }, + "start": Object { + "column": 14, + "line": 2, + }, + }, + "params": Array [ + Object { + "constraint": Object { + "loc": Object { + "end": Object { + "column": 31, + "line": 2, + }, + "start": Object { + "column": 25, + "line": 2, + }, + }, + "range": Array [ + 71, + 77, + ], + "type": "TSStringKeyword", + }, + "default": undefined, + "loc": Object { + "end": Object { + "column": 31, + "line": 2, + }, + "start": Object { + "column": 15, + "line": 2, + }, + }, + "name": Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 2, + }, + "start": Object { + "column": 15, + "line": 2, + }, + }, + "name": "S", + "range": Array [ + 61, + 62, + ], + "type": "Identifier", + }, + "range": Array [ + 61, + 77, + ], + "type": "TSTypeParameter", + }, + ], + "range": Array [ + 60, + 78, + ], + "type": "TSTypeParameterDeclaration", + }, + }, + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 3, + }, + "start": Object { + "column": 5, + "line": 3, + }, + }, + "name": "Capitalize", + "range": Array [ + 97, + 107, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 46, + "line": 3, + }, + "start": Object { + "column": 0, + "line": 3, + }, + }, + "range": Array [ + 92, + 138, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 45, + "line": 3, + }, + "start": Object { + "column": 36, + "line": 3, + }, + }, + "range": Array [ + 128, + 137, + ], + "type": "TSIntrinsicKeyword", + }, + "typeParameters": Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 3, + }, + "start": Object { + "column": 15, + "line": 3, + }, + }, + "params": Array [ + Object { + "constraint": Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 3, + }, + "start": Object { + "column": 26, + "line": 3, + }, + }, + "range": Array [ + 118, + 124, + ], + "type": "TSStringKeyword", + }, + "default": undefined, + "loc": Object { + "end": Object { + "column": 32, + "line": 3, + }, + "start": Object { + "column": 16, + "line": 3, + }, + }, + "name": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 3, + }, + "start": Object { + "column": 16, + "line": 3, + }, + }, + "name": "S", + "range": Array [ + 108, + 109, + ], + "type": "Identifier", + }, + "range": Array [ + 108, + 124, + ], + "type": "TSTypeParameter", + }, + ], + "range": Array [ + 107, + 125, + ], + "type": "TSTypeParameterDeclaration", + }, + }, + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 4, + }, + "start": Object { + "column": 5, + "line": 4, + }, + }, + "name": "Uncapitalize", + "range": Array [ + 144, + 156, + ], + "type": "Identifier", + }, + "loc": Object { + "end": Object { + "column": 48, + "line": 4, + }, + "start": Object { + "column": 0, + "line": 4, + }, + }, + "range": Array [ + 139, + 187, + ], + "type": "TSTypeAliasDeclaration", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 47, + "line": 4, + }, + "start": Object { + "column": 38, + "line": 4, + }, + }, + "range": Array [ + 177, + 186, + ], + "type": "TSIntrinsicKeyword", + }, + "typeParameters": Object { + "loc": Object { + "end": Object { + "column": 35, + "line": 4, + }, + "start": Object { + "column": 17, + "line": 4, + }, + }, + "params": Array [ + Object { + "constraint": Object { + "loc": Object { + "end": Object { + "column": 34, + "line": 4, + }, + "start": Object { + "column": 28, + "line": 4, + }, + }, + "range": Array [ + 167, + 173, + ], + "type": "TSStringKeyword", + }, + "default": undefined, + "loc": Object { + "end": Object { + "column": 34, + "line": 4, + }, + "start": Object { + "column": 18, + "line": 4, + }, + }, + "name": Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 4, + }, + "start": Object { + "column": 18, + "line": 4, + }, + }, + "name": "S", + "range": Array [ + 157, + 158, + ], + "type": "Identifier", + }, + "range": Array [ + 157, + 173, + ], + "type": "TSTypeParameter", + }, + ], + "range": Array [ + 156, + 174, + ], + "type": "TSTypeParameterDeclaration", + }, + }, + ], + "comments": Array [], + "loc": Object { + "end": Object { + "column": 0, + "line": 5, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 188, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 4, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 14, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 14, + ], + "type": "Identifier", + "value": "Uppercase", + }, + Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 1, + }, + "start": Object { + "column": 14, + "line": 1, + }, + }, + "range": Array [ + 14, + 15, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 1, + }, + "start": Object { + "column": 15, + "line": 1, + }, + }, + "range": Array [ + 15, + 16, + ], + "type": "Identifier", + "value": "S", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 1, + }, + "start": Object { + "column": 17, + "line": 1, + }, + }, + "range": Array [ + 17, + 24, + ], + "type": "Keyword", + "value": "extends", + }, + Object { + "loc": Object { + "end": Object { + "column": 31, + "line": 1, + }, + "start": Object { + "column": 25, + "line": 1, + }, + }, + "range": Array [ + 25, + 31, + ], + "type": "Identifier", + "value": "string", + }, + Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 1, + }, + "start": Object { + "column": 31, + "line": 1, + }, + }, + "range": Array [ + 31, + 32, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 34, + "line": 1, + }, + "start": Object { + "column": 33, + "line": 1, + }, + }, + "range": Array [ + 33, + 34, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 44, + "line": 1, + }, + "start": Object { + "column": 35, + "line": 1, + }, + }, + "range": Array [ + 35, + 44, + ], + "type": "Identifier", + "value": "intrinsic", + }, + Object { + "loc": Object { + "end": Object { + "column": 45, + "line": 1, + }, + "start": Object { + "column": 44, + "line": 1, + }, + }, + "range": Array [ + 44, + 45, + ], + "type": "Punctuator", + "value": ";", + }, + Object { + "loc": Object { + "end": Object { + "column": 4, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 2, + }, + }, + "range": Array [ + 46, + 50, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 14, + "line": 2, + }, + "start": Object { + "column": 5, + "line": 2, + }, + }, + "range": Array [ + 51, + 60, + ], + "type": "Identifier", + "value": "Lowercase", + }, + Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 2, + }, + "start": Object { + "column": 14, + "line": 2, + }, + }, + "range": Array [ + 60, + 61, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 2, + }, + "start": Object { + "column": 15, + "line": 2, + }, + }, + "range": Array [ + 61, + 62, + ], + "type": "Identifier", + "value": "S", + }, + Object { + "loc": Object { + "end": Object { + "column": 24, + "line": 2, + }, + "start": Object { + "column": 17, + "line": 2, + }, + }, + "range": Array [ + 63, + 70, + ], + "type": "Keyword", + "value": "extends", + }, + Object { + "loc": Object { + "end": Object { + "column": 31, + "line": 2, + }, + "start": Object { + "column": 25, + "line": 2, + }, + }, + "range": Array [ + 71, + 77, + ], + "type": "Identifier", + "value": "string", + }, + Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 2, + }, + "start": Object { + "column": 31, + "line": 2, + }, + }, + "range": Array [ + 77, + 78, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 34, + "line": 2, + }, + "start": Object { + "column": 33, + "line": 2, + }, + }, + "range": Array [ + 79, + 80, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 44, + "line": 2, + }, + "start": Object { + "column": 35, + "line": 2, + }, + }, + "range": Array [ + 81, + 90, + ], + "type": "Identifier", + "value": "intrinsic", + }, + Object { + "loc": Object { + "end": Object { + "column": 45, + "line": 2, + }, + "start": Object { + "column": 44, + "line": 2, + }, + }, + "range": Array [ + 90, + 91, + ], + "type": "Punctuator", + "value": ";", + }, + Object { + "loc": Object { + "end": Object { + "column": 4, + "line": 3, + }, + "start": Object { + "column": 0, + "line": 3, + }, + }, + "range": Array [ + 92, + 96, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 15, + "line": 3, + }, + "start": Object { + "column": 5, + "line": 3, + }, + }, + "range": Array [ + 97, + 107, + ], + "type": "Identifier", + "value": "Capitalize", + }, + Object { + "loc": Object { + "end": Object { + "column": 16, + "line": 3, + }, + "start": Object { + "column": 15, + "line": 3, + }, + }, + "range": Array [ + 107, + 108, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 3, + }, + "start": Object { + "column": 16, + "line": 3, + }, + }, + "range": Array [ + 108, + 109, + ], + "type": "Identifier", + "value": "S", + }, + Object { + "loc": Object { + "end": Object { + "column": 25, + "line": 3, + }, + "start": Object { + "column": 18, + "line": 3, + }, + }, + "range": Array [ + 110, + 117, + ], + "type": "Keyword", + "value": "extends", + }, + Object { + "loc": Object { + "end": Object { + "column": 32, + "line": 3, + }, + "start": Object { + "column": 26, + "line": 3, + }, + }, + "range": Array [ + 118, + 124, + ], + "type": "Identifier", + "value": "string", + }, + Object { + "loc": Object { + "end": Object { + "column": 33, + "line": 3, + }, + "start": Object { + "column": 32, + "line": 3, + }, + }, + "range": Array [ + 124, + 125, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 35, + "line": 3, + }, + "start": Object { + "column": 34, + "line": 3, + }, + }, + "range": Array [ + 126, + 127, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 45, + "line": 3, + }, + "start": Object { + "column": 36, + "line": 3, + }, + }, + "range": Array [ + 128, + 137, + ], + "type": "Identifier", + "value": "intrinsic", + }, + Object { + "loc": Object { + "end": Object { + "column": 46, + "line": 3, + }, + "start": Object { + "column": 45, + "line": 3, + }, + }, + "range": Array [ + 137, + 138, + ], + "type": "Punctuator", + "value": ";", + }, + Object { + "loc": Object { + "end": Object { + "column": 4, + "line": 4, + }, + "start": Object { + "column": 0, + "line": 4, + }, + }, + "range": Array [ + 139, + 143, + ], + "type": "Identifier", + "value": "type", + }, + Object { + "loc": Object { + "end": Object { + "column": 17, + "line": 4, + }, + "start": Object { + "column": 5, + "line": 4, + }, + }, + "range": Array [ + 144, + 156, + ], + "type": "Identifier", + "value": "Uncapitalize", + }, + Object { + "loc": Object { + "end": Object { + "column": 18, + "line": 4, + }, + "start": Object { + "column": 17, + "line": 4, + }, + }, + "range": Array [ + 156, + 157, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 19, + "line": 4, + }, + "start": Object { + "column": 18, + "line": 4, + }, + }, + "range": Array [ + 157, + 158, + ], + "type": "Identifier", + "value": "S", + }, + Object { + "loc": Object { + "end": Object { + "column": 27, + "line": 4, + }, + "start": Object { + "column": 20, + "line": 4, + }, + }, + "range": Array [ + 159, + 166, + ], + "type": "Keyword", + "value": "extends", + }, + Object { + "loc": Object { + "end": Object { + "column": 34, + "line": 4, + }, + "start": Object { + "column": 28, + "line": 4, + }, + }, + "range": Array [ + 167, + 173, + ], + "type": "Identifier", + "value": "string", + }, + Object { + "loc": Object { + "end": Object { + "column": 35, + "line": 4, + }, + "start": Object { + "column": 34, + "line": 4, + }, + }, + "range": Array [ + 173, + 174, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 37, + "line": 4, + }, + "start": Object { + "column": 36, + "line": 4, + }, + }, + "range": Array [ + 175, + 176, + ], + "type": "Punctuator", + "value": "=", + }, + Object { + "loc": Object { + "end": Object { + "column": 47, + "line": 4, + }, + "start": Object { + "column": 38, + "line": 4, + }, + }, + "range": Array [ + 177, + 186, + ], + "type": "Identifier", + "value": "intrinsic", + }, + Object { + "loc": Object { + "end": Object { + "column": 48, + "line": 4, + }, + "start": Object { + "column": 47, + "line": 4, + }, + }, + "range": Array [ + 186, + 187, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; diff --git a/packages/visitor-keys/src/visitor-keys.ts b/packages/visitor-keys/src/visitor-keys.ts index 68c6b806bcc..1f2363e948e 100644 --- a/packages/visitor-keys/src/visitor-keys.ts +++ b/packages/visitor-keys/src/visitor-keys.ts @@ -99,6 +99,7 @@ const additionalKeys: AdditionalKeys = { TSInterfaceDeclaration: ['id', 'typeParameters', 'extends', 'body'], TSInterfaceHeritage: ['expression', 'typeParameters'], TSIntersectionType: ['types'], + TSIntrinsicKeyword: [], TSLiteralType: ['literal'], TSMappedType: ['nameType', 'typeParameter', 'typeAnnotation'], TSMethodSignature: ['typeParameters', 'key', 'params', 'returnType'], From efe38d208e098f6d8bba5956388c1c269eef570b Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 18:40:34 +0100 Subject: [PATCH 06/15] fix: correct issues with guards --- .../typescript-estree/src/convert-guards.ts | 4 +++ packages/typescript-estree/src/convert.ts | 30 +++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index b78a5f3f031..8e0877e8d08 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -290,3 +290,7 @@ export type TSESTreeToTSNodeGuard< : T extends null | undefined ? null : T; + +export type TypeTest = Exclude; + +export type TypeTest2 = Exclude; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index ebbf2a3004b..25f5124eb77 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -101,12 +101,12 @@ export class Converter { * @param allowPattern flag to determine if patterns are allowed * @returns the converted ESTree node */ - private converter( + private converter( node: T, parent?: ts.Node, inTypeMode?: boolean, - allowPattern?: boolean, - ): TSESTreeToTSNodeGuard { + allowPattern?: P, + ): TSESTreeToTSNodeGuard { /** * Exit early for null and undefined */ @@ -123,7 +123,7 @@ export class Converter { this.allowPattern = allowPattern; } - const result = this.convertNode(node, (parent ?? node.parent) as TSNode); + const result = this.convertNode

(node, (parent ?? node.parent) as TSNode); this.registerTSNodeInNodeMap(node, result); @@ -218,8 +218,8 @@ export class Converter { private convertPattern( child: T, parent?: ts.Node, - ): TSESTreeToTSNodeGuard { - return this.converter(child, parent, this.inTypeMode, true); + ): TSESTreeToTSNodeGuard { + return this.converter(child, parent, this.inTypeMode, true); } /** @@ -231,8 +231,8 @@ export class Converter { private convertChild( child: T, parent?: ts.Node, - ): TSESTreeToTSNodeGuard { - return this.converter(child, parent, this.inTypeMode, false); + ): TSESTreeToTSNodeGuard { + return this.converter(child, parent, this.inTypeMode, false); } /** @@ -244,8 +244,8 @@ export class Converter { private convertType( child: T, parent?: ts.Node, - ): TSESTreeToTSNodeGuard { - return this.converter(child, parent, true, false); + ): TSESTreeToTSNodeGuard { + return this.converter(child, parent, true, false); } private createNode( @@ -323,7 +323,7 @@ export class Converter { return ( nodes - .map(statement => { + .map(statement => { const child = this.convertChild(statement); if (allowDirectives) { if ( @@ -658,12 +658,12 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - private convertNode( - node: TSNodeSupported, + private convertNode

( + node: TSNode, parent: TSNode, - ): TSESTreeToTSNode2 { + ): TSESTreeToTSNodeGuard { switch (node.kind) { - case SyntaxKind.SourceFile: { + case ts.SyntaxKind.SourceFile: { return this.createNode(node, { type: AST_NODE_TYPES.Program, body: this.convertBodyExpressions(node.statements, node), From 96f5e431df39a714fef455c850eadec29cb84f99 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 19:33:43 +0100 Subject: [PATCH 07/15] refactor: simplify type resolution --- .../typescript-estree/src/convert-guards.ts | 77 ++++++++++--------- packages/typescript-estree/src/convert.ts | 6 +- .../src/ts-estree/estree-to-ts-node-types.ts | 4 +- .../src/ts-estree/ts-nodes.ts | 47 ++++------- 4 files changed, 57 insertions(+), 77 deletions(-) diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index 8e0877e8d08..51fc891f651 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -1,13 +1,6 @@ import { TSESTree } from '@typescript-eslint/types'; import * as ts from 'typescript'; -import { - TSNodeClassElement, - TSNodeExpression, - TSNodeSupported, - TSNodeStatement, - TSNodeTypeElement, - TSNodeTypeNode, -} from './ts-estree/ts-nodes'; +import { TSNode } from './ts-estree/ts-nodes'; /** * this is not correct yet, additional refining is required @@ -212,21 +205,7 @@ export interface BaseGuard { [ts.SyntaxKind.TemplateLiteralType]: TSESTree.TSTemplateLiteralType; // TODO: just for testing - delete/change me - [ts.SyntaxKind.ExportKeyword]: 'ExportKeyword'; - [ts.SyntaxKind.ImportKeyword]: 'ImportKeyword'; - [ts.SyntaxKind.PrivateKeyword]: 'PrivateKeyword'; - [ts.SyntaxKind.StaticKeyword]: 'StaticKeyword'; - [ts.SyntaxKind.ProtectedKeyword]: 'ProtectedKeyword'; - [ts.SyntaxKind.AsyncKeyword]: 'AsyncKeyword'; - [ts.SyntaxKind.PublicKeyword]: 'PublicKeyword'; - [ts.SyntaxKind.DeclareKeyword]: 'DeclareKeyword'; [ts.SyntaxKind.IntrinsicKeyword]: 'IntrinsicKeyword'; - [ts.SyntaxKind.ReadonlyKeyword]: 'ReadonlyKeyword'; - [ts.SyntaxKind.TemplateSpan]: 'TemplateSpan'; - [ts.SyntaxKind.CaseBlock]: 'CaseBlock'; - [ts.SyntaxKind.NamedImports]: 'NamedImports'; - [ts.SyntaxKind.NamedExports]: 'NamedExports'; - [ts.SyntaxKind.HeritageClause]: 'HeritageClause'; } export interface NonPatternGuard extends BaseGuard { @@ -256,24 +235,50 @@ export interface PatternGuard extends BaseGuard { [ts.SyntaxKind.ObjectLiteralExpression]: TSESTree.ObjectPattern; } -// export type TypeTest = Exclude< -// TSNodeSupported['kind'], -// keyof TSESTreeToTSNodeTypes -// >; +export type TSNodePattern = TSNode & { + kind: keyof PatternGuard | keyof NonPatternGuard; +}; +export type TSNodeBaseGuard = TSNode & { kind: keyof BaseGuard }; -export type TSESTreeToTSNode2< - T extends TSNodeSupported | undefined, - P extends boolean -> = T extends Exclude +export type TSNodeSupported = + | TSNodePattern + | TSNodeBaseGuard + | ts.ParenthesizedExpression; + +export type TSNodeExpression = Exclude< + Extract, + // manual fixes + | ts.OmittedExpression // there is advanced handling for this node in type guards + | ts.Token // this node can be generated only in call expression +>; +export type TSNodeStatement = Extract; +export type TSNodeTypeNode = Exclude< + Extract, + // manual fixes + ts.ExpressionWithTypeArguments +>; +export type TSNodeTypeElement = Extract; +export type TSNodeClassElement = Extract; + +export type TSNodeConvertable = + | TSNode + | ts.Expression + | ts.Statement + | ts.TypeNode + | ts.TypeElement + | ts.ClassElement + | undefined; + +export type TSESTreeToTSNode2 = T extends TSNodeBaseGuard + ? BaseGuard[T['kind']] + : T extends TSNodePattern ? P extends true ? PatternGuard[T['kind']] : NonPatternGuard[T['kind']] - : T extends ts.ParenthesizedExpression - ? TSESTreeToTSNode2, P> - : null; + : TSESTreeToTSNode2; export type TSESTreeToTSNodeGuard< - T, + T extends TSNodeConvertable, P extends boolean > = T extends TSNodeSupported ? TSESTreeToTSNode2 @@ -287,9 +292,7 @@ export type TSESTreeToTSNodeGuard< ? TSESTreeToTSNode2 : T extends ts.ClassElement ? TSESTreeToTSNode2 - : T extends null | undefined - ? null - : T; + : null; export type TypeTest = Exclude; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 25f5124eb77..93015012107 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -29,10 +29,8 @@ import { TSESTree, TSESTreeToTSNode, TSNode, - TSNodeConvertable, - TSNodeSupported, } from './ts-estree'; -import { TSESTreeToTSNode2, TSESTreeToTSNodeGuard } from './convert-guards'; +import { TSESTreeToTSNodeGuard, TSNodeConvertable } from './convert-guards'; import { typescriptVersionIsAtLeast } from './version-check'; @@ -318,7 +316,7 @@ export class Converter { private convertBodyExpressions( nodes: ts.NodeArray, parent: ts.SourceFile | ts.Block | ts.ModuleBlock, - ): TSESTree.Statement[] { + ): TSESTree.ProgramStatement[] { let allowDirectives = canContainDirective(parent); return ( 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 896b2212968..48cdb3c9bc7 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 @@ -1,6 +1,6 @@ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/types'; import * as ts from 'typescript'; -import { TSNode, TSNodeUnsupported, TSNodeSkipped } from './ts-nodes'; +import { TSNode, TSNodeUnused, TSNodeSkipped } from './ts-nodes'; export interface EstreeToTsNodeTypes { [AST_NODE_TYPES.ArrayExpression]: ts.ArrayLiteralExpression; @@ -279,7 +279,7 @@ export interface EstreeToTsNodeTypes { * This mapping is based on the internal logic of the parser. */ export type TSESTreeToTSNode = Extract< - | Exclude + | Exclude | ts.Token, // if this errors, it means that one of the AST_NODE_TYPES is not defined in the above interface EstreeToTsNodeTypes[T['type']] diff --git a/packages/typescript-estree/src/ts-estree/ts-nodes.ts b/packages/typescript-estree/src/ts-estree/ts-nodes.ts index c1a50584e99..8fa8a8f3577 100644 --- a/packages/typescript-estree/src/ts-estree/ts-nodes.ts +++ b/packages/typescript-estree/src/ts-estree/ts-nodes.ts @@ -11,21 +11,24 @@ declare module 'typescript' { export type TSToken = ts.Token; -/** - * List of nodes that are skipped - */ +// TODO: drop after TSESTreeToTSNode refactor export type TSNodeSkipped = + // List of nodes that are skipped | ts.OmittedExpression - | ts.ComputedPropertyName // we are skipping this node - | ts.CaseBlock + | ts.ComputedPropertyName + | ts.ParenthesizedExpression + | ts.Token; + +// TODO: drop after TSESTreeToTSNode refactor +export type TSNodeUnused = + // Nodes that are skipped when generating code | ts.HeritageClause + | ts.CaseBlock | ts.NamedImports - | ts.NamedExports | ts.TemplateSpan - | ts.ParenthesizedExpression - | ts.Token; + | ts.NamedExports -export type TSNodeUnsupported = + // Those nodes can't be generated by ast | ts.PartiallyEmittedExpression | ts.SyntheticExpression | ts.NotEmittedStatement @@ -73,7 +76,7 @@ export type TSNodeUnsupported = // TODO: replace with code that retrieves all nodes that have kind // export type TSNode2 = Extract export type TSNode = - | TSNodeUnsupported + | TSNodeUnused | TSNodeSkipped | ts.Modifier | ts.Identifier @@ -218,27 +221,3 @@ export type TSNode = | ts.SourceFile | ts.TemplateLiteralTypeNode; -export type TSNodeSupported = Exclude; -export type TSNodeExpression = Exclude< - Extract, - // manual fixes - | ts.OmittedExpression // there is advanced handling for this node in type guards - | ts.Token // this node can be generated only in call expression ->; -export type TSNodeStatement = Extract; -export type TSNodeTypeNode = Exclude< - Extract, - // manual fixes - ts.ExpressionWithTypeArguments ->; -export type TSNodeTypeElement = Extract; -export type TSNodeClassElement = Extract; - -export type TSNodeConvertable = - | TSNode - | ts.Expression - | ts.Statement - | ts.TypeNode - | ts.TypeElement - | ts.ClassElement - | undefined; From 0351d0b84f89644bc7d56a438f0699349ebdf1e6 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 19:43:13 +0100 Subject: [PATCH 08/15] fix: register TSIntrinsicKeyword --- packages/typescript-estree/src/convert-guards.ts | 4 +--- packages/typescript-estree/src/convert.ts | 4 ++-- packages/typescript-estree/src/ts-estree/ts-nodes.ts | 1 - 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index 51fc891f651..6504252d5c1 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -203,9 +203,7 @@ export interface BaseGuard { [ts.SyntaxKind.OptionalType]: TSESTree.TSOptionalType; [ts.SyntaxKind.RestType]: TSESTree.TSRestType; [ts.SyntaxKind.TemplateLiteralType]: TSESTree.TSTemplateLiteralType; - - // TODO: just for testing - delete/change me - [ts.SyntaxKind.IntrinsicKeyword]: 'IntrinsicKeyword'; + [ts.SyntaxKind.IntrinsicKeyword]: TSESTree.TSIntrinsicKeyword; } export interface NonPatternGuard extends BaseGuard { diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 0de4fa17f87..d6f46d07e52 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -2127,9 +2127,9 @@ export class Converter { } case SyntaxKind.JsxAttribute: { - const attributeName = this.convertChild( + const attributeName = (this.convertChild( node.name, - ) as TSESTree.JSXIdentifier; + ) as unknown) as TSESTree.JSXIdentifier; attributeName.type = AST_NODE_TYPES.JSXIdentifier; return this.createNode(node, { diff --git a/packages/typescript-estree/src/ts-estree/ts-nodes.ts b/packages/typescript-estree/src/ts-estree/ts-nodes.ts index 8fa8a8f3577..32887dc46b2 100644 --- a/packages/typescript-estree/src/ts-estree/ts-nodes.ts +++ b/packages/typescript-estree/src/ts-estree/ts-nodes.ts @@ -220,4 +220,3 @@ export type TSNode = | ts.ExportAssignment | ts.SourceFile | ts.TemplateLiteralTypeNode; - From 0671330fe984bb0b2835f383667ccbd3e22b1f72 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 21:16:21 +0100 Subject: [PATCH 09/15] fix; merge ProgramStatement with Statement and update types --- packages/types/src/ts-estree.ts | 32 +++---- .../typescript-estree/src/convert-guards.ts | 86 ++++++++++++++----- packages/typescript-estree/src/convert.ts | 4 +- 3 files changed, 81 insertions(+), 41 deletions(-) diff --git a/packages/types/src/ts-estree.ts b/packages/types/src/ts-estree.ts index 5ee964f97c8..4bf7c867c78 100644 --- a/packages/types/src/ts-estree.ts +++ b/packages/types/src/ts-estree.ts @@ -465,20 +465,7 @@ export type PrimaryExpression = | TemplateLiteral | ThisExpression | TSNullKeyword; -export type ProgramStatement = - | ClassDeclaration - | ExportAllDeclaration - | ExportDefaultDeclaration - | ExportNamedDeclaration - | ImportDeclaration - | Statement - | TSDeclareFunction - | TSEnumDeclaration - | TSExportAssignment - | TSImportEqualsDeclaration - | TSInterfaceDeclaration - | TSNamespaceExportDeclaration - | TSTypeAliasDeclaration; +export type ProgramStatement = Statement; export type Property = PropertyComputedName | PropertyNonComputedName; export type PropertyName = PropertyNameComputed | PropertyNameNonComputed; export type PropertyNameComputed = Expression; @@ -504,7 +491,20 @@ export type Statement = | ThrowStatement | TryStatement | VariableDeclaration - | WithStatement; + | WithStatement + // old: ProgramStatement + | ClassDeclaration + | ExportAllDeclaration + | ExportDefaultDeclaration + | ExportNamedDeclaration + | ImportDeclaration + | TSDeclareFunction + | TSEnumDeclaration + | TSExportAssignment + | TSImportEqualsDeclaration + | TSInterfaceDeclaration + | TSNamespaceExportDeclaration + | TSTypeAliasDeclaration; export type TSAbstractClassProperty = | TSAbstractClassPropertyComputedName | TSAbstractClassPropertyNonComputedName; @@ -1271,7 +1271,7 @@ export interface TryStatement extends BaseNode { type: AST_NODE_TYPES.TryStatement; block: BlockStatement; handler: CatchClause | null; - finalizer: BlockStatement; + finalizer: BlockStatement | null; } export interface TSAbstractClassPropertyComputedName diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index 6504252d5c1..6ca45406a12 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -204,13 +204,13 @@ export interface BaseGuard { [ts.SyntaxKind.RestType]: TSESTree.TSRestType; [ts.SyntaxKind.TemplateLiteralType]: TSESTree.TSTemplateLiteralType; [ts.SyntaxKind.IntrinsicKeyword]: TSESTree.TSIntrinsicKeyword; -} - -export interface NonPatternGuard extends BaseGuard { [ts.SyntaxKind.BindingElement]: - | TSESTree.AssignmentPattern + | TSESTree.AssignmentPattern // This is possible only when parent is ArrayPattern... | TSESTree.RestElement | TSESTree.Property; +} + +export interface NonPatternGuard extends BaseGuard { [ts.SyntaxKind.ArrayLiteralExpression]: TSESTree.ArrayExpression; [ts.SyntaxKind.BinaryExpression]: | TSESTree.SequenceExpression @@ -223,7 +223,6 @@ export interface NonPatternGuard extends BaseGuard { } export interface PatternGuard extends BaseGuard { - [ts.SyntaxKind.BindingElement]: TSESTree.AssignmentPattern; [ts.SyntaxKind.ArrayLiteralExpression]: TSESTree.ArrayPattern; [ts.SyntaxKind.BinaryExpression]: | TSESTree.SequenceExpression @@ -233,23 +232,47 @@ export interface PatternGuard extends BaseGuard { [ts.SyntaxKind.ObjectLiteralExpression]: TSESTree.ObjectPattern; } +// This is really slow for some reason export type TSNodePattern = TSNode & { kind: keyof PatternGuard | keyof NonPatternGuard; }; +// This is really slow for some reason export type TSNodeBaseGuard = TSNode & { kind: keyof BaseGuard }; -export type TSNodeSupported = - | TSNodePattern - | TSNodeBaseGuard - | ts.ParenthesizedExpression; +export type TSNodeSupported = TSNodePattern | TSNodeBaseGuard; +// Expressions - this is needed for optimization export type TSNodeExpression = Exclude< Extract, // manual fixes | ts.OmittedExpression // there is advanced handling for this node in type guards | ts.Token // this node can be generated only in call expression >; +export type TSNodeObjectLiteralElementLike = Extract< + TSNodeExpression, + ts.ObjectLiteralElementLike +>; +export type TSNodeLeftHandSideExpression = Extract< + TSNodeExpression, + ts.LeftHandSideExpression +>; +export type TSNodeUnaryExpression = Extract< + TSNodeExpression, + ts.UnaryExpression +>; +export type TSNodeLiteralExpression = Extract< + TSNodeExpression, + ts.LiteralExpression +>; +export type TSNodeUpdateExpression = Extract< + TSNodeExpression, + ts.UpdateExpression +>; + +// Statements - this is needed for optimization export type TSNodeStatement = Extract; + +// Declarations - this is needed for optimization export type TSNodeTypeNode = Exclude< Extract, // manual fixes @@ -258,6 +281,8 @@ export type TSNodeTypeNode = Exclude< export type TSNodeTypeElement = Extract; export type TSNodeClassElement = Extract; +// ---------------- + export type TSNodeConvertable = | TSNode | ts.Expression @@ -267,31 +292,46 @@ export type TSNodeConvertable = | ts.ClassElement | undefined; -export type TSESTreeToTSNode2 = T extends TSNodeBaseGuard +export type TSESTreeToTSNode2< + T extends TSNodePattern, + P extends boolean +> = T extends TSNodeBaseGuard ? BaseGuard[T['kind']] - : T extends TSNodePattern - ? P extends true - ? PatternGuard[T['kind']] - : NonPatternGuard[T['kind']] - : TSESTreeToTSNode2; + : P extends true + ? PatternGuard[T['kind']] + : NonPatternGuard[T['kind']]; export type TSESTreeToTSNodeGuard< T extends TSNodeConvertable, P extends boolean -> = T extends TSNodeSupported +> = T extends ts.ParenthesizedExpression + ? TSESTreeToTSNode2 + : T extends TSNodeSupported ? TSESTreeToTSNode2 - : T extends ts.Expression - ? TSESTreeToTSNode2 - : T extends ts.Statement - ? TSESTreeToTSNode2 + : T extends ts.UnaryExpression + ? TSESTreeToTSNode2 + : T extends ts.LiteralExpression + ? TSESTreeToTSNode2 + : T extends ts.UpdateExpression + ? TSESTreeToTSNode2 + : T extends ts.LeftHandSideExpression + ? TSESTreeToTSNode2 : T extends ts.TypeNode ? TSESTreeToTSNode2 : T extends ts.TypeElement ? TSESTreeToTSNode2 : T extends ts.ClassElement ? TSESTreeToTSNode2 - : null; + : T extends ts.Statement + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ? any // TSESTreeToTSNode2 + : T extends ts.Expression + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ? any // TSESTreeToTSNode2 + : null; // TODO + +// export type TypeTest = Exclude; -export type TypeTest = Exclude; +// export type TypeTest2 = Exclude; -export type TypeTest2 = Exclude; +// export type TypeTest3 = TSESTreeToTSNode2; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index d6f46d07e52..8cf00b82d22 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -316,7 +316,7 @@ export class Converter { private convertBodyExpressions( nodes: ts.NodeArray, parent: ts.SourceFile | ts.Block | ts.ModuleBlock, - ): TSESTree.ProgramStatement[] { + ): TSESTree.Statements[] { let allowDirectives = canContainDirective(parent); return ( @@ -661,7 +661,7 @@ export class Converter { parent: TSNode, ): TSESTreeToTSNodeGuard { switch (node.kind) { - case ts.SyntaxKind.SourceFile: { + case SyntaxKind.SourceFile: { return this.createNode(node, { type: AST_NODE_TYPES.Program, body: this.convertBodyExpressions(node.statements, node), From bc49404dcf191b7c28b230743f2631f019476090 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 21:41:03 +0100 Subject: [PATCH 10/15] fix: refactor applyModifiersToResult and correct types --- packages/types/src/ts-estree.ts | 4 +-- .../typescript-estree/src/convert-guards.ts | 15 ++++++----- packages/typescript-estree/src/convert.ts | 25 ++++++------------- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/packages/types/src/ts-estree.ts b/packages/types/src/ts-estree.ts index 4bf7c867c78..3b92d7d1084 100644 --- a/packages/types/src/ts-estree.ts +++ b/packages/types/src/ts-estree.ts @@ -428,11 +428,9 @@ export type MethodDefinition = export type Modifier = | TSAbstractKeyword | TSAsyncKeyword - | TSDeclareKeyword - | TSExportKeyword - | TSPublicKeyword | TSPrivateKeyword | TSProtectedKeyword + | TSPublicKeyword | TSReadonlyKeyword | TSStaticKeyword; export type ObjectLiteralElementLike = diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index 6ca45406a12..ded437b85f3 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -145,6 +145,7 @@ export interface BaseGuard { [ts.SyntaxKind.TypeReference]: TSESTree.TSTypeReference; [ts.SyntaxKind.TypeParameter]: TSESTree.TSTypeParameter; [ts.SyntaxKind.ThisType]: TSESTree.TSThisType; + [ts.SyntaxKind.AbstractKeyword]: TSESTree.TSAbstractKeyword; [ts.SyntaxKind.AnyKeyword]: TSESTree.TSAnyKeyword; [ts.SyntaxKind.BigIntKeyword]: TSESTree.TSBigIntKeyword; [ts.SyntaxKind.BooleanKeyword]: TSESTree.TSBooleanKeyword; @@ -314,20 +315,22 @@ export type TSESTreeToTSNodeGuard< ? TSESTreeToTSNode2 : T extends ts.UpdateExpression ? TSESTreeToTSNode2 - : T extends ts.LeftHandSideExpression - ? TSESTreeToTSNode2 : T extends ts.TypeNode ? TSESTreeToTSNode2 : T extends ts.TypeElement ? TSESTreeToTSNode2 : T extends ts.ClassElement ? TSESTreeToTSNode2 + : // This is extremely slow + T extends ts.LeftHandSideExpression + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + any // TSESTreeToTSNode2 : T extends ts.Statement - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ? any // TSESTreeToTSNode2 + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + any // TSESTreeToTSNode2 : T extends ts.Expression - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ? any // TSESTreeToTSNode2 + ? // eslint-disable-next-line @typescript-eslint/no-explicit-any + any // TSESTreeToTSNode2 : null; // TODO // export type TypeTest = Exclude; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 8cf00b82d22..fbba0dff324 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -586,15 +586,14 @@ export class Converter { if (!modifiers || !modifiers.length) { return; } + const remainingModifiers: TSESTree.Modifier[] = []; /** * Some modifiers are explicitly handled by applying them as * boolean values on the result node. As well as adding them * to the result, we remove them from the array, so that they * are not handled twice. */ - const handledModifierIndices: { [key: number]: boolean } = {}; - for (let i = 0; i < modifiers.length; i++) { - const modifier = modifiers[i]; + for (const modifier of modifiers) { switch (modifier.kind) { /** * Ignore ExportKeyword and DefaultKeyword, they are handled @@ -602,31 +601,27 @@ export class Converter { */ case SyntaxKind.ExportKeyword: case SyntaxKind.DefaultKeyword: - handledModifierIndices[i] = true; break; case SyntaxKind.ConstKeyword: (result as any).const = true; - handledModifierIndices[i] = true; break; case SyntaxKind.DeclareKeyword: result.declare = true; - handledModifierIndices[i] = true; break; default: + remainingModifiers.push(this.convertChild(modifier)); + break; } } + /** * If there are still valid modifiers available which have * not been explicitly handled above, we just convert and * add the modifiers array to the result node. */ - const remainingModifiers = modifiers.filter( - (_, i) => !handledModifierIndices[i], - ); - if (!remainingModifiers || !remainingModifiers.length) { - return; + if (remainingModifiers.length) { + result.modifiers = remainingModifiers; } - result.modifiers = remainingModifiers.map(el => this.convertChild(el)); } /** @@ -2212,6 +2207,7 @@ export class Converter { type: AST_NODE_TYPES.TSThisType, }); + case SyntaxKind.AbstractKeyword: case SyntaxKind.AnyKeyword: case SyntaxKind.BigIntKeyword: case SyntaxKind.BooleanKeyword: @@ -2694,11 +2690,6 @@ export class Converter { id: this.convertChild(node.name), }); } - case SyntaxKind.AbstractKeyword: { - return this.createNode(node, { - type: AST_NODE_TYPES.TSAbstractKeyword, - }); - } // Tuple case SyntaxKind.TupleType: { From 4bd4d9aff8eb6134f294b2030b905cdf7327f0c5 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 20 Feb 2021 23:56:14 +0100 Subject: [PATCH 11/15] fix: simplify code and disable some of typeguards --- .../typescript-estree/src/convert-guards.ts | 100 ++++++------------ 1 file changed, 33 insertions(+), 67 deletions(-) diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index ded437b85f3..bf827493f40 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -1,6 +1,6 @@ import { TSESTree } from '@typescript-eslint/types'; import * as ts from 'typescript'; -import { TSNode } from './ts-estree/ts-nodes'; +import { TSNode, TSNodeUnused } from './ts-estree/ts-nodes'; /** * this is not correct yet, additional refining is required @@ -233,54 +233,33 @@ export interface PatternGuard extends BaseGuard { [ts.SyntaxKind.ObjectLiteralExpression]: TSESTree.ObjectPattern; } -// This is really slow for some reason -export type TSNodePattern = TSNode & { - kind: keyof PatternGuard | keyof NonPatternGuard; -}; -// This is really slow for some reason -export type TSNodeBaseGuard = TSNode & { kind: keyof BaseGuard }; - -export type TSNodeSupported = TSNodePattern | TSNodeBaseGuard; - -// Expressions - this is needed for optimization -export type TSNodeExpression = Exclude< - Extract, +// This is really slow - https://github.com/microsoft/TypeScript/pull/42556 +// export type TSNodeBaseGuard = TSNode & { kind: keyof BaseGuard }; +export type TSNodeBaseGuard = Exclude< + TSNode, + | TSNodeUnused + | TSNodePattern // manual fixes + | ts.ParenthesizedExpression + | ts.ComputedPropertyName | ts.OmittedExpression // there is advanced handling for this node in type guards | ts.Token // this node can be generated only in call expression ->; -export type TSNodeObjectLiteralElementLike = Extract< - TSNodeExpression, - ts.ObjectLiteralElementLike ->; -export type TSNodeLeftHandSideExpression = Extract< - TSNodeExpression, - ts.LeftHandSideExpression ->; -export type TSNodeUnaryExpression = Extract< - TSNodeExpression, - ts.UnaryExpression ->; -export type TSNodeLiteralExpression = Extract< - TSNodeExpression, - ts.LiteralExpression ->; -export type TSNodeUpdateExpression = Extract< - TSNodeExpression, - ts.UpdateExpression + | ts.ExpressionWithTypeArguments + | ts.Modifier >; -// Statements - this is needed for optimization -export type TSNodeStatement = Extract; +// This is really slow - https://github.com/microsoft/TypeScript/pull/42556 +// export type TSNodePattern = TSNode & { +// kind: keyof PatternGuard | keyof NonPatternGuard; +// }; +export type TSNodePattern = + | ts.ArrayLiteralExpression + | ts.BinaryExpression + | ts.SpreadAssignment + | ts.SpreadElement + | ts.ObjectLiteralExpression; -// Declarations - this is needed for optimization -export type TSNodeTypeNode = Exclude< - Extract, - // manual fixes - ts.ExpressionWithTypeArguments ->; -export type TSNodeTypeElement = Extract; -export type TSNodeClassElement = Extract; +export type TSNodeSupported = TSNodePattern | TSNodeBaseGuard; // ---------------- @@ -294,7 +273,7 @@ export type TSNodeConvertable = | undefined; export type TSESTreeToTSNode2< - T extends TSNodePattern, + T extends TSNodeSupported, P extends boolean > = T extends TSNodeBaseGuard ? BaseGuard[T['kind']] @@ -309,32 +288,19 @@ export type TSESTreeToTSNodeGuard< ? TSESTreeToTSNode2 : T extends TSNodeSupported ? TSESTreeToTSNode2 - : T extends ts.UnaryExpression - ? TSESTreeToTSNode2 - : T extends ts.LiteralExpression - ? TSESTreeToTSNode2 - : T extends ts.UpdateExpression - ? TSESTreeToTSNode2 - : T extends ts.TypeNode - ? TSESTreeToTSNode2 - : T extends ts.TypeElement - ? TSESTreeToTSNode2 - : T extends ts.ClassElement - ? TSESTreeToTSNode2 - : // This is extremely slow - T extends ts.LeftHandSideExpression - ? // eslint-disable-next-line @typescript-eslint/no-explicit-any - any // TSESTreeToTSNode2 - : T extends ts.Statement - ? // eslint-disable-next-line @typescript-eslint/no-explicit-any - any // TSESTreeToTSNode2 - : T extends ts.Expression - ? // eslint-disable-next-line @typescript-eslint/no-explicit-any - any // TSESTreeToTSNode2 - : null; // TODO + : T extends ts.Node + ? // This is really slow - https://github.com/microsoft/TypeScript/pull/42556 + // TSESTreeToTSNode2, P> + // eslint-disable-next-line @typescript-eslint/no-explicit-any + any + : null; // export type TypeTest = Exclude; // export type TypeTest2 = Exclude; +// Expressions - this is needed for optimization +// export type TSNodeExpression = Extract; // export type TypeTest3 = TSESTreeToTSNode2; + +// export type TypeTest4 = Exclude; From 3f8f0ca17a3bbd54ffed56cd59c6d5f164ee91f9 Mon Sep 17 00:00:00 2001 From: Armano Date: Sun, 21 Feb 2021 02:06:01 +0100 Subject: [PATCH 12/15] fix: cleanup code after refactoring --- packages/types/src/ts-estree.ts | 2 +- .../typescript-estree/src/convert-guards.ts | 29 ++++++++--- packages/typescript-estree/src/convert.ts | 15 ++++-- .../src/ts-estree/estree-to-ts-node-types.ts | 4 +- .../src/ts-estree/ts-nodes.ts | 49 +++++++++---------- 5 files changed, 58 insertions(+), 41 deletions(-) diff --git a/packages/types/src/ts-estree.ts b/packages/types/src/ts-estree.ts index 3b92d7d1084..3a20d46e41a 100644 --- a/packages/types/src/ts-estree.ts +++ b/packages/types/src/ts-estree.ts @@ -1506,7 +1506,7 @@ export interface TSModuleBlock extends BaseNode { export interface TSModuleDeclaration extends BaseNode { type: AST_NODE_TYPES.TSModuleDeclaration; id: Identifier | Literal; - body?: TSModuleBlock; + body?: TSModuleBlock | TSModuleDeclaration; global?: boolean; declare?: boolean; modifiers?: Modifier[]; diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index bf827493f40..6c13b6d70ad 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -1,6 +1,6 @@ import { TSESTree } from '@typescript-eslint/types'; import * as ts from 'typescript'; -import { TSNode, TSNodeUnused } from './ts-estree/ts-nodes'; +import { TSNodeUsed } from './ts-estree/ts-nodes'; /** * this is not correct yet, additional refining is required @@ -209,6 +209,16 @@ export interface BaseGuard { | TSESTree.AssignmentPattern // This is possible only when parent is ArrayPattern... | TSESTree.RestElement | TSESTree.Property; + + // we should delete those + [ts.SyntaxKind.ReadonlyKeyword]: TSESTree.TSReadonlyKeyword; + [ts.SyntaxKind.ExportKeyword]: TSESTree.TSExportKeyword; + [ts.SyntaxKind.PrivateKeyword]: TSESTree.TSPrivateKeyword; + [ts.SyntaxKind.ProtectedKeyword]: TSESTree.TSProtectedKeyword; + [ts.SyntaxKind.PublicKeyword]: TSESTree.TSPublicKeyword; + [ts.SyntaxKind.StaticKeyword]: TSESTree.TSStaticKeyword; + [ts.SyntaxKind.AsyncKeyword]: TSESTree.TSAsyncKeyword; + [ts.SyntaxKind.DeclareKeyword]: TSESTree.TSDeclareKeyword; } export interface NonPatternGuard extends BaseGuard { @@ -234,10 +244,9 @@ export interface PatternGuard extends BaseGuard { } // This is really slow - https://github.com/microsoft/TypeScript/pull/42556 -// export type TSNodeBaseGuard = TSNode & { kind: keyof BaseGuard }; +// export type TSNodeBaseGuard = TSNodeUsed & { kind: keyof BaseGuard }; export type TSNodeBaseGuard = Exclude< - TSNode, - | TSNodeUnused + TSNodeUsed, | TSNodePattern // manual fixes | ts.ParenthesizedExpression @@ -245,11 +254,15 @@ export type TSNodeBaseGuard = Exclude< | ts.OmittedExpression // there is advanced handling for this node in type guards | ts.Token // this node can be generated only in call expression | ts.ExpressionWithTypeArguments - | ts.Modifier + | ts.HeritageClause + | ts.CaseBlock + | ts.NamedImports + | ts.TemplateSpan + | ts.NamedExports >; // This is really slow - https://github.com/microsoft/TypeScript/pull/42556 -// export type TSNodePattern = TSNode & { +// export type TSNodePattern = TSNodeUsed & { // kind: keyof PatternGuard | keyof NonPatternGuard; // }; export type TSNodePattern = @@ -264,7 +277,7 @@ export type TSNodeSupported = TSNodePattern | TSNodeBaseGuard; // ---------------- export type TSNodeConvertable = - | TSNode + | TSNodeUsed | ts.Expression | ts.Statement | ts.TypeNode @@ -303,4 +316,4 @@ export type TSESTreeToTSNodeGuard< // export type TSNodeExpression = Extract; // export type TypeTest3 = TSESTreeToTSNode2; -// export type TypeTest4 = Exclude; +// export type TypeTest4 = Exclude; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index fbba0dff324..ec5f2713d9f 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -29,6 +29,7 @@ import { TSESTree, TSESTreeToTSNode, TSNode, + TSNodeUsed, } from './ts-estree'; import { TSESTreeToTSNodeGuard, TSNodeConvertable } from './convert-guards'; @@ -121,7 +122,10 @@ export class Converter { this.allowPattern = allowPattern; } - const result = this.convertNode

(node, (parent ?? node.parent) as TSNode); + const result = this.convertNode

( + node, + (parent ?? node.parent) as TSNodeUsed, + ); this.registerTSNodeInNodeMap(node, result); @@ -652,8 +656,8 @@ export class Converter { * @returns the converted ESTree node */ private convertNode

( - node: TSNode, - parent: TSNode, + node: TSNodeUsed, + parent: TSNodeUsed, ): TSESTreeToTSNodeGuard { switch (node.kind) { case SyntaxKind.SourceFile: { @@ -2600,7 +2604,10 @@ export class Converter { id: this.convertChild(node.name), }); if (node.body) { - result.body = this.convertChild(node.body); + // type is not correct as is include JSDoc + result.body = this.convertChild( + node.body as Exclude, + )!; } // apply modifiers first... this.applyModifiersToResult(result, node.modifiers); 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 b9e9526bcba..c717dc74ff7 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 @@ -1,6 +1,6 @@ import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/types'; import * as ts from 'typescript'; -import { TSNode, TSNodeUnused, TSNodeSkipped } from './ts-nodes'; +import { TSNodeUsed } from './ts-nodes'; export interface EstreeToTsNodeTypes { [AST_NODE_TYPES.ArrayExpression]: ts.ArrayLiteralExpression; @@ -280,7 +280,7 @@ export interface EstreeToTsNodeTypes { * This mapping is based on the internal logic of the parser. */ export type TSESTreeToTSNode = Extract< - | Exclude + | TSNodeUsed | ts.Token, // if this errors, it means that one of the AST_NODE_TYPES is not defined in the above interface EstreeToTsNodeTypes[T['type']] diff --git a/packages/typescript-estree/src/ts-estree/ts-nodes.ts b/packages/typescript-estree/src/ts-estree/ts-nodes.ts index 32887dc46b2..a69ba9b4091 100644 --- a/packages/typescript-estree/src/ts-estree/ts-nodes.ts +++ b/packages/typescript-estree/src/ts-estree/ts-nodes.ts @@ -11,24 +11,8 @@ declare module 'typescript' { export type TSToken = ts.Token; -// TODO: drop after TSESTreeToTSNode refactor -export type TSNodeSkipped = - // List of nodes that are skipped - | ts.OmittedExpression - | ts.ComputedPropertyName - | ts.ParenthesizedExpression - | ts.Token; - -// TODO: drop after TSESTreeToTSNode refactor export type TSNodeUnused = - // Nodes that are skipped when generating code - | ts.HeritageClause - | ts.CaseBlock - | ts.NamedImports - | ts.TemplateSpan - | ts.NamedExports - - // Those nodes can't be generated by ast + // Those nodes can't be generated | ts.PartiallyEmittedExpression | ts.SyntheticExpression | ts.NotEmittedStatement @@ -38,18 +22,24 @@ export type TSNodeUnused = | ts.InputFiles | ts.UnparsedNode | ts.UnparsedSource - | ts.SemicolonClassElement + | ts.SemicolonClassElement // A list of comma-separated expressions. This node is only created by transformations. // Modifiers | ts.ConstKeyword | ts.DefaultKeyword + // Type Unions + // | ts.SignatureDeclarationBase -> CallSignatureDeclaration, ConstructSignatureDeclaration + // | ts.FunctionOrConstructorTypeNodeBase -> FunctionTypeNode, ConstructorTypeNode + // JSON: Unsupported // | ts.JsonMinusNumericLiteral // same node as PrefixUnaryExpression // JSDoc: Unsupported | ts.JSDoc | ts.JSDocTypeExpression + | ts.JSDocNameReference + | ts.JSDocNamespaceDeclaration | ts.JSDocUnknownTag | ts.JSDocAugmentsTag | ts.JSDocClassTag @@ -73,17 +63,13 @@ export type TSNodeUnused = | ts.JSDocVariadicType | ts.JSDocAuthorTag; -// TODO: replace with code that retrieves all nodes that have kind -// export type TSNode2 = Extract -export type TSNode = - | TSNodeUnused - | TSNodeSkipped - | ts.Modifier +export type TSNodeUsed = + | Exclude | ts.Identifier | ts.QualifiedName + | ts.ComputedPropertyName | ts.Decorator | ts.TypeParameterDeclaration - // | ts.SignatureDeclarationBase -> CallSignatureDeclaration, ConstructSignatureDeclaration | ts.CallSignatureDeclaration | ts.ConstructSignatureDeclaration | ts.VariableDeclaration @@ -107,7 +93,6 @@ export type TSNode = | ts.KeywordTypeNode // TODO: This node is bad, maybe we should report this | ts.ImportTypeNode | ts.ThisTypeNode - // | ts.FunctionOrConstructorTypeNodeBase -> FunctionTypeNode, ConstructorTypeNode | ts.ConstructorTypeNode | ts.FunctionTypeNode | ts.TypeReferenceNode @@ -129,6 +114,7 @@ export type TSNode = | ts.MappedTypeNode | ts.LiteralTypeNode | ts.StringLiteral + | ts.OmittedExpression | ts.PrefixUnaryExpression | ts.PostfixUnaryExpression | ts.NullLiteral @@ -153,6 +139,8 @@ export type TSNode = | ts.TemplateMiddle | ts.TemplateTail | ts.TemplateExpression + | ts.TemplateSpan + | ts.ParenthesizedExpression | ts.ArrayLiteralExpression | ts.SpreadElement | ts.ObjectLiteralExpression @@ -193,6 +181,7 @@ export type TSNode = | ts.ReturnStatement | ts.WithStatement | ts.SwitchStatement + | ts.CaseBlock | ts.CaseClause | ts.DefaultClause | ts.LabeledStatement @@ -203,6 +192,7 @@ export type TSNode = | ts.ClassDeclaration | ts.ClassExpression | ts.InterfaceDeclaration + | ts.HeritageClause | ts.TypeAliasDeclaration | ts.EnumMember | ts.EnumDeclaration @@ -215,8 +205,15 @@ export type TSNode = | ts.NamespaceImport | ts.NamespaceExportDeclaration | ts.ExportDeclaration + | ts.NamedImports + | ts.NamedExports | ts.ImportSpecifier | ts.ExportSpecifier | ts.ExportAssignment | ts.SourceFile | ts.TemplateLiteralTypeNode; + +export type TSNode = TSNodeUnused | TSNodeUsed; + +// type _Test = Extract +// type _Test2 = Exclude From 5ce6ff9e0755313d5fdd465c4a9cf52e05333317 Mon Sep 17 00:00:00 2001 From: Armano Date: Sun, 21 Feb 2021 03:24:46 +0100 Subject: [PATCH 13/15] fix: correct type issues --- .../typescript-estree/src/convert-guards.ts | 2 +- packages/typescript-estree/src/convert.ts | 27 ++++++++++--------- .../src/ts-estree/estree-to-ts-node-types.ts | 3 +-- .../src/ts-estree/ts-nodes.ts | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index 6c13b6d70ad..d53d0f102aa 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -80,6 +80,7 @@ export interface BaseGuard { [ts.SyntaxKind.Parameter]: | TSESTree.RestElement | TSESTree.AssignmentPattern + | TSESTree.BindingName | TSESTree.TSParameterProperty; [ts.SyntaxKind.ClassDeclaration]: TSESTree.ClassDeclaration; [ts.SyntaxKind.ClassExpression]: TSESTree.ClassExpression; @@ -251,7 +252,6 @@ export type TSNodeBaseGuard = Exclude< // manual fixes | ts.ParenthesizedExpression | ts.ComputedPropertyName - | ts.OmittedExpression // there is advanced handling for this node in type guards | ts.Token // this node can be generated only in call expression | ts.ExpressionWithTypeArguments | ts.HeritageClause diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index ec5f2713d9f..2dbcecc1a74 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -100,12 +100,12 @@ export class Converter { * @param allowPattern flag to determine if patterns are allowed * @returns the converted ESTree node */ - private converter( - node: T, + private converter

( + node: TSNodeConvertable, parent?: ts.Node, inTypeMode?: boolean, allowPattern?: P, - ): TSESTreeToTSNodeGuard { + ): TSESTreeToTSNodeGuard { /** * Exit early for null and undefined */ @@ -123,8 +123,8 @@ export class Converter { } const result = this.convertNode

( - node, - (parent ?? node.parent) as TSNodeUsed, + node as TSNodeUsed, + parent ?? node.parent, ); this.registerTSNodeInNodeMap(node, result); @@ -221,7 +221,7 @@ export class Converter { child: T, parent?: ts.Node, ): TSESTreeToTSNodeGuard { - return this.converter(child, parent, this.inTypeMode, true); + return this.converter(child, parent, this.inTypeMode, true); } /** @@ -234,7 +234,7 @@ export class Converter { child: T, parent?: ts.Node, ): TSESTreeToTSNodeGuard { - return this.converter(child, parent, this.inTypeMode, false); + return this.converter(child, parent, this.inTypeMode, false); } /** @@ -247,7 +247,7 @@ export class Converter { child: T, parent?: ts.Node, ): TSESTreeToTSNodeGuard { - return this.converter(child, parent, true, false); + return this.converter(child, parent, true, false); } private createNode( @@ -256,7 +256,7 @@ export class Converter { ): T { const result = data; if (!result.range) { - result.range = getRange(node, this.ast); + result.range = getRange(node as TSNodeUsed, this.ast); } if (!result.loc) { result.loc = getLocFor(result.range[0], result.range[1], this.ast); @@ -320,7 +320,7 @@ export class Converter { private convertBodyExpressions( nodes: ts.NodeArray, parent: ts.SourceFile | ts.Block | ts.ModuleBlock, - ): TSESTree.Statements[] { + ): TSESTree.Statement[] { let allowDirectives = canContainDirective(parent); return ( @@ -657,7 +657,7 @@ export class Converter { */ private convertNode

( node: TSNodeUsed, - parent: TSNodeUsed, + parent: TSNode | ts.Node, ): TSESTreeToTSNodeGuard { switch (node.kind) { case SyntaxKind.SourceFile: { @@ -1444,7 +1444,10 @@ export class Converter { case SyntaxKind.Parameter: { let parameter: TSESTree.RestElement | TSESTree.BindingName; - let result: TSESTree.RestElement | TSESTree.AssignmentPattern; + let result: + | TSESTree.RestElement + | TSESTree.AssignmentPattern + | TSESTree.BindingName; if (node.dotDotDotToken) { parameter = 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 c717dc74ff7..480a0b3cddf 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 @@ -280,8 +280,7 @@ export interface EstreeToTsNodeTypes { * This mapping is based on the internal logic of the parser. */ export type TSESTreeToTSNode = Extract< - | TSNodeUsed - | ts.Token, + TSNodeUsed | ts.Token, // if this errors, it means that one of the AST_NODE_TYPES is not defined in the above interface EstreeToTsNodeTypes[T['type']] >; diff --git a/packages/typescript-estree/src/ts-estree/ts-nodes.ts b/packages/typescript-estree/src/ts-estree/ts-nodes.ts index a69ba9b4091..c984be251a0 100644 --- a/packages/typescript-estree/src/ts-estree/ts-nodes.ts +++ b/packages/typescript-estree/src/ts-estree/ts-nodes.ts @@ -31,6 +31,7 @@ export type TSNodeUnused = // Type Unions // | ts.SignatureDeclarationBase -> CallSignatureDeclaration, ConstructSignatureDeclaration // | ts.FunctionOrConstructorTypeNodeBase -> FunctionTypeNode, ConstructorTypeNode + // | ts.ClassLikeDeclarationBase -> ClassDeclaration | ClassExpression // JSON: Unsupported // | ts.JsonMinusNumericLiteral // same node as PrefixUnaryExpression @@ -188,7 +189,6 @@ export type TSNodeUsed = | ts.ThrowStatement | ts.TryStatement | ts.CatchClause - // | ts.ClassLikeDeclarationBase -> ClassDeclaration | ClassExpression | ts.ClassDeclaration | ts.ClassExpression | ts.InterfaceDeclaration From 88d000a346dde60a5c1d0929ee7d6c56eb038f9d Mon Sep 17 00:00:00 2001 From: Armano Date: Sun, 21 Feb 2021 14:33:37 +0100 Subject: [PATCH 14/15] refactor: improve guard name --- packages/typescript-estree/src/convert-guards.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index d53d0f102aa..05f39f22989 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -285,7 +285,7 @@ export type TSNodeConvertable = | ts.ClassElement | undefined; -export type TSESTreeToTSNode2< +export type TSESTreeToTSNodeGuardHelper< T extends TSNodeSupported, P extends boolean > = T extends TSNodeBaseGuard @@ -298,12 +298,12 @@ export type TSESTreeToTSNodeGuard< T extends TSNodeConvertable, P extends boolean > = T extends ts.ParenthesizedExpression - ? TSESTreeToTSNode2 + ? TSESTreeToTSNodeGuardHelper : T extends TSNodeSupported - ? TSESTreeToTSNode2 + ? TSESTreeToTSNodeGuardHelper : T extends ts.Node ? // This is really slow - https://github.com/microsoft/TypeScript/pull/42556 - // TSESTreeToTSNode2, P> + // TSESTreeToTSNodeGuardHelper, P> // eslint-disable-next-line @typescript-eslint/no-explicit-any any : null; @@ -314,6 +314,6 @@ export type TSESTreeToTSNodeGuard< // Expressions - this is needed for optimization // export type TSNodeExpression = Extract; -// export type TypeTest3 = TSESTreeToTSNode2; +// export type TypeTest3 = TSESTreeToTSNodeGuardHelper; // export type TypeTest4 = Exclude; From 35e498fad7d439f37261f9366cb82e948b7f8e7b Mon Sep 17 00:00:00 2001 From: Armano Date: Mon, 22 Feb 2021 05:49:20 +0100 Subject: [PATCH 15/15] fix: refactor type guards --- .../typescript-estree/src/convert-guards.ts | 659 +++++++++++------- packages/typescript-estree/src/convert.ts | 54 +- 2 files changed, 442 insertions(+), 271 deletions(-) diff --git a/packages/typescript-estree/src/convert-guards.ts b/packages/typescript-estree/src/convert-guards.ts index 05f39f22989..36da34ae62a 100644 --- a/packages/typescript-estree/src/convert-guards.ts +++ b/packages/typescript-estree/src/convert-guards.ts @@ -5,244 +5,378 @@ import { TSNodeUsed } from './ts-estree/ts-nodes'; /** * this is not correct yet, additional refining is required */ -export interface BaseGuard { - [ts.SyntaxKind.SourceFile]: TSESTree.Program; - [ts.SyntaxKind.Block]: TSESTree.BlockStatement; - [ts.SyntaxKind.Identifier]: TSESTree.Identifier; - [ts.SyntaxKind.WithStatement]: TSESTree.WithStatement; - [ts.SyntaxKind.ReturnStatement]: TSESTree.ReturnStatement; - [ts.SyntaxKind.LabeledStatement]: TSESTree.LabeledStatement; - [ts.SyntaxKind.ContinueStatement]: TSESTree.ContinueStatement; - [ts.SyntaxKind.BreakStatement]: TSESTree.BreakStatement; - [ts.SyntaxKind.IfStatement]: TSESTree.IfStatement; - [ts.SyntaxKind.SwitchStatement]: TSESTree.SwitchStatement; - [ts.SyntaxKind.CaseClause]: TSESTree.SwitchCase; - [ts.SyntaxKind.DefaultClause]: TSESTree.SwitchCase; - [ts.SyntaxKind.ThrowStatement]: TSESTree.ThrowStatement; - [ts.SyntaxKind.TryStatement]: TSESTree.TryStatement; - [ts.SyntaxKind.CatchClause]: TSESTree.CatchClause; - [ts.SyntaxKind.WhileStatement]: TSESTree.WhileStatement; - [ts.SyntaxKind.DoStatement]: TSESTree.DoWhileStatement; - [ts.SyntaxKind.ForStatement]: TSESTree.ForStatement; - [ts.SyntaxKind.ForInStatement]: TSESTree.ForInStatement; - [ts.SyntaxKind.ForOfStatement]: TSESTree.ForOfStatement; - [ts.SyntaxKind.FunctionDeclaration]: - | TSESTree.TSDeclareFunction - | TSESTree.FunctionDeclaration; - [ts.SyntaxKind.VariableDeclaration]: TSESTree.VariableDeclarator; - [ts.SyntaxKind.VariableStatement]: TSESTree.VariableDeclaration; - [ts.SyntaxKind.VariableDeclarationList]: TSESTree.VariableDeclaration; - [ts.SyntaxKind.ExpressionStatement]: TSESTree.ExpressionStatement; - [ts.SyntaxKind.ThisKeyword]: TSESTree.ThisExpression; - [ts.SyntaxKind.PropertyAssignment]: TSESTree.Property; - [ts.SyntaxKind.ShorthandPropertyAssignment]: TSESTree.Property; - // TODO: skipped node - [ts.SyntaxKind.ComputedPropertyName]: null; - [ts.SyntaxKind.PropertyDeclaration]: - | TSESTree.TSAbstractClassProperty - | TSESTree.ClassProperty; - // TODO: conditional - [ts.SyntaxKind.GetAccessor]: - | TSESTree.TSEmptyBodyFunctionExpression - | TSESTree.TSAbstractMethodDefinition - | TSESTree.MethodDefinition - | TSESTree.FunctionExpression - | TSESTree.Property; - [ts.SyntaxKind.SetAccessor]: - | TSESTree.TSEmptyBodyFunctionExpression - | TSESTree.TSAbstractMethodDefinition - | TSESTree.MethodDefinition - | TSESTree.FunctionExpression - | TSESTree.Property; - [ts.SyntaxKind.MethodDeclaration]: - | TSESTree.TSEmptyBodyFunctionExpression - | TSESTree.TSAbstractMethodDefinition - | TSESTree.MethodDefinition - | TSESTree.FunctionExpression - | TSESTree.Property; - [ts.SyntaxKind.Constructor]: - | TSESTree.TSAbstractMethodDefinition - | TSESTree.MethodDefinition; - [ts.SyntaxKind.FunctionExpression]: TSESTree.FunctionExpression; - [ts.SyntaxKind.SuperKeyword]: TSESTree.Super; - [ts.SyntaxKind.ArrayBindingPattern]: TSESTree.ArrayPattern; - [ts.SyntaxKind.OmittedExpression]: null; - [ts.SyntaxKind.ObjectBindingPattern]: TSESTree.ObjectPattern; - [ts.SyntaxKind.ArrowFunction]: TSESTree.ArrowFunctionExpression; - [ts.SyntaxKind.YieldExpression]: TSESTree.YieldExpression; - [ts.SyntaxKind.AwaitExpression]: TSESTree.AwaitExpression; - [ts.SyntaxKind.NoSubstitutionTemplateLiteral]: TSESTree.TemplateLiteral; - [ts.SyntaxKind.TemplateExpression]: TSESTree.TemplateLiteral; - [ts.SyntaxKind.TaggedTemplateExpression]: TSESTree.TaggedTemplateExpression; - [ts.SyntaxKind.TemplateHead]: TSESTree.TemplateElement; - [ts.SyntaxKind.TemplateMiddle]: TSESTree.TemplateElement; - [ts.SyntaxKind.TemplateTail]: TSESTree.TemplateElement; - [ts.SyntaxKind.Parameter]: - | TSESTree.RestElement - | TSESTree.AssignmentPattern - | TSESTree.BindingName - | TSESTree.TSParameterProperty; - [ts.SyntaxKind.ClassDeclaration]: TSESTree.ClassDeclaration; - [ts.SyntaxKind.ClassExpression]: TSESTree.ClassExpression; - [ts.SyntaxKind.ModuleBlock]: TSESTree.TSModuleBlock; - [ts.SyntaxKind.ImportDeclaration]: TSESTree.ImportDeclaration; - [ts.SyntaxKind.NamespaceImport]: TSESTree.ImportNamespaceSpecifier; - [ts.SyntaxKind.ImportSpecifier]: TSESTree.ImportSpecifier; - [ts.SyntaxKind.ImportClause]: TSESTree.ImportDefaultSpecifier; - [ts.SyntaxKind.ExportDeclaration]: - | TSESTree.ExportNamedDeclaration - | TSESTree.ExportAllDeclaration; - [ts.SyntaxKind.ExportSpecifier]: TSESTree.ExportSpecifier; - [ts.SyntaxKind.ExportAssignment]: - | TSESTree.TSExportAssignment - | TSESTree.ExportDefaultDeclaration; - [ts.SyntaxKind.PrefixUnaryExpression]: - | TSESTree.UpdateExpression - | TSESTree.UnaryExpression; - [ts.SyntaxKind.PostfixUnaryExpression]: - | TSESTree.UpdateExpression - | TSESTree.UnaryExpression; - [ts.SyntaxKind.DeleteExpression]: TSESTree.UnaryExpression; - [ts.SyntaxKind.VoidExpression]: TSESTree.UnaryExpression; - [ts.SyntaxKind.TypeOfExpression]: TSESTree.UnaryExpression; - [ts.SyntaxKind.TypeOperator]: TSESTree.TSTypeOperator; - [ts.SyntaxKind.PropertyAccessExpression]: - | TSESTree.MemberExpression - | TSESTree.ChainExpression; - [ts.SyntaxKind.ElementAccessExpression]: - | TSESTree.MemberExpression - | TSESTree.ChainExpression; - [ts.SyntaxKind.CallExpression]: - | TSESTree.ImportExpression - | TSESTree.CallExpression - | TSESTree.ChainExpression; - [ts.SyntaxKind.NewExpression]: TSESTree.NewExpression; - [ts.SyntaxKind.ConditionalExpression]: TSESTree.ConditionalExpression; - [ts.SyntaxKind.MetaProperty]: TSESTree.MetaProperty; - [ts.SyntaxKind.Decorator]: TSESTree.Decorator; - [ts.SyntaxKind.StringLiteral]: TSESTree.StringLiteral; - [ts.SyntaxKind.NumericLiteral]: TSESTree.NumberLiteral; - [ts.SyntaxKind.BigIntLiteral]: TSESTree.BigIntLiteral; - [ts.SyntaxKind.RegularExpressionLiteral]: TSESTree.RegExpLiteral; - [ts.SyntaxKind.TrueKeyword]: TSESTree.BooleanLiteral; - [ts.SyntaxKind.FalseKeyword]: TSESTree.BooleanLiteral; - [ts.SyntaxKind.NullKeyword]: TSESTree.NullLiteral | TSESTree.TSNullKeyword; - [ts.SyntaxKind.EmptyStatement]: TSESTree.EmptyStatement; - [ts.SyntaxKind.DebuggerStatement]: TSESTree.DebuggerStatement; - [ts.SyntaxKind.JsxElement]: TSESTree.JSXElement; - [ts.SyntaxKind.JsxFragment]: TSESTree.JSXFragment; - [ts.SyntaxKind.JsxSelfClosingElement]: TSESTree.JSXElement; - [ts.SyntaxKind.JsxOpeningElement]: TSESTree.JSXOpeningElement; - [ts.SyntaxKind.JsxClosingElement]: TSESTree.JSXClosingElement; - [ts.SyntaxKind.JsxOpeningFragment]: TSESTree.JSXOpeningFragment; - [ts.SyntaxKind.JsxClosingFragment]: TSESTree.JSXClosingFragment; - [ts.SyntaxKind.JsxExpression]: - | TSESTree.JSXSpreadChild - | TSESTree.JSXExpressionContainer; - [ts.SyntaxKind.JsxAttribute]: TSESTree.JSXAttribute; - [ts.SyntaxKind.JsxText]: TSESTree.JSXText; - [ts.SyntaxKind.JsxSpreadAttribute]: TSESTree.JSXSpreadAttribute; - [ts.SyntaxKind.QualifiedName]: TSESTree.TSQualifiedName; - [ts.SyntaxKind.TypeReference]: TSESTree.TSTypeReference; - [ts.SyntaxKind.TypeParameter]: TSESTree.TSTypeParameter; - [ts.SyntaxKind.ThisType]: TSESTree.TSThisType; - [ts.SyntaxKind.AbstractKeyword]: TSESTree.TSAbstractKeyword; - [ts.SyntaxKind.AnyKeyword]: TSESTree.TSAnyKeyword; - [ts.SyntaxKind.BigIntKeyword]: TSESTree.TSBigIntKeyword; - [ts.SyntaxKind.BooleanKeyword]: TSESTree.TSBooleanKeyword; - [ts.SyntaxKind.NeverKeyword]: TSESTree.TSNeverKeyword; - [ts.SyntaxKind.NumberKeyword]: TSESTree.TSNumberKeyword; - [ts.SyntaxKind.ObjectKeyword]: TSESTree.TSObjectKeyword; - [ts.SyntaxKind.StringKeyword]: TSESTree.TSStringKeyword; - [ts.SyntaxKind.SymbolKeyword]: TSESTree.TSSymbolKeyword; - [ts.SyntaxKind.UnknownKeyword]: TSESTree.TSUnknownKeyword; - [ts.SyntaxKind.VoidKeyword]: TSESTree.TSVoidKeyword; - [ts.SyntaxKind.UndefinedKeyword]: TSESTree.TSUndefinedKeyword; - [ts.SyntaxKind.NonNullExpression]: - | TSESTree.TSNonNullExpression - | TSESTree.ChainExpression; - [ts.SyntaxKind.TypeLiteral]: TSESTree.TSTypeLiteral; - [ts.SyntaxKind.ArrayType]: TSESTree.TSArrayType; - [ts.SyntaxKind.IndexedAccessType]: TSESTree.TSIndexedAccessType; - [ts.SyntaxKind.ConditionalType]: TSESTree.TSConditionalType; - [ts.SyntaxKind.TypeQuery]: TSESTree.TSTypeQuery; - [ts.SyntaxKind.MappedType]: TSESTree.TSMappedType; - // TODO: exports - [ts.SyntaxKind.TypeAliasDeclaration]: TSESTree.TSTypeAliasDeclaration; - [ts.SyntaxKind.MethodSignature]: TSESTree.TSMethodSignature; - [ts.SyntaxKind.PropertySignature]: TSESTree.TSPropertySignature; - [ts.SyntaxKind.IndexSignature]: TSESTree.TSIndexSignature; - [ts.SyntaxKind.ConstructorType]: TSESTree.TSConstructorType; - [ts.SyntaxKind.FunctionType]: TSESTree.TSFunctionType; - [ts.SyntaxKind.ConstructSignature]: TSESTree.TSConstructSignatureDeclaration; - [ts.SyntaxKind.CallSignature]: TSESTree.TSCallSignatureDeclaration; - [ts.SyntaxKind.ExpressionWithTypeArguments]: - | TSESTree.TSInterfaceHeritage - | TSESTree.TSClassImplements; - // TODO: exports - [ts.SyntaxKind.InterfaceDeclaration]: TSESTree.TSInterfaceDeclaration; - [ts.SyntaxKind.TypePredicate]: TSESTree.TSTypePredicate; - [ts.SyntaxKind.ImportType]: TSESTree.TSImportType; - [ts.SyntaxKind.EnumDeclaration]: TSESTree.TSEnumDeclaration; - [ts.SyntaxKind.EnumMember]: TSESTree.TSEnumMember; - [ts.SyntaxKind.ModuleDeclaration]: TSESTree.TSModuleDeclaration; - [ts.SyntaxKind.ParenthesizedType]: TSESTree.TSParenthesizedType; - [ts.SyntaxKind.UnionType]: TSESTree.TSUnionType; - [ts.SyntaxKind.IntersectionType]: TSESTree.TSIntersectionType; - [ts.SyntaxKind.AsExpression]: TSESTree.TSAsExpression; - [ts.SyntaxKind.InferType]: TSESTree.TSInferType; - [ts.SyntaxKind.LiteralType]: TSESTree.TSLiteralType; - [ts.SyntaxKind.TypeAssertionExpression]: TSESTree.TSTypeAssertion; - [ts.SyntaxKind.ImportEqualsDeclaration]: TSESTree.TSImportEqualsDeclaration; - [ts.SyntaxKind.ExternalModuleReference]: TSESTree.TSExternalModuleReference; - [ts.SyntaxKind - .NamespaceExportDeclaration]: TSESTree.TSNamespaceExportDeclaration; - [ts.SyntaxKind.AbstractKeyword]: TSESTree.TSAbstractKeyword; - [ts.SyntaxKind.TupleType]: TSESTree.TSTupleType; - [ts.SyntaxKind.NamedTupleMember]: - | TSESTree.TSNamedTupleMember - | TSESTree.TSRestType; - [ts.SyntaxKind.OptionalType]: TSESTree.TSOptionalType; - [ts.SyntaxKind.RestType]: TSESTree.TSRestType; - [ts.SyntaxKind.TemplateLiteralType]: TSESTree.TSTemplateLiteralType; - [ts.SyntaxKind.IntrinsicKeyword]: TSESTree.TSIntrinsicKeyword; - [ts.SyntaxKind.BindingElement]: - | TSESTree.AssignmentPattern // This is possible only when parent is ArrayPattern... - | TSESTree.RestElement - | TSESTree.Property; +export type BaseGuardType< + T extends TSNodeUsed, + KIND = T['kind'] +> = KIND extends ts.SyntaxKind.SourceFile + ? TSESTree.Program + : KIND extends ts.SyntaxKind.Block + ? TSESTree.BlockStatement + : KIND extends ts.SyntaxKind.Identifier + ? TSESTree.Identifier + : KIND extends ts.SyntaxKind.WithStatement + ? TSESTree.WithStatement + : KIND extends ts.SyntaxKind.WithStatement + ? TSESTree.WithStatement + : KIND extends ts.SyntaxKind.ReturnStatement + ? TSESTree.ReturnStatement + : KIND extends ts.SyntaxKind.LabeledStatement + ? TSESTree.LabeledStatement + : KIND extends ts.SyntaxKind.ContinueStatement + ? TSESTree.ContinueStatement + : KIND extends ts.SyntaxKind.BreakStatement + ? TSESTree.BreakStatement + : KIND extends ts.SyntaxKind.IfStatement + ? TSESTree.IfStatement + : KIND extends ts.SyntaxKind.SwitchStatement + ? TSESTree.SwitchStatement + : KIND extends ts.SyntaxKind.CaseClause + ? TSESTree.SwitchCase + : KIND extends ts.SyntaxKind.DefaultClause + ? TSESTree.SwitchCase + : KIND extends ts.SyntaxKind.ThrowStatement + ? TSESTree.ThrowStatement + : KIND extends ts.SyntaxKind.TryStatement + ? TSESTree.TryStatement + : KIND extends ts.SyntaxKind.CatchClause + ? TSESTree.CatchClause + : KIND extends ts.SyntaxKind.WhileStatement + ? TSESTree.WhileStatement + : KIND extends ts.SyntaxKind.DoStatement + ? TSESTree.DoWhileStatement + : KIND extends ts.SyntaxKind.ForStatement + ? TSESTree.ForStatement + : KIND extends ts.SyntaxKind.ForInStatement + ? TSESTree.ForInStatement + : KIND extends ts.SyntaxKind.ForOfStatement + ? TSESTree.ForOfStatement + : KIND extends ts.SyntaxKind.FunctionDeclaration + ? TSESTree.TSDeclareFunction | TSESTree.FunctionDeclaration + : KIND extends ts.SyntaxKind.VariableDeclaration + ? TSESTree.VariableDeclarator + : KIND extends ts.SyntaxKind.VariableStatement + ? TSESTree.VariableDeclaration + : KIND extends ts.SyntaxKind.VariableDeclarationList + ? TSESTree.VariableDeclaration + : KIND extends ts.SyntaxKind.ExpressionStatement + ? TSESTree.ExpressionStatement + : KIND extends ts.SyntaxKind.ThisKeyword + ? TSESTree.ThisExpression + : KIND extends ts.SyntaxKind.PropertyAssignment + ? TSESTree.Property + : KIND extends ts.SyntaxKind.ShorthandPropertyAssignment + ? TSESTree.Property + : KIND extends ts.SyntaxKind.PropertyDeclaration + ? TSESTree.TSAbstractClassProperty | TSESTree.ClassProperty // TODO: skipped node + : // TODO: conditional + KIND extends ts.SyntaxKind.GetAccessor + ? + | TSESTree.TSEmptyBodyFunctionExpression + | TSESTree.TSAbstractMethodDefinition + | TSESTree.MethodDefinition + | TSESTree.FunctionExpression + | TSESTree.Property + : KIND extends ts.SyntaxKind.SetAccessor + ? + | TSESTree.TSEmptyBodyFunctionExpression + | TSESTree.TSAbstractMethodDefinition + | TSESTree.MethodDefinition + | TSESTree.FunctionExpression + | TSESTree.Property + : KIND extends ts.SyntaxKind.MethodDeclaration + ? + | TSESTree.TSEmptyBodyFunctionExpression + | TSESTree.TSAbstractMethodDefinition + | TSESTree.MethodDefinition + | TSESTree.FunctionExpression + | TSESTree.Property + : KIND extends ts.SyntaxKind.Constructor + ? TSESTree.TSAbstractMethodDefinition | TSESTree.MethodDefinition + : KIND extends ts.SyntaxKind.FunctionExpression + ? TSESTree.FunctionExpression + : KIND extends ts.SyntaxKind.SuperKeyword + ? TSESTree.Super + : KIND extends ts.SyntaxKind.ArrayBindingPattern + ? TSESTree.ArrayPattern + : KIND extends ts.SyntaxKind.OmittedExpression + ? null + : KIND extends ts.SyntaxKind.ObjectBindingPattern + ? TSESTree.ObjectPattern + : KIND extends ts.SyntaxKind.ArrowFunction + ? TSESTree.ArrowFunctionExpression + : KIND extends ts.SyntaxKind.YieldExpression + ? TSESTree.YieldExpression + : KIND extends ts.SyntaxKind.AwaitExpression + ? TSESTree.AwaitExpression + : KIND extends + | ts.SyntaxKind.NoSubstitutionTemplateLiteral + | ts.SyntaxKind.TemplateExpression + ? TSESTree.TemplateLiteral + : KIND extends ts.SyntaxKind.TaggedTemplateExpression + ? TSESTree.TaggedTemplateExpression + : KIND extends + | ts.SyntaxKind.TemplateHead + | ts.SyntaxKind.TemplateMiddle + | ts.SyntaxKind.TemplateTail + ? TSESTree.TemplateElement + : KIND extends ts.SyntaxKind.Parameter + ? + | TSESTree.RestElement + | TSESTree.AssignmentPattern + | TSESTree.BindingName + | TSESTree.TSParameterProperty + : KIND extends ts.SyntaxKind.ClassDeclaration + ? TSESTree.ClassDeclaration + : KIND extends ts.SyntaxKind.ClassExpression + ? TSESTree.ClassExpression + : KIND extends ts.SyntaxKind.ModuleBlock + ? TSESTree.TSModuleBlock + : KIND extends ts.SyntaxKind.ImportDeclaration + ? TSESTree.ImportDeclaration + : KIND extends ts.SyntaxKind.NamespaceImport + ? TSESTree.ImportNamespaceSpecifier + : KIND extends ts.SyntaxKind.ImportSpecifier + ? TSESTree.ImportSpecifier + : KIND extends ts.SyntaxKind.ImportClause + ? TSESTree.ImportDefaultSpecifier + : KIND extends ts.SyntaxKind.ExportDeclaration + ? TSESTree.ExportNamedDeclaration | TSESTree.ExportAllDeclaration + : KIND extends ts.SyntaxKind.ExportSpecifier + ? TSESTree.ExportSpecifier + : KIND extends ts.SyntaxKind.ExportAssignment + ? TSESTree.TSExportAssignment | TSESTree.ExportDefaultDeclaration + : KIND extends + | ts.SyntaxKind.PrefixUnaryExpression + | ts.SyntaxKind.PostfixUnaryExpression + ? TSESTree.UpdateExpression | TSESTree.UnaryExpression + : KIND extends + | ts.SyntaxKind.DeleteExpression + | ts.SyntaxKind.VoidExpression + | ts.SyntaxKind.TypeOfExpression + ? TSESTree.UnaryExpression + : KIND extends ts.SyntaxKind.TypeOperator + ? TSESTree.TSTypeOperator + : KIND extends + | ts.SyntaxKind.PropertyAccessExpression + | ts.SyntaxKind.ElementAccessExpression + ? TSESTree.MemberExpression | TSESTree.ChainExpression + : KIND extends ts.SyntaxKind.CallExpression + ? + | TSESTree.ImportExpression + | TSESTree.CallExpression + | TSESTree.ChainExpression + : KIND extends ts.SyntaxKind.NewExpression + ? TSESTree.NewExpression + : KIND extends ts.SyntaxKind.ConditionalExpression + ? TSESTree.ConditionalExpression + : KIND extends ts.SyntaxKind.MetaProperty + ? TSESTree.MetaProperty + : KIND extends ts.SyntaxKind.Decorator + ? TSESTree.Decorator + : KIND extends ts.SyntaxKind.StringLiteral + ? TSESTree.StringLiteral + : KIND extends ts.SyntaxKind.NumericLiteral + ? TSESTree.NumberLiteral + : KIND extends ts.SyntaxKind.BigIntLiteral + ? TSESTree.BigIntLiteral + : KIND extends ts.SyntaxKind.RegularExpressionLiteral + ? TSESTree.RegExpLiteral + : KIND extends ts.SyntaxKind.TrueKeyword + ? TSESTree.BooleanLiteral + : KIND extends ts.SyntaxKind.FalseKeyword + ? TSESTree.BooleanLiteral + : KIND extends ts.SyntaxKind.NullKeyword + ? TSESTree.NullLiteral + : KIND extends ts.SyntaxKind.EmptyStatement + ? TSESTree.EmptyStatement + : KIND extends ts.SyntaxKind.DebuggerStatement + ? TSESTree.DebuggerStatement + : KIND extends ts.SyntaxKind.JsxFragment + ? TSESTree.JSXFragment + : KIND extends ts.SyntaxKind.JsxElement | ts.SyntaxKind.JsxSelfClosingElement + ? TSESTree.JSXElement + : KIND extends ts.SyntaxKind.JsxOpeningElement + ? TSESTree.JSXOpeningElement + : KIND extends ts.SyntaxKind.JsxClosingElement + ? TSESTree.JSXClosingElement + : KIND extends ts.SyntaxKind.JsxOpeningFragment + ? TSESTree.JSXOpeningFragment + : KIND extends ts.SyntaxKind.JsxClosingFragment + ? TSESTree.JSXClosingFragment + : KIND extends ts.SyntaxKind.JsxExpression + ? TSESTree.JSXSpreadChild | TSESTree.JSXExpressionContainer + : KIND extends ts.SyntaxKind.JsxAttribute + ? TSESTree.JSXAttribute + : KIND extends ts.SyntaxKind.JsxText + ? TSESTree.JSXText + : KIND extends ts.SyntaxKind.JsxSpreadAttribute + ? TSESTree.JSXSpreadAttribute + : KIND extends ts.SyntaxKind.QualifiedName + ? TSESTree.TSQualifiedName + : KIND extends ts.SyntaxKind.TypeReference + ? TSESTree.TSTypeReference + : KIND extends ts.SyntaxKind.TypeParameter + ? TSESTree.TSTypeParameter + : KIND extends ts.SyntaxKind.ThisType + ? TSESTree.TSThisType + : KIND extends ts.SyntaxKind.AbstractKeyword + ? TSESTree.TSAbstractKeyword + : KIND extends ts.SyntaxKind.AnyKeyword + ? TSESTree.TSAnyKeyword + : KIND extends ts.SyntaxKind.BigIntKeyword + ? TSESTree.TSBigIntKeyword + : KIND extends ts.SyntaxKind.BooleanKeyword + ? TSESTree.TSBooleanKeyword + : KIND extends ts.SyntaxKind.NeverKeyword + ? TSESTree.TSNeverKeyword + : KIND extends ts.SyntaxKind.NumberKeyword + ? TSESTree.TSNumberKeyword + : KIND extends ts.SyntaxKind.ObjectKeyword + ? TSESTree.TSObjectKeyword + : KIND extends ts.SyntaxKind.StringKeyword + ? TSESTree.TSStringKeyword + : KIND extends ts.SyntaxKind.SymbolKeyword + ? TSESTree.TSSymbolKeyword + : KIND extends ts.SyntaxKind.UnknownKeyword + ? TSESTree.TSUnknownKeyword + : KIND extends ts.SyntaxKind.VoidKeyword + ? TSESTree.TSVoidKeyword + : KIND extends ts.SyntaxKind.UndefinedKeyword + ? TSESTree.TSUndefinedKeyword + : KIND extends ts.SyntaxKind.NonNullExpression + ? TSESTree.TSNonNullExpression | TSESTree.ChainExpression + : KIND extends ts.SyntaxKind.TypeLiteral + ? TSESTree.TSTypeLiteral + : KIND extends ts.SyntaxKind.ArrayType + ? TSESTree.TSArrayType + : KIND extends ts.SyntaxKind.IndexedAccessType + ? TSESTree.TSIndexedAccessType + : KIND extends ts.SyntaxKind.ConditionalType + ? TSESTree.TSConditionalType + : KIND extends ts.SyntaxKind.TypeQuery + ? TSESTree.TSTypeQuery + : KIND extends ts.SyntaxKind.MappedType + ? TSESTree.TSMappedType + : KIND extends ts.SyntaxKind.TypeAliasDeclaration // TODO: exports + ? TSESTree.TSTypeAliasDeclaration + : KIND extends ts.SyntaxKind.MethodSignature + ? TSESTree.TSMethodSignature + : KIND extends ts.SyntaxKind.PropertySignature + ? TSESTree.TSPropertySignature + : KIND extends ts.SyntaxKind.IndexSignature + ? TSESTree.TSIndexSignature + : KIND extends ts.SyntaxKind.ConstructorType + ? TSESTree.TSConstructorType + : KIND extends ts.SyntaxKind.FunctionType + ? TSESTree.TSFunctionType + : KIND extends ts.SyntaxKind.ConstructSignature + ? TSESTree.TSConstructSignatureDeclaration + : KIND extends ts.SyntaxKind.CallSignature + ? TSESTree.TSCallSignatureDeclaration + : KIND extends ts.SyntaxKind.ExpressionWithTypeArguments + ? TSESTree.TSInterfaceHeritage | TSESTree.TSClassImplements + : KIND extends ts.SyntaxKind.InterfaceDeclaration // TODO: exports + ? TSESTree.TSInterfaceDeclaration + : KIND extends ts.SyntaxKind.TypePredicate + ? TSESTree.TSTypePredicate + : KIND extends ts.SyntaxKind.ImportType + ? TSESTree.TSImportType + : KIND extends ts.SyntaxKind.EnumDeclaration + ? TSESTree.TSEnumDeclaration + : KIND extends ts.SyntaxKind.EnumMember + ? TSESTree.TSEnumMember + : KIND extends ts.SyntaxKind.ModuleDeclaration + ? TSESTree.TSModuleDeclaration + : KIND extends ts.SyntaxKind.ParenthesizedType + ? TSESTree.TSParenthesizedType + : KIND extends ts.SyntaxKind.UnionType + ? TSESTree.TSUnionType + : KIND extends ts.SyntaxKind.IntersectionType + ? TSESTree.TSIntersectionType + : KIND extends ts.SyntaxKind.AsExpression + ? TSESTree.TSAsExpression + : KIND extends ts.SyntaxKind.InferType + ? TSESTree.TSInferType + : KIND extends ts.SyntaxKind.LiteralType + ? TSESTree.TSLiteralType | TSESTree.TSNullKeyword + : KIND extends ts.SyntaxKind.TypeAssertionExpression + ? TSESTree.TSTypeAssertion + : KIND extends ts.SyntaxKind.ImportEqualsDeclaration + ? TSESTree.TSImportEqualsDeclaration + : KIND extends ts.SyntaxKind.ExternalModuleReference + ? TSESTree.TSExternalModuleReference + : KIND extends ts.SyntaxKind.NamespaceExportDeclaration + ? TSESTree.TSNamespaceExportDeclaration + : KIND extends ts.SyntaxKind.AbstractKeyword + ? TSESTree.TSAbstractKeyword + : KIND extends ts.SyntaxKind.TupleType + ? TSESTree.TSTupleType + : KIND extends ts.SyntaxKind.NamedTupleMember + ? TSESTree.TSNamedTupleMember | TSESTree.TSRestType + : KIND extends ts.SyntaxKind.OptionalType + ? TSESTree.TSOptionalType + : KIND extends ts.SyntaxKind.RestType + ? TSESTree.TSRestType + : KIND extends ts.SyntaxKind.TemplateLiteralType + ? TSESTree.TSTemplateLiteralType + : KIND extends ts.SyntaxKind.IntrinsicKeyword + ? TSESTree.TSIntrinsicKeyword + : KIND extends ts.SyntaxKind.BindingElement + ? + | TSESTree.AssignmentPattern // This is possible only when parent is ArrayPattern... + | TSESTree.RestElement + | TSESTree.Property + : KIND extends ts.SyntaxKind.ReadonlyKeyword // we should delete those + ? TSESTree.TSReadonlyKeyword + : KIND extends ts.SyntaxKind.ExportKeyword + ? TSESTree.TSExportKeyword + : KIND extends ts.SyntaxKind.PrivateKeyword + ? TSESTree.TSPrivateKeyword + : KIND extends ts.SyntaxKind.ProtectedKeyword + ? TSESTree.TSProtectedKeyword + : KIND extends ts.SyntaxKind.PublicKeyword + ? TSESTree.TSPublicKeyword + : KIND extends ts.SyntaxKind.StaticKeyword + ? TSESTree.TSStaticKeyword + : KIND extends ts.SyntaxKind.AsyncKeyword + ? TSESTree.TSAsyncKeyword + : KIND extends ts.SyntaxKind.DeclareKeyword + ? TSESTree.TSDeclareKeyword + : never; - // we should delete those - [ts.SyntaxKind.ReadonlyKeyword]: TSESTree.TSReadonlyKeyword; - [ts.SyntaxKind.ExportKeyword]: TSESTree.TSExportKeyword; - [ts.SyntaxKind.PrivateKeyword]: TSESTree.TSPrivateKeyword; - [ts.SyntaxKind.ProtectedKeyword]: TSESTree.TSProtectedKeyword; - [ts.SyntaxKind.PublicKeyword]: TSESTree.TSPublicKeyword; - [ts.SyntaxKind.StaticKeyword]: TSESTree.TSStaticKeyword; - [ts.SyntaxKind.AsyncKeyword]: TSESTree.TSAsyncKeyword; - [ts.SyntaxKind.DeclareKeyword]: TSESTree.TSDeclareKeyword; -} +export type NonPatternGuard< + T extends TSNodeUsed, + KIND = T['kind'] +> = KIND extends ts.SyntaxKind.ArrayLiteralExpression + ? TSESTree.ArrayExpression + : KIND extends ts.SyntaxKind.BinaryExpression + ? + | TSESTree.SequenceExpression + | TSESTree.AssignmentExpression + | TSESTree.LogicalExpression + | TSESTree.BinaryExpression + : KIND extends ts.SyntaxKind.SpreadAssignment + ? TSESTree.SpreadElement + : KIND extends ts.SyntaxKind.SpreadElement + ? TSESTree.SpreadElement + : KIND extends ts.SyntaxKind.ObjectLiteralExpression + ? TSESTree.ObjectExpression + : never; -export interface NonPatternGuard extends BaseGuard { - [ts.SyntaxKind.ArrayLiteralExpression]: TSESTree.ArrayExpression; - [ts.SyntaxKind.BinaryExpression]: - | TSESTree.SequenceExpression - | TSESTree.AssignmentExpression - | TSESTree.LogicalExpression - | TSESTree.BinaryExpression; - [ts.SyntaxKind.SpreadAssignment]: TSESTree.SpreadElement; - [ts.SyntaxKind.SpreadElement]: TSESTree.SpreadElement; - [ts.SyntaxKind.ObjectLiteralExpression]: TSESTree.ObjectExpression; -} - -export interface PatternGuard extends BaseGuard { - [ts.SyntaxKind.ArrayLiteralExpression]: TSESTree.ArrayPattern; - [ts.SyntaxKind.BinaryExpression]: - | TSESTree.SequenceExpression - | TSESTree.AssignmentPattern; - [ts.SyntaxKind.SpreadAssignment]: TSESTree.RestElement; - [ts.SyntaxKind.SpreadElement]: TSESTree.RestElement; - [ts.SyntaxKind.ObjectLiteralExpression]: TSESTree.ObjectPattern; -} +export type PatternGuard< + T extends TSNodeUsed, + KIND = T['kind'] +> = KIND extends ts.SyntaxKind.ArrayLiteralExpression + ? TSESTree.ArrayPattern + : KIND extends ts.SyntaxKind.BinaryExpression + ? TSESTree.SequenceExpression | TSESTree.AssignmentPattern + : KIND extends ts.SyntaxKind.SpreadAssignment + ? TSESTree.RestElement + : KIND extends ts.SyntaxKind.SpreadElement + ? TSESTree.RestElement + : KIND extends ts.SyntaxKind.ObjectLiteralExpression + ? TSESTree.ObjectPattern + : never; // This is really slow - https://github.com/microsoft/TypeScript/pull/42556 // export type TSNodeBaseGuard = TSNodeUsed & { kind: keyof BaseGuard }; @@ -285,29 +419,54 @@ export type TSNodeConvertable = | ts.ClassElement | undefined; +export type TSNodeBaseGuardKind = TSNodeBaseGuard['kind']; +export type TSNodePatternKind = TSNodePattern['kind']; + export type TSESTreeToTSNodeGuardHelper< - T extends TSNodeSupported, - P extends boolean + T, + P extends true | false > = T extends TSNodeBaseGuard - ? BaseGuard[T['kind']] - : P extends true - ? PatternGuard[T['kind']] - : NonPatternGuard[T['kind']]; + ? BaseGuardType + : T extends TSNodePattern + ? P extends true + ? PatternGuard + : NonPatternGuard + : never; -export type TSESTreeToTSNodeGuard< +export type TSESTreeToTSNodeGuard = T extends + | ts.ParenthesizedExpression + | ts.ComputedPropertyName + ? TSESTreeToTSNodeGuardHelper + : T extends TSNodeBaseGuard + ? TSESTreeToTSNodeGuardHelper + : T extends + | ts.Statement + | ts.Declaration + | ts.Expression + | ts.TypeElement + | ts.TypeNode + ? any // TSESTreeToTSNodeGuardHelper, P> + : null; + +export type x = TSESTreeToTSNodeGuard; + +/*export type TSESTreeToTSNodeGuard< T extends TSNodeConvertable, P extends boolean -> = T extends ts.ParenthesizedExpression +> = any;*/ + +/* +export type TSESTreeToTSNodeGuard< + T extends TSNodeConvertable, + P extends true | false +> = T extends ts.ParenthesizedExpression | ts.ComputedPropertyName ? TSESTreeToTSNodeGuardHelper : T extends TSNodeSupported ? TSESTreeToTSNodeGuardHelper - : T extends ts.Node - ? // This is really slow - https://github.com/microsoft/TypeScript/pull/42556 - // TSESTreeToTSNodeGuardHelper, P> - // eslint-disable-next-line @typescript-eslint/no-explicit-any - any + : T extends ts.Statement | ts.Declaration | ts.Expression | ts.TypeElement + ? TSESTreeToTSNodeGuardHelper, P> : null; - +*/ // export type TypeTest = Exclude; // export type TypeTest2 = Exclude; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index dbd53f89723..d61883ade1c 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -100,12 +100,18 @@ export class Converter { * @param allowPattern flag to determine if patterns are allowed * @returns the converted ESTree node */ - private converter

( - node: TSNodeConvertable, + private converter( + node: T, parent?: ts.Node, inTypeMode?: boolean, allowPattern?: P, - ): TSESTreeToTSNodeGuard { + ): TSESTreeToTSNodeGuard; + private converter( + node: TSNodeConvertable, + parent?: ts.Node, + inTypeMode?: boolean, + allowPattern?: boolean, + ): TSESTree.Node | null { /** * Exit early for null and undefined */ @@ -122,10 +128,7 @@ export class Converter { this.allowPattern = allowPattern; } - const result = this.convertNode

( - node as TSNodeUsed, - parent ?? node.parent, - ); + const result = this.convertNode(node as TSNodeUsed, parent ?? node.parent); this.registerTSNodeInNodeMap(node, result); @@ -221,7 +224,7 @@ export class Converter { child: T, parent?: ts.Node, ): TSESTreeToTSNodeGuard { - return this.converter(child, parent, this.inTypeMode, true); + return this.converter(child, parent, this.inTypeMode, true) as any; } /** @@ -234,7 +237,7 @@ export class Converter { child: T, parent?: ts.Node, ): TSESTreeToTSNodeGuard { - return this.converter(child, parent, this.inTypeMode, false); + return this.converter(child, parent, this.inTypeMode, false) as any; } /** @@ -247,16 +250,20 @@ export class Converter { child: T, parent?: ts.Node, ): TSESTreeToTSNodeGuard { - return this.converter(child, parent, true, false); + return this.converter(child, parent, true, false) as any; } - private createNode( + private createNode( node: TSESTreeToTSNode, data: TSESTree.OptionalRangeAndLoc, - ): T { + ): T; + private createNode( + node: TSNodeUsed, + data: TSESTree.OptionalRangeAndLoc, + ): TSESTree.Node { const result = data; if (!result.range) { - result.range = getRange(node as TSNodeUsed, this.ast); + result.range = getRange(node, this.ast); } if (!result.loc) { result.loc = getLocFor(result.range[0], result.range[1], this.ast); @@ -265,7 +272,7 @@ export class Converter { if (result && this.options.shouldPreserveNodeMaps) { this.esTreeNodeToTSNodeMap.set(result, node); } - return result as T; + return result as TSESTree.Node; } private convertBindingNameWithTypeAnnotation( @@ -400,7 +407,7 @@ export class Converter { return []; } return parameters.map(param => { - const convertedParam = this.convertChild(param) as TSESTree.Parameter; + const convertedParam = this.convertChild(param); if (param.decorators?.length) { convertedParam.decorators = param.decorators.map(el => @@ -533,6 +540,14 @@ export class Converter { * @param parent * @returns the converted ESTree name object */ + private convertJSXTagName( + node: T, + parent: ts.Node, + ): T extends ts.JsxTagNamePropertyAccess + ? TSESTree.JSXMemberExpression + : T extends ts.ThisExpression | ts.Identifier + ? TSESTree.JSXIdentifier + : TSESTree.JSXMemberExpression | TSESTree.JSXIdentifier; private convertJSXTagName( node: ts.JsxTagNameExpression, parent: ts.Node, @@ -549,10 +564,7 @@ export class Converter { result = this.createNode(node, { type: AST_NODE_TYPES.JSXMemberExpression, object: this.convertJSXTagName(node.expression, parent), - property: this.convertJSXTagName( - node.name, - parent, - ) as TSESTree.JSXIdentifier, + property: this.convertJSXTagName(node.name, parent), }); break; @@ -656,10 +668,10 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - private convertNode

( + private convertNode( node: TSNodeUsed, parent: TSNode | ts.Node, - ): TSESTreeToTSNodeGuard { + ): TSESTree.Node | null { switch (node.kind) { case SyntaxKind.SourceFile: { return this.createNode(node, {