From b3e8ac9d9730fd24326581ed299bec6718491ae2 Mon Sep 17 00:00:00 2001 From: Armano Date: Mon, 28 Jan 2019 22:02:58 +0100 Subject: [PATCH 01/18] refactor(ts-estree): prototype of typed converter --- .../typescript-estree/src/ast-converter.ts | 27 +- packages/typescript-estree/src/ast-nodes.ts | 167 + .../typescript-estree/src/ast-tree-nodes.ts | 1258 ++++++ .../typescript-estree/src/convert-comments.ts | 53 +- packages/typescript-estree/src/convert.ts | 3864 +++++++++-------- .../src/estree/experimental.ts | 30 - .../src/estree/extensions.ts | 63 - packages/typescript-estree/src/estree/spec.ts | 985 ----- packages/typescript-estree/src/node-utils.ts | 91 +- .../typescript-estree/src/parser-options.ts | 35 + packages/typescript-estree/src/parser.ts | 17 +- .../src/temp-types-based-on-js-source.ts | 106 - .../typescript-estree/src/tsconfig-parser.ts | 2 +- .../typescript-estree/tests/lib/comments.ts | 2 +- .../typescript-estree/tests/lib/javascript.ts | 2 +- packages/typescript-estree/tests/lib/jsx.ts | 2 +- packages/typescript-estree/tests/lib/parse.ts | 2 +- .../tests/lib/semanticInfo.ts | 2 +- packages/typescript-estree/tests/lib/tsx.ts | 2 +- .../typescript-estree/tests/lib/typescript.ts | 2 +- .../typescript-estree/tools/test-utils.ts | 2 +- 21 files changed, 3494 insertions(+), 3220 deletions(-) create mode 100644 packages/typescript-estree/src/ast-nodes.ts create mode 100644 packages/typescript-estree/src/ast-tree-nodes.ts delete mode 100644 packages/typescript-estree/src/estree/experimental.ts delete mode 100644 packages/typescript-estree/src/estree/extensions.ts delete mode 100644 packages/typescript-estree/src/estree/spec.ts create mode 100644 packages/typescript-estree/src/parser-options.ts delete mode 100644 packages/typescript-estree/src/temp-types-based-on-js-source.ts diff --git a/packages/typescript-estree/src/ast-converter.ts b/packages/typescript-estree/src/ast-converter.ts index 13d2212c5c4f..131539a981b8 100644 --- a/packages/typescript-estree/src/ast-converter.ts +++ b/packages/typescript-estree/src/ast-converter.ts @@ -5,11 +5,11 @@ * @copyright jQuery Foundation and other contributors, https://jquery.org/ * MIT License */ -import convert, { getASTMaps, resetASTMaps, convertError } from './convert'; +import { convertError, Converter } from './convert'; import { convertComments } from './convert-comments'; import { convertTokens } from './node-utils'; import ts from 'typescript'; -import { Extra } from './temp-types-based-on-js-source'; +import { Extra } from './parser-options'; export default function astConverter( ast: ts.SourceFile, @@ -27,17 +27,14 @@ export default function astConverter( /** * Recursively convert the TypeScript AST into an ESTree-compatible AST */ - const estree: any = convert({ - node: ast, - parent: null, - ast, - additionalOptions: { - errorOnUnknownASTType: extra.errorOnUnknownASTType || false, - useJSXTextNode: extra.useJSXTextNode || false, - shouldProvideParserServices - } + const instance = new Converter(ast, { + errorOnUnknownASTType: extra.errorOnUnknownASTType || false, + useJSXTextNode: extra.useJSXTextNode || false, + shouldProvideParserServices }); + const estree = instance.convertProgram(); + /** * Optionally convert and include all tokens in the AST */ @@ -52,11 +49,9 @@ export default function astConverter( estree.comments = convertComments(ast, extra.code); } - let astMaps = undefined; - if (shouldProvideParserServices) { - astMaps = getASTMaps(); - resetASTMaps(); - } + const astMaps = shouldProvideParserServices + ? instance.getASTMaps() + : undefined; return { estree, astMaps }; } diff --git a/packages/typescript-estree/src/ast-nodes.ts b/packages/typescript-estree/src/ast-nodes.ts new file mode 100644 index 000000000000..d17de7363e54 --- /dev/null +++ b/packages/typescript-estree/src/ast-nodes.ts @@ -0,0 +1,167 @@ +import * as es from './ast-tree-nodes'; + +export type ASTTreeNodes = + | es.ArrayExpression + | es.ArrayPattern + | es.ArrowFunctionExpression + | es.AssignmentExpression + | es.AssignmentPattern + | es.AwaitExpression + | es.BigIntLiteral + | es.BinaryExpression + | es.BlockStatement + | es.BreakStatement + | es.CallExpression + | es.CatchClause + | es.ClassBody + | es.ClassDeclaration + | es.ClassExpression + | es.ClassProperty + | es.ConditionalExpression + | es.ContinueStatement + | es.DebuggerStatement + | es.Decorator + | es.DoWhileStatement + | es.EmptyStatement + | es.ExportAllDeclaration + | es.ExportDefaultDeclaration + | es.ExportNamedDeclaration + | es.ExportSpecifier + | es.ExpressionStatement + | es.ForInStatement + | es.ForOfStatement + | es.ForStatement + | es.FunctionDeclaration + | es.FunctionExpression + | es.Identifier + | es.IfStatement + | es.Import + | es.ImportDeclaration + | es.ImportDefaultSpecifier + | es.ImportNamespaceSpecifier + | es.ImportSpecifier + | es.JSXAttribute + | es.JSXClosingElement + | es.JSXClosingFragment + | es.JSXElement + | es.JSXEmptyExpression + | es.JSXExpressionContainer + | es.JSXFragment + | es.JSXIdentifier + | es.JSXMemberExpression + // | es.JSXNamespacedName // https://github.com/Microsoft/TypeScript/issues/7411 + | es.JSXOpeningElement + | es.JSXOpeningFragment + | es.JSXSpreadAttribute + | es.JSXSpreadChild + | es.JSXText + | es.LabeledStatement + | es.Literal + | es.LogicalExpression + | es.MemberExpression + | es.MetaProperty + | es.MethodDefinition + | es.NewExpression + | es.ObjectExpression + | es.ObjectPattern + | es.Program + | es.Property + | es.RestElement + | es.ReturnStatement + | es.SequenceExpression + | es.SpreadElement + | es.Super + | es.SwitchCase + | es.SwitchStatement + | es.TaggedTemplateExpression + | es.TemplateElement + | es.TemplateLiteral + | es.ThisExpression + | es.ThrowStatement + | es.TryStatement + | es.UnaryExpression + | es.UpdateExpression + | es.VariableDeclaration + | es.VariableDeclarator + | es.WhileStatement + | es.WithStatement + | es.YieldExpression + | es.TSAbstractClassProperty + // | es.TSAbstractKeyword + | es.TSAbstractMethodDefinition + | es.TSAnyKeyword + | es.TSArrayType + | es.TSAsExpression + | es.TSAsyncKeyword + | es.TSBooleanKeyword + | es.TSBigIntKeyword + | es.TSConditionalType + | es.TSConstructorType + | es.TSCallSignatureDeclaration + | es.TSClassImplements + | es.TSConstructSignatureDeclaration + // | es.TSDeclareKeyword + | es.TSDeclareFunction + | es.TSEnumDeclaration + | es.TSEnumMember + | es.TSExportAssignment + // | es.TSExportKeyword + | es.TSExternalModuleReference + | es.TSImportType + | es.TSInferType + | es.TSLiteralType + | es.TSIndexedAccessType + | es.TSIndexSignature + | es.TSInterfaceBody + | es.TSInterfaceDeclaration + | es.TSInterfaceHeritage + | es.TSImportEqualsDeclaration + | es.TSFunctionType + | es.TSMethodSignature + | es.TSModuleBlock + | es.TSModuleDeclaration + | es.TSNamespaceExportDeclaration + | es.TSNonNullExpression + | es.TSNeverKeyword + | es.TSNullKeyword + | es.TSNumberKeyword + | es.TSMappedType + | es.TSObjectKeyword + | es.TSParameterProperty + | es.TSPrivateKeyword + | es.TSPropertySignature + | es.TSProtectedKeyword + | es.TSPublicKeyword + | es.TSQualifiedName + // | es.TSQuestionToken + // | es.TSReadonlyKeyword + | es.TSRestType + | es.TSStaticKeyword + | es.TSStringKeyword + | es.TSSymbolKeyword + | es.TSThisType + | es.TSTypeAnnotation + | es.TSTypeAliasDeclaration + | es.TSTypeAssertion + | es.TSTypeLiteral + | es.TSTypeOperator + | es.TSTypeParameter + | es.TSTypeParameterDeclaration + | es.TSTypeParameterInstantiation + | es.TSTypePredicate + | es.TSTypeReference + | es.TSTypeQuery + | es.TSIntersectionType + | es.TSTupleType + | es.TSOptionalType + | es.TSParenthesizedType + | es.TSUnionType + | es.TSUndefinedKeyword + | es.TSUnknownKeyword + | es.TSVoidKeyword + // abstract types + | es.FunctionDeclarationLike + | es.ClassPropertyLikeNode + | es.ClassLikeNode + | es.TSFunctionDeclarationLike + | es.TSExpressionWithTypeArgumentsLike; diff --git a/packages/typescript-estree/src/ast-tree-nodes.ts b/packages/typescript-estree/src/ast-tree-nodes.ts new file mode 100644 index 000000000000..6259afaebb4e --- /dev/null +++ b/packages/typescript-estree/src/ast-tree-nodes.ts @@ -0,0 +1,1258 @@ +/** + * @fileoverview Definition of AST structure. + * @author Armano + */ +/* eslint-disable @typescript-eslint/array-type */ + +import { AST_NODE_TYPES } from './ast-node-types'; + +export interface Position { + line: number; + column: number; +} + +export interface SourceLocation { + source?: string | null; + start: Position; + end: Position; +} + +/** + * TODO: loc and range should be optional, but its not supported yet by covert + */ +export interface BaseNode { + type: string; + loc?: SourceLocation | null; + range?: [number, number]; +} + +export interface Token extends BaseNode { + type: AST_NODE_TYPES; + value: string; + regex?: { + pattern: string; + flags: string; + }; + object?: any; + property?: any; + name?: any; +} + +export interface Comment extends BaseNode { + type: 'Line' | 'Block'; + value: string; +} + +export interface ArrayExpression extends BaseNode { + type: AST_NODE_TYPES.ArrayExpression; + elements: Array; +} + +export interface ArrayPattern extends BaseNode { + type: AST_NODE_TYPES.ArrayPattern; + optional?: boolean; + typeAnnotation?: TSTypeAnnotation; + elements: Array< + | ArrayPattern + | AssignmentPattern + | Identifier + | MemberExpression + | ObjectPattern + | RestElement + | null + >; +} + +export interface ArrowFunctionExpression extends BaseNode { + type: AST_NODE_TYPES.ArrowFunctionExpression; + generator: boolean; + expression: boolean; + async: boolean; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array< + | ArrayPattern + | AssignmentPattern + | Identifier + | ObjectPattern + | RestElement + | TSParameterProperty + >; + id: null; + body: BlockStatement | Expressions | Identifier | JSXElement | Literals; +} + +export interface AssignmentExpression extends BaseNode { + type: AST_NODE_TYPES.AssignmentExpression; + operator: + | '%=' + | '&=' + | '**=' + | '*=' + | '+=' + | '-=' + | '/=' + | '<<=' + | '=' + | '>>=' + | '>>>=' + | '^=' + | '|='; + right: Expressions | Identifier | JSXElement | Literals; + left: ArrayPattern | Expressions | Identifier | Literal | ObjectPattern; +} + +export interface AssignmentPattern extends BaseNode { + type: AST_NODE_TYPES.AssignmentPattern; + right: Expressions | Identifier | Literals; + left: ArrayPattern | Identifier | ObjectPattern; +} + +export interface AwaitExpression extends BaseNode { + type: AST_NODE_TYPES.AwaitExpression; + argument: Expressions | Identifier | Literal; +} + +export interface BigIntLiteral extends BaseNode { + type: AST_NODE_TYPES.BigIntLiteral; + value: string; + raw: string; +} + +export interface BinaryExpression extends BaseNode { + type: AST_NODE_TYPES.BinaryExpression; + operator: + | '!=' + | '!==' + | '%' + | '&' + | '*' + | '**' + | '+' + | '-' + | '/' + | '<' + | '<<' + | '<=' + | '==' + | '===' + | '>' + | '>=' + | '>>' + | '>>>' + | '^' + | 'in' + | 'instanceof' + | '|'; + right: Expressions | Identifier | Literals; + left: Expressions | Identifier | Literals; +} + +export interface BlockStatement extends BaseNode { + type: AST_NODE_TYPES.BlockStatement; + body: Array; +} + +export interface BreakStatement extends BaseNode { + type: AST_NODE_TYPES.BreakStatement; + label: null | Identifier; +} + +export interface CallExpression extends BaseNode { + type: AST_NODE_TYPES.CallExpression; + typeParameters?: TSTypeParameterInstantiation; + callee: Expressions | Identifier | Import | Literals | Super; + arguments: Array; +} + +export interface CatchClause extends BaseNode { + type: AST_NODE_TYPES.CatchClause; + param: null | ArrayPattern | Identifier | ObjectPattern; + body: BlockStatement; +} + +export interface ClassBody extends BaseNode { + type: AST_NODE_TYPES.ClassBody; + body: Array< + | ClassProperty + | MethodDefinition + | TSAbstractClassProperty + | TSIndexSignature + >; +} + +export interface ClassLikeNode extends BaseNode { + type: AST_NODE_TYPES.ClassDeclaration | AST_NODE_TYPES.ClassExpression; + id: null | Identifier; + declare?: boolean; + abstract?: boolean; + body: ClassBody; + decorators?: Array; + superClass: null | Expressions | Identifier | Literal; + superTypeParameters?: TSTypeParameterInstantiation; + typeParameters?: TSTypeParameterDeclaration; + implements?: Array; +} + +export interface ClassDeclaration extends ClassLikeNode { + type: AST_NODE_TYPES.ClassDeclaration; +} + +export interface ClassExpression extends ClassLikeNode { + type: AST_NODE_TYPES.ClassExpression; +} + +export interface ClassPropertyLikeNode extends BaseNode { + type: AST_NODE_TYPES.ClassProperty | AST_NODE_TYPES.TSAbstractClassProperty; + static: boolean; + readonly?: boolean; + optional?: boolean; + definite?: boolean; + computed: boolean; + accessibility?: 'private' | 'protected' | 'public'; + value: null | Expressions | Identifier | Literal; + typeAnnotation?: TSTypeAnnotation; + key: Expressions | Identifier | Literals; + decorators?: Array; +} + +export interface ClassProperty extends ClassPropertyLikeNode { + type: AST_NODE_TYPES.ClassProperty; +} + +export interface TSAbstractClassProperty extends ClassPropertyLikeNode { + type: AST_NODE_TYPES.TSAbstractClassProperty; +} + +export interface ConditionalExpression extends BaseNode { + type: AST_NODE_TYPES.ConditionalExpression; + test: Expressions | Identifier | Literals; + consequent: Expressions | Identifier | JSXElement | Literals; + alternate: Expressions | Identifier | JSXElement | Literals; +} + +export interface ContinueStatement extends BaseNode { + type: AST_NODE_TYPES.ContinueStatement; + label: null | Identifier; +} + +export interface DebuggerStatement extends BaseNode { + type: AST_NODE_TYPES.DebuggerStatement; +} + +export interface Decorator extends BaseNode { + type: AST_NODE_TYPES.Decorator; + expression: Expressions | Identifier; +} + +export interface DoWhileStatement extends BaseNode { + type: AST_NODE_TYPES.DoWhileStatement; + test: Expressions | Identifier | Literal; + body: BlockStatement | VariableDeclaration; +} + +export interface EmptyStatement extends BaseNode { + type: AST_NODE_TYPES.EmptyStatement; +} + +export interface ExportAllDeclaration extends BaseNode { + type: AST_NODE_TYPES.ExportAllDeclaration; + source: Identifier | Literal; +} + +export interface ExportDefaultDeclaration extends BaseNode { + type: AST_NODE_TYPES.ExportDefaultDeclaration; + declaration: + | null + | Declarations + | Expressions + | Identifier + | JSXElement + | Literal; +} + +export interface ExportNamedDeclaration extends BaseNode { + type: AST_NODE_TYPES.ExportNamedDeclaration; + specifiers: Array; + source: null | Literal; + declaration: + | null + | Declarations + | Expressions + | Identifier + | JSXElement + | Literal; +} + +export interface ExportSpecifier extends BaseNode { + type: AST_NODE_TYPES.ExportSpecifier; + local: Identifier; + exported: Identifier; +} + +export interface ExpressionStatement extends BaseNode { + type: AST_NODE_TYPES.ExpressionStatement; + directive?: string; + expression: Expressions | Identifier | JSXElement | JSXFragment | Literals; +} + +export interface ForInStatement extends BaseNode { + type: AST_NODE_TYPES.ForInStatement; + right: Expressions | Identifier | Literal; + left: + | AssignmentPattern + | Expressions + | Identifier + | ObjectPattern + | VariableDeclaration; + body: Statements | VariableDeclaration; +} + +export interface ForOfStatement extends BaseNode { + type: AST_NODE_TYPES.ForOfStatement; + await: boolean; + right: Expressions | Identifier | Literal; + left: + | ArrayPattern + | Expressions + | Identifier + | ObjectPattern + | VariableDeclaration; + body: Statements; +} + +export interface ForStatement extends BaseNode { + type: AST_NODE_TYPES.ForStatement; + update: null | Expressions | Identifier; + test: null | Expressions | Identifier | Literal; + init: null | Expressions | Identifier | VariableDeclaration; + body: Statements | VariableDeclaration; +} + +export interface FunctionDeclarationLike extends BaseNode { + generator: boolean; + expression: boolean; + async: boolean; + declare?: boolean; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array< + | ArrayPattern + | AssignmentPattern + | Identifier + | ObjectPattern + | RestElement + | TSParameterProperty + >; + id: null | Identifier; + body?: BlockStatement; +} + +export interface FunctionDeclaration extends FunctionDeclarationLike { + type: AST_NODE_TYPES.FunctionDeclaration; + body: BlockStatement; +} + +export interface FunctionExpression extends BaseNode { + type: AST_NODE_TYPES.FunctionExpression; + generator: boolean; + expression: boolean; + async: boolean; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array< + | ArrayPattern + | AssignmentPattern + | Identifier + | ObjectPattern + | RestElement + | TSParameterProperty + >; + id: null | Identifier; + body: null | BlockStatement; +} + +export interface Identifier extends BaseNode { + type: AST_NODE_TYPES.Identifier; + optional?: boolean; + name: string; + typeAnnotation?: TSTypeAnnotation; + decorators?: Array; +} + +export interface IfStatement extends BaseNode { + type: AST_NODE_TYPES.IfStatement; + test: Expressions | Identifier | Literal; + consequent: Statements | VariableDeclaration; + alternate: null | Statements | VariableDeclaration; +} + +export interface Import extends BaseNode { + type: AST_NODE_TYPES.Import; +} + +export interface ImportDeclaration extends BaseNode { + type: AST_NODE_TYPES.ImportDeclaration; + specifiers: Array< + ImportDefaultSpecifier | ImportNamespaceSpecifier | ImportSpecifier + >; + source: Literal; +} + +export interface ImportDefaultSpecifier extends BaseNode { + type: AST_NODE_TYPES.ImportDefaultSpecifier; + local: Identifier; +} + +export interface ImportNamespaceSpecifier extends BaseNode { + type: AST_NODE_TYPES.ImportNamespaceSpecifier; + local: Identifier; +} + +export interface ImportSpecifier extends BaseNode { + type: AST_NODE_TYPES.ImportSpecifier; + local: Identifier; + imported: Identifier; +} + +export interface JSXAttribute extends BaseNode { + type: AST_NODE_TYPES.JSXAttribute; + value: null | JSXExpressionContainer | Literal; + name: JSXIdentifier; +} + +export interface JSXClosingElement extends BaseNode { + type: AST_NODE_TYPES.JSXClosingElement; + name: JSXIdentifier | JSXMemberExpression; +} + +export interface JSXClosingFragment extends BaseNode { + type: AST_NODE_TYPES.JSXClosingFragment; +} + +export interface JSXElement extends BaseNode { + type: AST_NODE_TYPES.JSXElement; + openingElement: JSXOpeningElement; + closingElement: null | JSXClosingElement; + children: Array< + JSXElement | JSXExpressionContainer | JSXFragment | JSXSpreadChild | JSXText + >; +} + +export interface JSXEmptyExpression extends BaseNode { + type: AST_NODE_TYPES.JSXEmptyExpression; +} + +export interface JSXExpressionContainer extends BaseNode { + type: AST_NODE_TYPES.JSXExpressionContainer; + expression: + | Expressions + | Identifier + | JSXElement + | JSXEmptyExpression + | Literal; +} + +export interface JSXFragment extends BaseNode { + type: AST_NODE_TYPES.JSXFragment; + openingFragment: JSXOpeningFragment; + closingFragment: JSXClosingFragment; + children: Array; +} + +export interface JSXIdentifier extends BaseNode { + type: AST_NODE_TYPES.JSXIdentifier; + name: string; +} + +export interface JSXMemberExpression extends BaseNode { + type: AST_NODE_TYPES.JSXMemberExpression; + property: JSXIdentifier; + object: JSXIdentifier | JSXMemberExpression | MemberExpression; +} + +export interface JSXOpeningElement extends BaseNode { + type: AST_NODE_TYPES.JSXOpeningElement; + selfClosing: boolean; + typeParameters?: TSTypeParameterInstantiation; + name: JSXIdentifier | JSXMemberExpression; + attributes: Array; +} + +export interface JSXOpeningFragment extends BaseNode { + type: AST_NODE_TYPES.JSXOpeningFragment; +} + +export interface JSXSpreadAttribute extends BaseNode { + type: AST_NODE_TYPES.JSXSpreadAttribute; + argument: Expressions | Identifier; +} + +export interface JSXSpreadChild extends BaseNode { + type: AST_NODE_TYPES.JSXSpreadChild; + expression: Expressions | JSXElement; +} + +export interface JSXText extends BaseNode { + type: AST_NODE_TYPES.JSXText; + value: string; + raw: string; +} + +export interface LabeledStatement extends BaseNode { + type: AST_NODE_TYPES.LabeledStatement; + label: Identifier; + body: Statements | VariableDeclaration; +} + +export interface Literal extends BaseNode { + type: AST_NODE_TYPES.Literal; + value: boolean | null | number | string | RegExp; + raw: string; + regex?: { + pattern: string; + flags: string; + }; +} + +export interface LogicalExpression extends BaseNode { + type: AST_NODE_TYPES.LogicalExpression; + operator: '&&' | '||'; + right: Expressions | Identifier | Literal; + left: Expressions | Identifier | Literal; +} + +export interface MemberExpression extends BaseNode { + type: AST_NODE_TYPES.MemberExpression; + computed?: boolean; + property: Expressions | Identifier | Literals; + object: Expressions | Identifier | Literals | Super; +} + +export interface MetaProperty extends BaseNode { + type: AST_NODE_TYPES.MetaProperty; + property: Identifier; + meta: Identifier; +} + +export interface MethodDefinition extends BaseNode { + type: + | AST_NODE_TYPES.MethodDefinition + | AST_NODE_TYPES.TSAbstractMethodDefinition; + static: boolean; + kind: 'constructor' | 'get' | 'method' | 'set'; + computed: boolean; + accessibility?: 'private' | 'protected' | 'public'; + value: FunctionExpression; + key: Expressions | Identifier | Literals; + decorators?: Array; +} + +export interface TSAbstractMethodDefinition extends MethodDefinition { + type: AST_NODE_TYPES.TSAbstractMethodDefinition; +} + +export interface NewExpression extends BaseNode { + type: AST_NODE_TYPES.NewExpression; + typeParameters?: TSTypeParameterInstantiation; + callee: Expressions | Identifier | Super | TemplateLiteral; + arguments: Array; +} + +export interface ObjectExpression extends BaseNode { + type: AST_NODE_TYPES.ObjectExpression; + properties: Array; +} + +export interface ObjectPattern extends BaseNode { + type: AST_NODE_TYPES.ObjectPattern; + optional?: boolean; + typeAnnotation?: TSTypeAnnotation; + properties: Array; +} + +export interface Program extends BaseNode { + type: AST_NODE_TYPES.Program; + sourceType: 'module' | 'script'; + body: Array; + tokens?: Token[]; + comments?: Comment[]; +} + +export interface Property extends BaseNode { + type: AST_NODE_TYPES.Property; + shorthand: boolean; + method: boolean; + kind: 'get' | 'init' | 'set'; + computed: boolean; + value: + | ArrayPattern + | AssignmentPattern + | Expressions + | Identifier + | Literals + | ObjectPattern; + typeParameters?: TSTypeParameterDeclaration; + key: Expressions | Identifier | Literals; +} + +export interface RestElement extends BaseNode { + type: AST_NODE_TYPES.RestElement; + optional?: boolean; + typeAnnotation?: TSTypeAnnotation; + decorators?: Array; + argument: ArrayPattern | AssignmentPattern | Identifier | ObjectPattern; + value?: + | ArrayPattern + | AssignmentPattern + | Expressions + | Identifier + | Literals + | ObjectPattern; +} + +export interface ReturnStatement extends BaseNode { + type: AST_NODE_TYPES.ReturnStatement; + argument: + | null + | Expressions + | Identifier + | JSXElement + | JSXFragment + | Literals; +} + +export interface SequenceExpression extends BaseNode { + type: AST_NODE_TYPES.SequenceExpression; + expressions: Array; +} + +export interface SpreadElement extends BaseNode { + type: AST_NODE_TYPES.SpreadElement; + argument: Expressions | Identifier; +} + +export interface Super extends BaseNode { + type: AST_NODE_TYPES.Super; +} + +export interface SwitchCase extends BaseNode { + type: AST_NODE_TYPES.SwitchCase; + test: null | Expressions | Identifier | Literals; + consequent: Array; +} + +export interface SwitchStatement extends BaseNode { + type: AST_NODE_TYPES.SwitchStatement; + discriminant: Expressions | Identifier | Literals; + cases: Array; +} + +export interface TaggedTemplateExpression extends BaseNode { + type: AST_NODE_TYPES.TaggedTemplateExpression; + typeParameters?: TSTypeParameterInstantiation; + tag: Identifier | MemberExpression | TemplateLiteral; + quasi: TemplateLiteral; +} + +export interface TemplateElement extends BaseNode { + type: AST_NODE_TYPES.TemplateElement; + tail: boolean; + value: { + raw: string; + cooked: string; + }; +} + +export interface TemplateLiteral extends BaseNode { + type: AST_NODE_TYPES.TemplateLiteral; + quasis: Array; + expressions: Array; +} + +export interface ThisExpression extends BaseNode { + type: AST_NODE_TYPES.ThisExpression; +} + +export interface ThrowStatement extends BaseNode { + type: AST_NODE_TYPES.ThrowStatement; + argument: null | Expressions | Identifier | Literal; +} + +export interface TryStatement extends BaseNode { + type: AST_NODE_TYPES.TryStatement; + handler: null | CatchClause; + finalizer: null | BlockStatement; + block: BlockStatement; +} + +export interface UnaryExpression extends BaseNode { + type: AST_NODE_TYPES.UnaryExpression; + prefix: boolean; + operator: '!' | '+' | '-' | 'delete' | 'typeof' | 'void' | '~'; + argument: Expressions | Identifier | Literals; +} + +export interface UpdateExpression extends BaseNode { + type: AST_NODE_TYPES.UpdateExpression; + prefix: boolean; + operator: '++' | '--'; + argument: Expressions | Identifier | Literal; +} + +export interface VariableDeclaration extends BaseNode { + type: AST_NODE_TYPES.VariableDeclaration; + kind: 'const' | 'let' | 'var'; + declare?: boolean; + declarations: Array; +} + +export interface VariableDeclarator extends BaseNode { + type: AST_NODE_TYPES.VariableDeclarator; + definite?: boolean; + init: null | Expressions | Identifier | JSXElement | Literals; + id: ArrayPattern | Identifier | ObjectPattern; +} + +export interface WhileStatement extends BaseNode { + type: AST_NODE_TYPES.WhileStatement; + test: Expressions | Identifier | Literals; + body: Statements | VariableDeclaration; +} + +export interface WithStatement extends BaseNode { + type: AST_NODE_TYPES.WithStatement; + object: Expressions | Identifier | Literal; + body: Statements | VariableDeclaration; +} + +export interface YieldExpression extends BaseNode { + type: AST_NODE_TYPES.YieldExpression; + delegate: boolean; + argument: null | Expressions | Identifier | Literals; +} + +export interface TSArrayType extends BaseNode { + type: AST_NODE_TYPES.TSArrayType; + elementType: TSTypeKeywords | TSTypeOperators; +} + +export interface TSAsExpression extends BaseNode { + type: AST_NODE_TYPES.TSAsExpression; + typeAnnotation: TSLiteralType | TSTypeKeywords | TSTypeOperators; + expression: Expressions | Identifier | JSXElement | Literals; +} + +export interface TSExpressionWithTypeArgumentsLike extends BaseNode { + type: AST_NODE_TYPES.TSInterfaceHeritage | AST_NODE_TYPES.TSClassImplements; + typeParameters?: TSTypeParameterInstantiation; + expression: Identifier | MemberExpression | Expressions; +} + +export interface TSClassImplements extends TSExpressionWithTypeArgumentsLike { + type: AST_NODE_TYPES.TSClassImplements; +} + +export interface TSInterfaceHeritage extends TSExpressionWithTypeArgumentsLike { + type: AST_NODE_TYPES.TSInterfaceHeritage; +} + +export interface TSConditionalType extends BaseNode { + type: AST_NODE_TYPES.TSConditionalType; + trueType: TSLiteralType | TSTypeKeywords | TSTypeOperators; + falseType: TSLiteralType | TSTypeKeywords | TSTypeOperators; + extendsType: TSLiteralType | TSTypeKeywords | TSTypeOperators; + checkType: TSTypeKeywords | TSTypeOperators; +} + +export interface TSFunctionDeclarationLike extends BaseNode { + type: + | AST_NODE_TYPES.TSConstructSignatureDeclaration + | AST_NODE_TYPES.TSConstructorType + | AST_NODE_TYPES.TSFunctionType + | AST_NODE_TYPES.TSCallSignatureDeclaration; + params: Array< + | Identifier + | ObjectPattern + | RestElement + | TSParameterProperty + | AssignmentPattern + | ArrayPattern + >; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; +} + +export interface TSCallSignatureDeclaration extends TSFunctionDeclarationLike { + type: AST_NODE_TYPES.TSCallSignatureDeclaration; +} + +export interface TSConstructSignatureDeclaration + extends TSFunctionDeclarationLike { + type: AST_NODE_TYPES.TSConstructSignatureDeclaration; +} + +export interface TSConstructorType extends TSFunctionDeclarationLike { + type: AST_NODE_TYPES.TSConstructorType; +} + +export interface TSFunctionType extends TSFunctionDeclarationLike { + type: AST_NODE_TYPES.TSFunctionType; +} + +export interface TSDeclareFunction extends FunctionDeclarationLike { + type: AST_NODE_TYPES.TSDeclareFunction; + body?: BlockStatement; +} + +export interface TSEnumDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSEnumDeclaration; + declare?: boolean; + const?: boolean; + modifiers?: Array< + TSAsyncKeyword | TSPrivateKeyword | TSPublicKeyword | TSStaticKeyword + >; + members: Array; + id: Identifier; + decorators?: Array; +} + +export interface TSEnumMember extends BaseNode { + type: AST_NODE_TYPES.TSEnumMember; + initializer?: Expressions | Identifier | Literal; + id: Identifier | Literal; +} + +export interface TSExportAssignment extends BaseNode { + type: AST_NODE_TYPES.TSExportAssignment; + expression: Expressions | Identifier | Literal; +} + +export interface TSExternalModuleReference extends BaseNode { + type: AST_NODE_TYPES.TSExternalModuleReference; + expression: Identifier | Literal; +} + +export interface TSImportEqualsDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSImportEqualsDeclaration; + isExport: boolean; + moduleReference: Identifier | TSExternalModuleReference | TSQualifiedName; + id: Identifier; +} + +export interface TSImportType extends BaseNode { + type: AST_NODE_TYPES.TSImportType; + isTypeOf: boolean; + typeParameters: null | TSTypeParameterInstantiation; + qualifier: null | Identifier; + parameter: TSLiteralType; +} + +export interface TSIndexSignature extends BaseNode { + type: AST_NODE_TYPES.TSIndexSignature; + static?: boolean; + readonly?: boolean; + export?: boolean; + accessibility?: 'private' | 'protected' | 'public'; + typeAnnotation?: TSTypeAnnotation; + parameters: Array< + AssignmentPattern | Identifier | RestElement | TSParameterProperty + >; +} + +export interface TSIndexedAccessType extends BaseNode { + type: AST_NODE_TYPES.TSIndexedAccessType; + objectType: TSTypeOperators | TSAnyKeyword; + indexType: TSLiteralType | TSTypeOperators | TSNeverKeyword; +} + +export interface TSInferType extends BaseNode { + type: AST_NODE_TYPES.TSInferType; + typeParameter: TSTypeParameter; +} + +export interface TSInterfaceBody extends BaseNode { + type: AST_NODE_TYPES.TSInterfaceBody; + body: Array; +} + +export interface TSInterfaceDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSInterfaceDeclaration; + declare?: boolean; + abstract?: boolean; + typeParameters?: TSTypeParameterDeclaration; + implements?: Array; + id: Identifier; + extends?: Array; + decorators?: Array; + body: TSInterfaceBody; +} + +export interface TSIntersectionType extends BaseNode { + type: AST_NODE_TYPES.TSIntersectionType; + types: Array; +} + +export interface TSLiteralType extends BaseNode { + type: AST_NODE_TYPES.TSLiteralType; + literal: Literals | UnaryExpression; +} + +export interface TSMappedType extends BaseNode { + type: AST_NODE_TYPES.TSMappedType; + readonly?: boolean | '+' | '-'; + optional?: boolean | '+' | '-'; + typeParameter: TSTypeParameter; + typeAnnotation?: TSLiteralType | TSTypeKeywords | TSTypeOperators; +} + +export interface TSMethodSignature extends BaseNode { + type: AST_NODE_TYPES.TSMethodSignature; + optional?: boolean; + computed: boolean; + readonly?: boolean; + export?: boolean; + static?: boolean; + accessibility?: 'private' | 'protected' | 'public'; + typeParameters?: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + params: Array< + | ArrayPattern + | AssignmentPattern + | Identifier + | ObjectPattern + | RestElement + | TSParameterProperty + >; + key: Expressions | Identifier | Literal; +} + +export interface TSModuleBlock extends BaseNode { + type: AST_NODE_TYPES.TSModuleBlock; + body: Array; +} + +export interface TSModuleDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSModuleDeclaration; + global?: boolean; + declare?: boolean; + modifiers?: Array< + | TSAsyncKeyword + | TSPrivateKeyword + | TSProtectedKeyword + | TSPublicKeyword + | TSStaticKeyword + >; + id: Identifier | Literal; + body?: TSModuleBlock | TSModuleDeclaration; +} + +export interface TSNamespaceExportDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSNamespaceExportDeclaration; + id: Identifier; +} + +export interface TSNonNullExpression extends BaseNode { + type: AST_NODE_TYPES.TSNonNullExpression; + expression: Expressions | Identifier | Literal; +} + +export interface TSOptionalType extends BaseNode { + type: AST_NODE_TYPES.TSOptionalType; + typeAnnotation: TSStringKeyword; +} + +export interface TSParameterProperty extends BaseNode { + type: AST_NODE_TYPES.TSParameterProperty; + static?: boolean; + readonly?: boolean; + export?: boolean; + accessibility?: 'private' | 'protected' | 'public'; + parameter: + | ArrayPattern + | AssignmentPattern + | Identifier + | ObjectPattern + | RestElement; + decorators?: Array; +} + +export interface TSParenthesizedType extends BaseNode { + type: AST_NODE_TYPES.TSParenthesizedType; + typeAnnotation: TSLiteralType | TSTypeOperators; +} + +export interface TSPropertySignature extends BaseNode { + type: AST_NODE_TYPES.TSPropertySignature; + readonly?: boolean; + optional?: boolean; + static?: boolean; + export?: boolean; + computed: boolean; + accessibility?: 'private' | 'protected' | 'public'; + typeAnnotation?: TSTypeAnnotation; + key: Expressions | Identifier | Literal; + initializer?: Literal; +} + +export interface TSQualifiedName extends BaseNode { + type: AST_NODE_TYPES.TSQualifiedName; + right: Identifier; + left: Identifier | TSQualifiedName; +} + +export interface TSRestType extends BaseNode { + type: AST_NODE_TYPES.TSRestType; + typeAnnotation: TSTypeOperators; +} + +export interface TSThisType extends BaseNode { + type: AST_NODE_TYPES.TSThisType; +} + +export interface TSTupleType extends BaseNode { + type: AST_NODE_TYPES.TSTupleType; + elementTypes: Array; +} + +export interface TSTypeAliasDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSTypeAliasDeclaration; + declare?: boolean; + typeParameters?: TSTypeParameterDeclaration; + typeAnnotation: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; + id: Identifier; +} + +export interface TSTypeAnnotation extends BaseNode { + type: AST_NODE_TYPES.TSTypeAnnotation; + typeAnnotation: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; +} + +export interface TSTypeAssertion extends BaseNode { + type: AST_NODE_TYPES.TSTypeAssertion; + typeAnnotation: TSTypeKeywords | TSTypeOperators; + expression: Expressions | Identifier | Literals; +} + +export interface TSTypeLiteral extends BaseNode { + type: AST_NODE_TYPES.TSTypeLiteral; + members: Array; +} + +export interface TSTypeOperator extends BaseNode { + type: AST_NODE_TYPES.TSTypeOperator; + operator: 'keyof' | 'unique'; + typeAnnotation: TSTypeKeywords | TSTypeOperators; +} + +export interface TSTypeParameter extends BaseNode { + type: AST_NODE_TYPES.TSTypeParameter; + name: Identifier; + default?: TSLiteralType | TSTypeKeywords | TSTypeOperators; + constraint?: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; +} + +export interface TSTypeParameterDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSTypeParameterDeclaration; + params: Array; +} + +export interface TSTypeParameterInstantiation extends BaseNode { + type: AST_NODE_TYPES.TSTypeParameterInstantiation; + params: Array; +} + +export interface TSTypePredicate extends BaseNode { + type: AST_NODE_TYPES.TSTypePredicate; + typeAnnotation: TSTypeAnnotation; + parameterName: Identifier | TSThisType; +} + +export interface TSTypeQuery extends BaseNode { + type: AST_NODE_TYPES.TSTypeQuery; + exprName: Identifier | TSQualifiedName; +} + +export interface TSTypeReference extends BaseNode { + type: AST_NODE_TYPES.TSTypeReference; + typeParameters?: TSTypeParameterInstantiation; + typeName: Identifier | TSQualifiedName; +} + +export interface TSUnionType extends BaseNode { + type: AST_NODE_TYPES.TSUnionType; + types: Array; +} + +export interface TSAnyKeyword extends BaseNode { + type: AST_NODE_TYPES.TSAnyKeyword; +} + +export interface TSAsyncKeyword extends BaseNode { + type: AST_NODE_TYPES.TSAsyncKeyword; +} + +export interface TSBigIntKeyword extends BaseNode { + type: AST_NODE_TYPES.TSBigIntKeyword; +} + +export interface TSBooleanKeyword extends BaseNode { + type: AST_NODE_TYPES.TSBooleanKeyword; +} + +export interface TSNeverKeyword extends BaseNode { + type: AST_NODE_TYPES.TSNeverKeyword; +} + +export interface TSNullKeyword extends BaseNode { + type: AST_NODE_TYPES.TSNullKeyword; +} + +export interface TSNumberKeyword extends BaseNode { + type: AST_NODE_TYPES.TSNumberKeyword; +} + +export interface TSObjectKeyword extends BaseNode { + type: AST_NODE_TYPES.TSObjectKeyword; +} + +export interface TSPrivateKeyword extends BaseNode { + type: AST_NODE_TYPES.TSPrivateKeyword; +} + +export interface TSProtectedKeyword extends BaseNode { + type: AST_NODE_TYPES.TSProtectedKeyword; +} + +export interface TSPublicKeyword extends BaseNode { + type: AST_NODE_TYPES.TSPublicKeyword; +} + +export interface TSStaticKeyword extends BaseNode { + type: AST_NODE_TYPES.TSStaticKeyword; +} + +export interface TSStringKeyword extends BaseNode { + type: AST_NODE_TYPES.TSStringKeyword; +} + +export interface TSSymbolKeyword extends BaseNode { + type: AST_NODE_TYPES.TSSymbolKeyword; +} + +export interface TSUndefinedKeyword extends BaseNode { + type: AST_NODE_TYPES.TSUndefinedKeyword; +} + +export interface TSUnknownKeyword extends BaseNode { + type: AST_NODE_TYPES.TSUnknownKeyword; +} + +export interface TSVoidKeyword extends BaseNode { + type: AST_NODE_TYPES.TSVoidKeyword; +} + +export type Declarations = + | ClassDeclaration + | ExportAllDeclaration + | ExportDefaultDeclaration + | ExportNamedDeclaration + | FunctionDeclaration + | ImportDeclaration + | VariableDeclaration + | TSDeclareFunction + | TSEnumDeclaration + | TSExportAssignment + | TSImportEqualsDeclaration + | TSInterfaceDeclaration + | TSModuleDeclaration + | TSTypeAliasDeclaration; + +export type Statements = + | ExpressionStatement + | BlockStatement + | EmptyStatement + | DebuggerStatement + | WithStatement + | ReturnStatement + | LabeledStatement + | BreakStatement + | ContinueStatement + | IfStatement + | SwitchStatement + | ThrowStatement + | TryStatement + | WhileStatement + | DoWhileStatement + | ForStatement + | ForInStatement + | ForOfStatement; + +export type Literals = TemplateLiteral | Literal | BigIntLiteral; + +export type Expressions = + | ThisExpression + | ArrayExpression + | ObjectExpression + | FunctionExpression + | ArrowFunctionExpression + | YieldExpression + | UnaryExpression + | UpdateExpression + | BinaryExpression + | AssignmentExpression + | LogicalExpression + | MemberExpression + | ConditionalExpression + | CallExpression + | NewExpression + | SequenceExpression + | TaggedTemplateExpression + | ClassExpression + | MetaProperty + | AwaitExpression + | TSAsExpression + | TSNonNullExpression + | TSTypeAssertion; + +export type TSSignatures = + | TSCallSignatureDeclaration + | TSConstructSignatureDeclaration + | TSIndexSignature + | TSMethodSignature + | TSPropertySignature; + +export type TSTypeKeywords = + | TSAnyKeyword + | TSBigIntKeyword + | TSBooleanKeyword + | TSNeverKeyword + | TSNullKeyword + | TSNumberKeyword + | TSObjectKeyword + | TSStringKeyword + | TSSymbolKeyword + | TSUndefinedKeyword + | TSUnknownKeyword + | TSVoidKeyword; + +export type TSTypeOperators = + | TSArrayType + | TSConditionalType + | TSConstructorType + | TSFunctionType + | TSImportType + | TSIndexedAccessType + | TSInferType + | TSIntersectionType + | TSMappedType + | TSParenthesizedType + | TSTupleType + | TSTypeLiteral + | TSTypeOperator + | TSTypePredicate + | TSTypeQuery + | TSTypeReference + | TSUnionType + | TSOptionalType + | TSRestType; diff --git a/packages/typescript-estree/src/convert-comments.ts b/packages/typescript-estree/src/convert-comments.ts index ac7f8504d8aa..037024fb98aa 100644 --- a/packages/typescript-estree/src/convert-comments.ts +++ b/packages/typescript-estree/src/convert-comments.ts @@ -7,31 +7,28 @@ import ts from 'typescript'; import { getLocFor, getNodeContainer } from './node-utils'; -import { - ESTreeComment, - LineAndColumnData -} from './temp-types-based-on-js-source'; +import * as es from './ast-tree-nodes'; /** * Converts a TypeScript comment to an Esprima comment. - * @param {boolean} block True if it's a block comment, false if not. - * @param {string} text The text of the comment. - * @param {number} start The index at which the comment starts. - * @param {number} end The index at which the comment ends. - * @param {LineAndColumnData} startLoc The location at which the comment starts. - * @param {LineAndColumnData} endLoc The location at which the comment ends. - * @returns {Object} The comment object. - * @private + * @param block True if it's a block comment, false if not. + * @param text The text of the comment. + * @param start The index at which the comment starts. + * @param end The index at which the comment ends. + * @param startLoc The location at which the comment starts. + * @param endLoc The location at which the comment ends. + * @returns The comment object. + * @internal */ function convertTypeScriptCommentToEsprimaComment( block: boolean, text: string, start: number, end: number, - startLoc: LineAndColumnData, - endLoc: LineAndColumnData -): ESTreeComment { - const comment: ESTreeComment = { + startLoc: es.Position, + endLoc: es.Position +): es.Comment { + const comment: es.Comment = { type: block ? 'Block' : 'Line', value: text }; @@ -52,17 +49,17 @@ function convertTypeScriptCommentToEsprimaComment( /** * Convert comment from TypeScript Triva Scanner. - * @param {ts.Scanner} triviaScanner TS Scanner - * @param {ts.SourceFile} ast the AST object - * @param {string} code TypeScript code - * @returns {ESTreeComment} the converted ESTreeComment + * @param triviaScanner TS Scanner + * @param ast the AST object + * @param code TypeScript code + * @returns the converted Comment * @private */ function getCommentFromTriviaScanner( triviaScanner: ts.Scanner, ast: ts.SourceFile, code: string -): ESTreeComment { +): es.Comment { const kind = triviaScanner.getToken(); const isBlock = kind === ts.SyntaxKind.MultiLineCommentTrivia; const range = { @@ -77,7 +74,7 @@ function getCommentFromTriviaScanner( : comment.replace(/^\/\//, ''); const loc = getLocFor(range.pos, range.end, ast); - const esprimaComment = convertTypeScriptCommentToEsprimaComment( + return convertTypeScriptCommentToEsprimaComment( isBlock, text, range.pos, @@ -85,22 +82,20 @@ function getCommentFromTriviaScanner( loc.start, loc.end ); - - return esprimaComment; } /** * Convert all comments for the given AST. - * @param {ts.SourceFile} ast the AST object - * @param {string} code the TypeScript code - * @returns {ESTreeComment[]} the converted ESTreeComment + * @param ast the AST object + * @param code the TypeScript code + * @returns the converted ESTreeComment * @private */ export function convertComments( ast: ts.SourceFile, code: string -): ESTreeComment[] { - const comments: ESTreeComment[] = []; +): es.Comment[] { + const comments: es.Comment[] = []; /** * Create a TypeScript Scanner, with skipTrivia set to false so that diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 9a7adebc8e2e..d98fb82ce080 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -6,47 +6,36 @@ * MIT License */ import ts from 'typescript'; +import * as es from './ast-tree-nodes'; import { canContainDirective, + convertToken, createError, - getLoc, - getLocFor, findNextToken, - convertToken, - hasModifier, fixExports, - getTSNodeAccessibility, + getBinaryExpressionType, + getDeclarationKind, + getLastModifier, + getLineAndCharacterFor, + getLocFor, + getRange, getTextForTokenKind, - isJSXToken, + getTSNodeAccessibility, + hasModifier, + isComma, isComputedProperty, isESTreeClassMember, - isComma, - getBinaryExpressionType, + isJSXToken, isOptional, - unescapeStringLiteralText, - getDeclarationKind, - getLastModifier, - getLineAndCharacterFor + unescapeStringLiteralText } from './node-utils'; import { AST_NODE_TYPES } from './ast-node-types'; -import { ESTreeNode } from './temp-types-based-on-js-source'; import { TSNode } from './ts-nodes'; +import { ASTTreeNodes } from './ast-nodes'; const SyntaxKind = ts.SyntaxKind; -let esTreeNodeToTSNodeMap = new WeakMap(); -let tsNodeToESTreeNodeMap = new WeakMap(); - -export function resetASTMaps() { - esTreeNodeToTSNodeMap = new WeakMap(); - tsNodeToESTreeNodeMap = new WeakMap(); -} - -export function getASTMaps() { - return { esTreeNodeToTSNodeMap, tsNodeToESTreeNodeMap }; -} - -interface ConvertAdditionalOptions { +interface ConverterOptions { errorOnUnknownASTType: boolean; useJSXTextNode: boolean; shouldProvideParserServices: boolean; @@ -58,7 +47,7 @@ interface ConvertConfig { inTypeMode?: boolean; allowPattern?: boolean; ast: ts.SourceFile; - additionalOptions: ConvertAdditionalOptions; + options: ConverterOptions; } /** @@ -74,99 +63,148 @@ export function convertError(error: any) { ); } -/** - * Converts a TypeScript node into an ESTree node - * @param {Object} config configuration options for the conversion - * @param {TSNode} config.node the ts.Node - * @param {ts.Node} config.parent the parent ts.Node - * @param {ts.SourceFile} config.ast the full TypeScript AST - * @param {Object} config.additionalOptions additional options for the conversion - * @returns {ESTreeNode|null} the converted ESTreeNode - */ -export default function convert(config: ConvertConfig): ESTreeNode | null { - const node: TSNode = config.node as TSNode; - const parent = config.parent; - const ast = config.ast; - const additionalOptions = config.additionalOptions || {}; +export class Converter { + protected ast: ts.SourceFile; + protected options: ConverterOptions; + public esTreeNodeToTSNodeMap = new WeakMap(); + public tsNodeToESTreeNodeMap = new WeakMap(); + + protected allowPattern: boolean = false; + protected inTypeMode: boolean = false; /** - * Exit early for null and undefined + * Converts a TypeScript node into an ESTree node + * @param ast the full TypeScript AST + * @param options additional options for the conversion + * @returns the converted ESTreeNode */ - if (!node) { - return null; + constructor(ast: ts.SourceFile, options: ConverterOptions) { + this.ast = ast; + this.options = options; + } + + public getASTMaps() { + return { + esTreeNodeToTSNodeMap: this.esTreeNodeToTSNodeMap, + tsNodeToESTreeNodeMap: this.tsNodeToESTreeNodeMap + }; + } + + public convertProgram(): es.Program { + return this.converter(this.ast) as es.Program; } /** - * Create a new ESTree node + * Converts a TypeScript node into an ESTree node. + * @param node the child ts.Node + * @param parent parentNode + * @param inTypeMode flag to determine if we are in typeMode + * @param allowPattern flag to determine if patterns are allowed + * @returns the converted ESTree node */ - let result: ESTreeNode = { - type: '' as AST_NODE_TYPES, - range: [node.getStart(ast), node.end], - loc: getLoc(node, ast) - }; - - function converter( - child?: ts.Node, + protected converter( + node?: ts.Node, + parent?: ts.Node, inTypeMode?: boolean, allowPattern?: boolean - ): ESTreeNode | null { - if (!child) { + ): any { + /** + * Exit early for null and undefined + */ + if (!node) { return null; } - return convert({ - node: child, - parent: node, - inTypeMode, - allowPattern, - ast, - additionalOptions - }); + + const typeMode = this.inTypeMode; + const pattern = this.allowPattern; + if (inTypeMode !== undefined) { + this.inTypeMode = inTypeMode; + } + if (allowPattern !== undefined) { + this.allowPattern = allowPattern; + } + + let result: es.BaseNode | null = this.convertNode( + node as TSNode, + parent || node.parent + ); + + if (result && this.options.shouldProvideParserServices) { + this.tsNodeToESTreeNodeMap.set(node, result); + this.esTreeNodeToTSNodeMap.set(result, node); + } + + this.inTypeMode = typeMode; + this.allowPattern = pattern; + return result; } /** * Converts a TypeScript node into an ESTree node. - * @param {ts.Node} child the child ts.Node - * @returns {ESTreeNode|null} the converted ESTree node + * @param child the child ts.Node + * @param parent parentNode + * @returns the converted ESTree node */ - function convertPattern(child?: ts.Node): ESTreeNode | null { - return converter(child, config.inTypeMode, true); + protected convertPattern(child?: ts.Node, parent?: ts.Node): any | null { + return this.converter(child, parent, this.inTypeMode, true); } /** * Converts a TypeScript node into an ESTree node. - * @param {ts.Node} child the child ts.Node - * @returns {ESTreeNode|null} the converted ESTree node + * @param child the child ts.Node + * @param parent parentNode + * @returns the converted ESTree node */ - function convertChild(child?: ts.Node): ESTreeNode | null { - return converter(child, config.inTypeMode, false); + protected convertChild(child?: ts.Node, parent?: ts.Node): any | null { + return this.converter(child, parent, this.inTypeMode, false); } /** * Converts a TypeScript node into an ESTree node. - * @param {ts.Node} child the child ts.Node - * @returns {ESTreeNode|null} the converted ESTree node + * @param child the child ts.Node + * @param parent parentNode + * @returns the converted ESTree node */ - function convertChildType(child?: ts.Node): ESTreeNode | null { - return converter(child, true, false); + protected convertType(child?: ts.Node, parent?: ts.Node): any | null { + return this.converter(child, parent, true, false); + } + + protected createNode( + node: ts.Node, + data: T + ): T { + const result: T = data; + if (!result.range) { + result.range = getRange(node, this.ast); + } + if (!result.loc) { + result.loc = getLocFor(result.range[0], result.range[1], this.ast); + } + + return result as T & { range: [number, number]; loc: es.SourceLocation }; } /** * Converts a child into a type annotation. This creates an intermediary * TypeAnnotation node to match what Flow does. - * @param {ts.TypeNode} child The TypeScript AST node to convert. - * @returns {ESTreeNode} The type annotation node. + * @param child The TypeScript AST node to convert. + * @param parent parentNode + * @returns The type annotation node. */ - function convertTypeAnnotation(child: ts.TypeNode): ESTreeNode { - const annotation = convertChildType(child); + protected convertTypeAnnotation( + child: ts.TypeNode, + parent: ts.Node + ): es.TSTypeAnnotation { + const annotation = this.convertType(child); // in FunctionType and ConstructorType typeAnnotation has 2 characters `=>` and in other places is just colon const offset = - node.kind === SyntaxKind.FunctionType || - node.kind === SyntaxKind.ConstructorType + parent.kind === SyntaxKind.FunctionType || + parent.kind === SyntaxKind.ConstructorType ? 2 : 1; const annotationStartCol = child.getFullStart() - offset; - const loc = getLocFor(annotationStartCol, child.end, ast); + const loc = getLocFor(annotationStartCol, child.end, this.ast); return { type: AST_NODE_TYPES.TSTypeAnnotation, loc, @@ -177,18 +215,20 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { /** * Coverts body Nodes and add directive field to StringLiterals - * @param {ts.NodeArray} nodes of ts.Node - * @returns {ESTreeNode[]} Array of body statements + * @param nodes of ts.Node + * @param parent parentNode + * @returns Array of body statements */ - function convertBodyExpressions( - nodes: ts.NodeArray - ): ESTreeNode[] { - let allowDirectives = canContainDirective(node); + protected convertBodyExpressions( + nodes: ts.NodeArray, + parent: ts.Node + ): any[] { + let allowDirectives = canContainDirective(parent); return ( nodes .map(statement => { - const child = convertChild(statement); + const child = this.convertChild(statement); if (allowDirectives) { if ( child && @@ -212,58 +252,60 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { /** * Converts a ts.Node's typeArguments to TSTypeParameterInstantiation node - * @param {ts.NodeArray} typeArguments ts.Node typeArguments - * @returns {ESTreeNode} TypeParameterInstantiation node + * @param typeArguments ts.Node typeArguments + * @returns TypeParameterInstantiation node */ - function convertTypeArgumentsToTypeParameters( + protected convertTypeArgumentsToTypeParameters( typeArguments: ts.NodeArray - ): ESTreeNode { - const greaterThanToken = findNextToken(typeArguments, ast, ast)!; + ): es.TSTypeParameterInstantiation { + const greaterThanToken = findNextToken(typeArguments, this.ast, this.ast)!; return { type: AST_NODE_TYPES.TSTypeParameterInstantiation, range: [typeArguments.pos - 1, greaterThanToken.end], - loc: getLocFor(typeArguments.pos - 1, greaterThanToken.end, ast), - params: typeArguments.map(typeArgument => convertChildType(typeArgument)) + loc: getLocFor(typeArguments.pos - 1, greaterThanToken.end, this.ast), + params: typeArguments.map(typeArgument => this.convertType(typeArgument)) }; } /** * Converts a ts.Node's typeParameters to TSTypeParameterDeclaration node - * @param {ts.NodeArray} typeParameters ts.Node typeParameters - * @returns {ESTreeNode} TypeParameterDeclaration node + * @param typeParameters ts.Node typeParameters + * @returns TypeParameterDeclaration node */ - function convertTSTypeParametersToTypeParametersDeclaration( + protected convertTSTypeParametersToTypeParametersDeclaration( typeParameters: ts.NodeArray - ): ESTreeNode { - const greaterThanToken = findNextToken(typeParameters, ast, ast)!; + ): es.TSTypeParameterDeclaration { + const greaterThanToken = findNextToken(typeParameters, this.ast, this.ast)!; return { type: AST_NODE_TYPES.TSTypeParameterDeclaration, range: [typeParameters.pos - 1, greaterThanToken.end], - loc: getLocFor(typeParameters.pos - 1, greaterThanToken.end, ast), + loc: getLocFor(typeParameters.pos - 1, greaterThanToken.end, this.ast), params: typeParameters.map(typeParameter => - convertChildType(typeParameter) + this.convertType(typeParameter) ) }; } /** * Converts an array of ts.Node parameters into an array of ESTreeNode params - * @param {ts.Node[]} parameters An array of ts.Node params to be converted - * @returns {ESTreeNode[]} an array of converted ESTreeNode params + * @param parameters An array of ts.Node params to be converted + * @returns an array of converted ESTreeNode params */ - function convertParameters(parameters: ts.NodeArray): ESTreeNode[] { + protected convertParameters( + parameters: ts.NodeArray + ): (es.TSParameterProperty | es.RestElement | es.AssignmentPattern)[] { if (!parameters || !parameters.length) { return []; } return parameters.map(param => { - const convertedParam = convertChild(param)!; + const convertedParam = this.convertChild(param)!; if (!param.decorators || !param.decorators.length) { return convertedParam; } return Object.assign(convertedParam, { - decorators: param.decorators.map(convertChild) + decorators: param.decorators.map(el => this.convertChild(el)) }); }); } @@ -272,21 +314,20 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { * For nodes that are copied directly from the TypeScript AST into * ESTree mostly as-is. The only difference is the addition of a type * property instead of a kind property. Recursively copies all children. - * @returns {void} */ - function deeplyCopy(): void { + protected deeplyCopy(node: ts.Node): any { const customType = `TS${SyntaxKind[node.kind]}` as AST_NODE_TYPES; /** * If the "errorOnUnknownASTType" option is set to true, throw an error, * otherwise fallback to just including the unknown type as-is. */ - if ( - additionalOptions.errorOnUnknownASTType && - !AST_NODE_TYPES[customType] - ) { + if (this.options.errorOnUnknownASTType && !AST_NODE_TYPES[customType]) { throw new Error(`Unknown AST_NODE_TYPE: "${customType}"`); } - result.type = customType; + const result = this.createNode(node, { + type: customType + }); + Object.keys(node) .filter( key => @@ -297,48 +338,57 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { .forEach(key => { if (key === 'type') { result.typeAnnotation = (node as any).type - ? convertTypeAnnotation((node as any).type) + ? this.convertTypeAnnotation((node as any).type, node) : null; } else if (key === 'typeArguments') { result.typeParameters = (node as any).typeArguments - ? convertTypeArgumentsToTypeParameters((node as any).typeArguments) + ? this.convertTypeArgumentsToTypeParameters( + (node as any).typeArguments + ) : null; } else if (key === 'typeParameters') { result.typeParameters = (node as any).typeParameters - ? convertTSTypeParametersToTypeParametersDeclaration( + ? this.convertTSTypeParametersToTypeParametersDeclaration( (node as any).typeParameters ) : null; } else if (key === 'decorators') { if (node.decorators && node.decorators.length) { - result.decorators = node.decorators.map(convertChild); + result.decorators = node.decorators.map((el: any) => + this.convertChild(el) + ); } } else { if (Array.isArray((node as any)[key])) { - (result as any)[key] = (node as any)[key].map(convertChild); + result[key] = (node as any)[key].map((el: any) => + this.convertChild(el) + ); } else if ( (node as any)[key] && typeof (node as any)[key] === 'object' && (node as any)[key].kind ) { // need to check node[key].kind to ensure we don't try to convert a symbol - (result as any)[key] = convertChild((node as any)[key]); + result[key] = this.convertChild((node as any)[key]); } else { - (result as any)[key] = (node as any)[key]; + result[key] = (node as any)[key]; } } }); + return result; } /** * Converts a TypeScript JSX node.tagName into an ESTree node.name - * @param {ts.JsxTagNameExpression} tagName the tagName object from a JSX ts.Node - * @returns {Object} the converted ESTree name object + * @param tagName the tagName object from a JSX ts.Node + * @param node + * @returns the converted ESTree name object */ - function convertTypeScriptJSXTagNameToESTreeName( - tagName: ts.JsxTagNameExpression - ): ESTreeNode { - const tagNameToken = convertToken(tagName, ast); + protected convertTypeScriptJSXTagNameToESTreeName( + tagName: ts.JsxTagNameExpression, + node: ts.Node + ): es.JSXMemberExpression | es.JSXIdentifier { + const tagNameToken = convertToken(tagName, this.ast); if (tagNameToken.type === AST_NODE_TYPES.JSXMemberExpression) { const isNestedMemberExpression = @@ -347,8 +397,14 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { // Convert TSNode left and right objects into ESTreeNode object // and property objects - tagNameToken.object = convertChild((node as any).tagName.expression); - tagNameToken.property = convertChild((node as any).tagName.name); + tagNameToken.object = this.convertChild( + (node as any).tagName.expression, + node + ); + tagNameToken.property = this.convertChild( + (node as any).tagName.name, + node + ); // Assign the appropriate types tagNameToken.object.type = isNestedMemberExpression @@ -365,15 +421,21 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { delete tagNameToken.value; - return tagNameToken; + return tagNameToken as any; } /** * Applies the given TS modifiers to the given result object. - * @param {ts.ModifiersArray} modifiers original ts.Nodes from the node.modifiers array - * @returns {void} (the current result object will be mutated) + * @param result + * @param modifiers original ts.Nodes from the node.modifiers array + * @returns the current result object will be mutated + * @deprecated + * TODO: remove this */ - function applyModifiersToResult(modifiers?: ts.ModifiersArray): void { + protected applyModifiersToResult( + result: es.TSEnumDeclaration | es.TSModuleDeclaration, + modifiers?: ts.ModifiersArray + ): void { if (!modifiers || !modifiers.length) { return; } @@ -396,7 +458,7 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { handledModifierIndices[i] = true; break; case SyntaxKind.ConstKeyword: - result.const = true; + (result as any).const = true; handledModifierIndices[i] = true; break; case SyntaxKind.DeclareKeyword: @@ -417,2091 +479,2037 @@ export default function convert(config: ConvertConfig): ESTreeNode | null { if (!remainingModifiers || !remainingModifiers.length) { return; } - result.modifiers = remainingModifiers.map(convertChild); + result.modifiers = remainingModifiers.map(el => this.convertChild(el)); } /** * Uses the current TSNode's end location for its `type` to adjust the location data of the given * ESTreeNode, which should be the parent of the final typeAnnotation node - * @param {ESTreeNode} typeAnnotationParent The node that will have its location data mutated - * @returns {void} + * @param typeAnnotationParent The node that will have its location data mutated + * @param node */ - function fixTypeAnnotationParentLocation( - typeAnnotationParent: ESTreeNode + protected fixTypeAnnotationParentLocation( + typeAnnotationParent: es.BaseNode, + node: ts.TypeNode ): void { - typeAnnotationParent.range[1] = (node as any).type.getEnd(); + typeAnnotationParent.range![1] = node.getEnd(); typeAnnotationParent.loc = getLocFor( - typeAnnotationParent.range[0], - typeAnnotationParent.range[1], - ast + typeAnnotationParent.range![0], + typeAnnotationParent.range![1], + this.ast ); } /** + * Converts a TypeScript node into an ESTree node. * The core of the conversion logic: * Identify and convert each relevant TypeScript SyntaxKind + * @param node the child ts.Node + * @param parent parentNode + * @returns the converted ESTree node */ - switch (node.kind) { - case SyntaxKind.SourceFile: - Object.assign(result, { - type: AST_NODE_TYPES.Program, - body: convertBodyExpressions(node.statements), - // externalModuleIndicator is internal field in TSC - sourceType: (node as any).externalModuleIndicator ? 'module' : 'script' - }); + protected convertNode(node: TSNode, parent: ts.Node): ASTTreeNodes | null { + switch (node.kind) { + case SyntaxKind.SourceFile: { + return this.createNode(node, { + type: AST_NODE_TYPES.Program, + body: this.convertBodyExpressions(node.statements, node), + // externalModuleIndicator is internal field in TSC + sourceType: (node as any).externalModuleIndicator + ? 'module' + : 'script', + range: [node.getStart(this.ast), node.endOfFileToken.end] + }); + } - result.range[1] = node.endOfFileToken.end; - result.loc = getLocFor(node.getStart(ast), result.range[1], ast); - break; + case SyntaxKind.Block: { + return this.createNode(node, { + type: AST_NODE_TYPES.BlockStatement, + body: this.convertBodyExpressions(node.statements, node) + }); + } - case SyntaxKind.Block: - Object.assign(result, { - type: AST_NODE_TYPES.BlockStatement, - body: convertBodyExpressions(node.statements) - }); - break; + case SyntaxKind.Identifier: { + return this.createNode(node, { + type: AST_NODE_TYPES.Identifier, + name: node.text + }); + } - case SyntaxKind.Identifier: - Object.assign(result, { - type: AST_NODE_TYPES.Identifier, - name: node.text - }); - break; + case SyntaxKind.WithStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.WithStatement, + object: this.convertChild(node.expression), + body: this.convertChild(node.statement) + }); - case SyntaxKind.WithStatement: - Object.assign(result, { - type: AST_NODE_TYPES.WithStatement, - object: convertChild(node.expression), - body: convertChild(node.statement) - }); - break; + // Control Flow - // Control Flow + case SyntaxKind.ReturnStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.ReturnStatement, + argument: this.convertChild(node.expression) + }); - case SyntaxKind.ReturnStatement: - Object.assign(result, { - type: AST_NODE_TYPES.ReturnStatement, - argument: convertChild(node.expression) - }); - break; + case SyntaxKind.LabeledStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.LabeledStatement, + label: this.convertChild(node.label), + body: this.convertChild(node.statement) + }); - case SyntaxKind.LabeledStatement: - Object.assign(result, { - type: AST_NODE_TYPES.LabeledStatement, - label: convertChild(node.label), - body: convertChild(node.statement) - }); - break; + case SyntaxKind.ContinueStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.ContinueStatement, + label: this.convertChild(node.label) + }); - case SyntaxKind.BreakStatement: - case SyntaxKind.ContinueStatement: - Object.assign(result, { - type: SyntaxKind[node.kind], - label: convertChild(node.label) - }); - break; + case SyntaxKind.BreakStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.BreakStatement, + label: this.convertChild(node.label) + }); - // Choice + // Choice - case SyntaxKind.IfStatement: - Object.assign(result, { - type: AST_NODE_TYPES.IfStatement, - test: convertChild(node.expression), - consequent: convertChild(node.thenStatement), - alternate: convertChild(node.elseStatement) - }); - break; + case SyntaxKind.IfStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.IfStatement, + test: this.convertChild(node.expression), + consequent: this.convertChild(node.thenStatement), + alternate: this.convertChild(node.elseStatement) + }); - case SyntaxKind.SwitchStatement: - Object.assign(result, { - type: AST_NODE_TYPES.SwitchStatement, - discriminant: convertChild(node.expression), - cases: node.caseBlock.clauses.map(convertChild) - }); - break; - - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: - Object.assign(result, { - type: AST_NODE_TYPES.SwitchCase, - // expression is present in case only - test: - node.kind === SyntaxKind.CaseClause - ? convertChild(node.expression) - : null, - consequent: node.statements.map(convertChild) - }); - break; + case SyntaxKind.SwitchStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.SwitchStatement, + discriminant: this.convertChild(node.expression), + cases: node.caseBlock.clauses.map(el => this.convertChild(el)) + }); - // Exceptions + case SyntaxKind.CaseClause: + case SyntaxKind.DefaultClause: + return this.createNode(node, { + type: AST_NODE_TYPES.SwitchCase, + // expression is present in case only + test: + node.kind === SyntaxKind.CaseClause + ? this.convertChild(node.expression) + : null, + consequent: node.statements.map(el => this.convertChild(el)) + }); - case SyntaxKind.ThrowStatement: - Object.assign(result, { - type: AST_NODE_TYPES.ThrowStatement, - argument: convertChild(node.expression) - }); - break; - - case SyntaxKind.TryStatement: - Object.assign(result, { - type: AST_NODE_TYPES.TryStatement, - block: convert({ - node: node.tryBlock, - parent: null, - ast, - additionalOptions - }), - handler: convertChild(node.catchClause), - finalizer: convertChild(node.finallyBlock) - }); - break; - - case SyntaxKind.CatchClause: - Object.assign(result, { - type: AST_NODE_TYPES.CatchClause, - param: node.variableDeclaration - ? convertChild(node.variableDeclaration.name) - : null, - body: convertChild(node.block) - }); - break; + // Exceptions - // Loops + case SyntaxKind.ThrowStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.ThrowStatement, + argument: this.convertChild(node.expression) + }); - case SyntaxKind.WhileStatement: - Object.assign(result, { - type: AST_NODE_TYPES.WhileStatement, - test: convertChild(node.expression), - body: convertChild(node.statement) - }); - break; + case SyntaxKind.TryStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.TryStatement, + block: this.convertChild(node.tryBlock), + handler: this.convertChild(node.catchClause), + finalizer: this.convertChild(node.finallyBlock) + }); - /** - * Unlike other parsers, TypeScript calls a "DoWhileStatement" - * a "DoStatement" - */ - case SyntaxKind.DoStatement: - Object.assign(result, { - type: AST_NODE_TYPES.DoWhileStatement, - test: convertChild(node.expression), - body: convertChild(node.statement) - }); - break; - - case SyntaxKind.ForStatement: - Object.assign(result, { - type: AST_NODE_TYPES.ForStatement, - init: convertChild(node.initializer), - test: convertChild(node.condition), - update: convertChild(node.incrementor), - body: convertChild(node.statement) - }); - break; - - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: { - Object.assign(result, { - type: SyntaxKind[node.kind], - left: convertPattern(node.initializer), - right: convertChild(node.expression), - body: convertChild(node.statement) - }); + case SyntaxKind.CatchClause: + return this.createNode(node, { + type: AST_NODE_TYPES.CatchClause, + param: node.variableDeclaration + ? this.convertChild(node.variableDeclaration.name) + : null, + body: this.convertChild(node.block) + }); - // await is only available in for of statement - if (node.kind === SyntaxKind.ForOfStatement) { - (result as any).await = Boolean( - node.awaitModifier && - node.awaitModifier.kind === SyntaxKind.AwaitKeyword - ); - } - break; - } + // Loops - // Declarations + case SyntaxKind.WhileStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.WhileStatement, + test: this.convertChild(node.expression), + body: this.convertChild(node.statement) + }); - case SyntaxKind.FunctionDeclaration: { - const isDeclare = hasModifier(SyntaxKind.DeclareKeyword, node); - let functionDeclarationType = AST_NODE_TYPES.FunctionDeclaration; - if (isDeclare || !node.body) { - functionDeclarationType = AST_NODE_TYPES.TSDeclareFunction; - } + /** + * Unlike other parsers, TypeScript calls a "DoWhileStatement" + * a "DoStatement" + */ + case SyntaxKind.DoStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.DoWhileStatement, + test: this.convertChild(node.expression), + body: this.convertChild(node.statement) + }); - Object.assign(result, { - type: functionDeclarationType, - id: convertChild(node.name), - generator: !!node.asteriskToken, - expression: false, - async: hasModifier(SyntaxKind.AsyncKeyword, node), - params: convertParameters(node.parameters), - body: convertChild(node.body) || undefined - }); + case SyntaxKind.ForStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.ForStatement, + init: this.convertChild(node.initializer), + test: this.convertChild(node.condition), + update: this.convertChild(node.incrementor), + body: this.convertChild(node.statement) + }); - // Process returnType - if (node.type) { - result.returnType = convertTypeAnnotation(node.type); - } + case SyntaxKind.ForInStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.ForInStatement, + left: this.convertPattern(node.initializer), + right: this.convertChild(node.expression), + body: this.convertChild(node.statement) + }); - if (isDeclare) { - result.declare = true; - } + case SyntaxKind.ForOfStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.ForOfStatement, + left: this.convertPattern(node.initializer), + right: this.convertChild(node.expression), + body: this.convertChild(node.statement), + await: Boolean( + node.awaitModifier && + node.awaitModifier.kind === SyntaxKind.AwaitKeyword + ) + }); - // Process typeParameters - if (node.typeParameters && node.typeParameters.length) { - result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); - } + // Declarations + + case SyntaxKind.FunctionDeclaration: { + const isDeclare = hasModifier(SyntaxKind.DeclareKeyword, node); + + const result = this.createNode(node, { + type: + isDeclare || !node.body + ? AST_NODE_TYPES.TSDeclareFunction + : AST_NODE_TYPES.FunctionDeclaration, + id: this.convertChild(node.name), + generator: !!node.asteriskToken, + expression: false, + async: hasModifier(SyntaxKind.AsyncKeyword, node), + params: this.convertParameters(node.parameters), + body: this.convertChild(node.body) || undefined + }); - // check for exports - result = fixExports(node, result, ast); + // Process returnType + if (node.type) { + result.returnType = this.convertTypeAnnotation(node.type, node); + } - break; - } + if (isDeclare) { + result.declare = true; + } - case SyntaxKind.VariableDeclaration: { - Object.assign(result, { - type: AST_NODE_TYPES.VariableDeclarator, - id: convertPattern(node.name), - init: convertChild(node.initializer) - }); + // Process typeParameters + if (node.typeParameters && node.typeParameters.length) { + result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); + } - if (node.exclamationToken) { - (result as any).definite = true; + // check for exports + return fixExports(node, result, this.ast); } - if (node.type) { - result.id!.typeAnnotation = convertTypeAnnotation(node.type); - fixTypeAnnotationParentLocation(result.id!); - } - break; - } + case SyntaxKind.VariableDeclaration: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.VariableDeclarator, + id: this.convertPattern(node.name), + init: this.convertChild(node.initializer) + }); - case SyntaxKind.VariableStatement: - Object.assign(result, { - type: AST_NODE_TYPES.VariableDeclaration, - declarations: node.declarationList.declarations.map(convertChild), - kind: getDeclarationKind(node.declarationList) - }); + if (node.exclamationToken) { + result.definite = true; + } - if (hasModifier(SyntaxKind.DeclareKeyword, node)) { - result.declare = true; + if (node.type) { + result.id.typeAnnotation = this.convertTypeAnnotation( + node.type, + node + ); + this.fixTypeAnnotationParentLocation(result.id, node.type); + } + return result; } - // check for exports - result = fixExports(node, result, ast); - break; - - // mostly for for-of, for-in - case SyntaxKind.VariableDeclarationList: - Object.assign(result, { - type: AST_NODE_TYPES.VariableDeclaration, - declarations: node.declarations.map(convertChild), - kind: getDeclarationKind(node) - }); - break; - - // Expressions - - case SyntaxKind.ExpressionStatement: - Object.assign(result, { - type: AST_NODE_TYPES.ExpressionStatement, - expression: convertChild(node.expression) - }); - break; + case SyntaxKind.VariableStatement: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.VariableDeclaration, + declarations: node.declarationList.declarations.map(el => + this.convertChild(el) + ), + kind: getDeclarationKind(node.declarationList) + }); - case SyntaxKind.ThisKeyword: - Object.assign(result, { - type: AST_NODE_TYPES.ThisExpression - }); - break; + if (hasModifier(SyntaxKind.DeclareKeyword, node)) { + result.declare = true; + } - case SyntaxKind.ArrayLiteralExpression: { - // TypeScript uses ArrayLiteralExpression in destructuring assignment, too - if (config.allowPattern) { - Object.assign(result, { - type: AST_NODE_TYPES.ArrayPattern, - elements: node.elements.map(convertPattern) - }); - } else { - Object.assign(result, { - type: AST_NODE_TYPES.ArrayExpression, - elements: node.elements.map(convertChild) - }); + // check for exports + return fixExports(node, result, this.ast); } - break; - } - case SyntaxKind.ObjectLiteralExpression: { - // TypeScript uses ObjectLiteralExpression in destructuring assignment, too - if (config.allowPattern) { - Object.assign(result, { - type: AST_NODE_TYPES.ObjectPattern, - properties: node.properties.map(convertPattern) - }); - } else { - Object.assign(result, { - type: AST_NODE_TYPES.ObjectExpression, - properties: node.properties.map(convertChild) + // mostly for for-of, for-in + case SyntaxKind.VariableDeclarationList: + return this.createNode(node, { + type: AST_NODE_TYPES.VariableDeclaration, + declarations: node.declarations.map(el => this.convertChild(el)), + kind: getDeclarationKind(node) }); - } - break; - } - case SyntaxKind.PropertyAssignment: - Object.assign(result, { - type: AST_NODE_TYPES.Property, - key: convertChild(node.name), - value: converter( - node.initializer, - config.inTypeMode, - config.allowPattern - ), - computed: isComputedProperty(node.name), - method: false, - shorthand: false, - kind: 'init' - }); - break; + // Expressions - case SyntaxKind.ShorthandPropertyAssignment: { - if (node.objectAssignmentInitializer) { - Object.assign(result, { - type: AST_NODE_TYPES.Property, - key: convertChild(node.name), - value: { - type: AST_NODE_TYPES.AssignmentPattern, - left: convertPattern(node.name), - right: convertChild(node.objectAssignmentInitializer), - loc: result.loc, - range: result.range - }, - computed: false, - method: false, - shorthand: true, - kind: 'init' - }); - } else { - // TODO: this node has no initializer field - Object.assign(result, { - type: AST_NODE_TYPES.Property, - key: convertChild(node.name), - value: convertChild((node as any).initializer || node.name), - computed: false, - method: false, - shorthand: true, - kind: 'init' + case SyntaxKind.ExpressionStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.ExpressionStatement, + expression: this.convertChild(node.expression) }); - } - break; - } - - case SyntaxKind.ComputedPropertyName: - return convertChild(node.expression); - - case SyntaxKind.PropertyDeclaration: { - const isAbstract = hasModifier(SyntaxKind.AbstractKeyword, node); - Object.assign(result, { - type: isAbstract - ? AST_NODE_TYPES.TSAbstractClassProperty - : AST_NODE_TYPES.ClassProperty, - key: convertChild(node.name), - value: convertChild(node.initializer), - computed: isComputedProperty(node.name), - static: hasModifier(SyntaxKind.StaticKeyword, node), - readonly: hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined - }); - - if (node.type) { - result.typeAnnotation = convertTypeAnnotation(node.type); - } - - if (node.decorators) { - result.decorators = node.decorators.map(convertChild); - } - - const accessibility = getTSNodeAccessibility(node); - if (accessibility) { - result.accessibility = accessibility; - } - - if (node.name.kind === SyntaxKind.Identifier && node.questionToken) { - result.optional = true; - } - if (node.exclamationToken) { - (result as any).definite = true; - } + case SyntaxKind.ThisKeyword: + return this.createNode(node, { + type: AST_NODE_TYPES.ThisExpression + }); - if ( - (result as any).key.type === AST_NODE_TYPES.Literal && - node.questionToken - ) { - result.optional = true; + case SyntaxKind.ArrayLiteralExpression: { + // TypeScript uses ArrayLiteralExpression in destructuring assignment, too + if (this.allowPattern) { + return this.createNode(node, { + type: AST_NODE_TYPES.ArrayPattern, + elements: node.elements.map(el => this.convertPattern(el)) + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.ArrayExpression, + elements: node.elements.map(el => this.convertChild(el)) + }); + } } - break; - } - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.MethodDeclaration: { - const method: ESTreeNode = { - type: AST_NODE_TYPES.FunctionExpression, - id: null, - generator: !!node.asteriskToken, - expression: false, // ESTreeNode as ESTreeNode here - async: hasModifier(SyntaxKind.AsyncKeyword, node), - body: convertChild(node.body), - range: [node.parameters.pos - 1, result.range[1]], - loc: { - start: getLineAndCharacterFor(node.parameters.pos - 1, ast), - end: result.loc.end + case SyntaxKind.ObjectLiteralExpression: { + // TypeScript uses ObjectLiteralExpression in destructuring assignment, too + if (this.allowPattern) { + return this.createNode(node, { + type: AST_NODE_TYPES.ObjectPattern, + properties: node.properties.map(el => this.convertPattern(el)) + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.ObjectExpression, + properties: node.properties.map(el => this.convertChild(el)) + }); } - } as any; - - if (node.type) { - (method as any).returnType = convertTypeAnnotation(node.type); } - if (parent!.kind === SyntaxKind.ObjectLiteralExpression) { - (method as any).params = node.parameters.map(convertChild); - - Object.assign(result, { + case SyntaxKind.PropertyAssignment: + return this.createNode(node, { type: AST_NODE_TYPES.Property, - key: convertChild(node.name), - value: method, + key: this.convertChild(node.name), + value: this.converter( + node.initializer, + node, + this.inTypeMode, + this.allowPattern + ), computed: isComputedProperty(node.name), - method: node.kind === SyntaxKind.MethodDeclaration, + method: false, shorthand: false, kind: 'init' }); - } else { - // class - /** - * Unlike in object literal methods, class method params can have decorators - */ - (method as any).params = convertParameters(node.parameters); + case SyntaxKind.ShorthandPropertyAssignment: { + if (node.objectAssignmentInitializer) { + return this.createNode(node, { + type: AST_NODE_TYPES.Property, + key: this.convertChild(node.name), + value: this.createNode(node, { + type: AST_NODE_TYPES.AssignmentPattern, + left: this.convertPattern(node.name), + right: this.convertChild(node.objectAssignmentInitializer) + }), + computed: false, + method: false, + shorthand: true, + kind: 'init' + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.Property, + key: this.convertChild(node.name), + value: this.convertChild(node.name), + computed: false, + method: false, + shorthand: true, + kind: 'init' + }); + } + } - /** - * TypeScript class methods can be defined as "abstract" - */ - const methodDefinitionType = hasModifier( - SyntaxKind.AbstractKeyword, - node - ) - ? AST_NODE_TYPES.TSAbstractMethodDefinition - : AST_NODE_TYPES.MethodDefinition; - - Object.assign(result, { - type: methodDefinitionType, - key: convertChild(node.name), - value: method, + case SyntaxKind.ComputedPropertyName: + return this.convertChild(node.expression); + + case SyntaxKind.PropertyDeclaration: { + const isAbstract = hasModifier(SyntaxKind.AbstractKeyword, node); + const result = this.createNode(node, { + type: isAbstract + ? AST_NODE_TYPES.TSAbstractClassProperty + : AST_NODE_TYPES.ClassProperty, + key: this.convertChild(node.name), + value: this.convertChild(node.initializer), computed: isComputedProperty(node.name), static: hasModifier(SyntaxKind.StaticKeyword, node), - kind: 'method' + readonly: hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined }); + if (node.type) { + result.typeAnnotation = this.convertTypeAnnotation(node.type, node); + } + if (node.decorators) { - result.decorators = node.decorators.map(convertChild); + result.decorators = node.decorators.map(el => this.convertChild(el)); } const accessibility = getTSNodeAccessibility(node); if (accessibility) { result.accessibility = accessibility; } - } - if ( - (result as any).key.type === AST_NODE_TYPES.Identifier && - node.questionToken - ) { - (result as any).key.optional = true; - } + if (node.name.kind === SyntaxKind.Identifier && node.questionToken) { + result.optional = true; + } - if (node.kind === SyntaxKind.GetAccessor) { - (result as any).kind = 'get'; - } else if (node.kind === SyntaxKind.SetAccessor) { - (result as any).kind = 'set'; - } else if ( - !(result as any).static && - node.name.kind === SyntaxKind.StringLiteral && - node.name.text === 'constructor' && - result.type !== AST_NODE_TYPES.Property - ) { - (result as any).kind = 'constructor'; - } + if (node.exclamationToken) { + result.definite = true; + } - // Process typeParameters - if (node.typeParameters && node.typeParameters.length) { - if (result.type !== AST_NODE_TYPES.Property) { - method.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); - } else { - result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); + if (result.key.type === AST_NODE_TYPES.Literal && node.questionToken) { + result.optional = true; } - } + return result; + } + + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.MethodDeclaration: { + const method = this.createNode(node, { + type: AST_NODE_TYPES.FunctionExpression, + id: null, + generator: !!node.asteriskToken, + expression: false, // ESTreeNode as ESTreeNode here + async: hasModifier(SyntaxKind.AsyncKeyword, node), + body: this.convertChild(node.body), + range: [node.parameters.pos - 1, node.end], + params: [] + }); - break; - } + if (node.type) { + (method as any).returnType = this.convertTypeAnnotation( + node.type, + node + ); + } - // TypeScript uses this even for static methods named "constructor" - case SyntaxKind.Constructor: { - const lastModifier = getLastModifier(node); - const constructorToken = - (lastModifier && findNextToken(lastModifier, node, ast)) || - node.getFirstToken()!; - - const constructorTokenRange = [ - constructorToken.getStart(ast), - constructorToken.end - ]; - - const constructor: ESTreeNode = { - type: AST_NODE_TYPES.FunctionExpression, - id: null, - params: convertParameters(node.parameters), - generator: false, - expression: false, // is not present in ESTreeNode - async: false, - body: convertChild(node.body), - range: [node.parameters.pos - 1, result.range[1]], - loc: { - start: getLineAndCharacterFor(node.parameters.pos - 1, ast), - end: result.loc.end - } - } as any; - - // Process typeParameters - if (node.typeParameters && node.typeParameters.length) { - constructor.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); - } + let result: es.Property | es.MethodDefinition; - // Process returnType - if (node.type) { - constructor.returnType = convertTypeAnnotation(node.type); - } + if (parent!.kind === SyntaxKind.ObjectLiteralExpression) { + (method as any).params = node.parameters.map(el => + this.convertChild(el) + ); - const constructorKey = { - type: AST_NODE_TYPES.Identifier, - name: 'constructor', - range: constructorTokenRange, - loc: getLocFor(constructorTokenRange[0], constructorTokenRange[1], ast) - }; + result = this.createNode(node, { + type: AST_NODE_TYPES.Property, + key: this.convertChild(node.name), + value: method, + computed: isComputedProperty(node.name), + method: node.kind === SyntaxKind.MethodDeclaration, + shorthand: false, + kind: 'init' + }); + } else { + // class + + /** + * Unlike in object literal methods, class method params can have decorators + */ + (method as any).params = this.convertParameters(node.parameters); + + /** + * TypeScript class methods can be defined as "abstract" + */ + const methodDefinitionType = hasModifier( + SyntaxKind.AbstractKeyword, + node + ) + ? AST_NODE_TYPES.TSAbstractMethodDefinition + : AST_NODE_TYPES.MethodDefinition; + + result = this.createNode(node, { + type: methodDefinitionType, + key: this.convertChild(node.name), + value: method, + computed: isComputedProperty(node.name), + static: hasModifier(SyntaxKind.StaticKeyword, node), + kind: 'method' + }); - const isStatic = hasModifier(SyntaxKind.StaticKeyword, node); + if (node.decorators) { + result.decorators = node.decorators.map(el => + this.convertChild(el) + ); + } - Object.assign(result, { - type: hasModifier(SyntaxKind.AbstractKeyword, node) - ? AST_NODE_TYPES.TSAbstractMethodDefinition - : AST_NODE_TYPES.MethodDefinition, - key: constructorKey, - value: constructor, - computed: false, - static: isStatic, - kind: isStatic ? 'method' : 'constructor' - }); + const accessibility = getTSNodeAccessibility(node); + if (accessibility) { + result.accessibility = accessibility; + } + } - const accessibility = getTSNodeAccessibility(node); - if (accessibility) { - result.accessibility = accessibility; - } + if ( + result.key.type === AST_NODE_TYPES.Identifier && + node.questionToken + ) { + result.key.optional = true; + } - break; - } + if (node.kind === SyntaxKind.GetAccessor) { + result.kind = 'get'; + } else if (node.kind === SyntaxKind.SetAccessor) { + result.kind = 'set'; + } else if ( + !(result as es.MethodDefinition).static && + node.name.kind === SyntaxKind.StringLiteral && + node.name.text === 'constructor' && + result.type !== AST_NODE_TYPES.Property + ) { + result.kind = 'constructor'; + } - case SyntaxKind.FunctionExpression: - Object.assign(result, { - type: AST_NODE_TYPES.FunctionExpression, - id: convertChild(node.name), - generator: !!node.asteriskToken, - params: convertParameters(node.parameters), - body: convertChild(node.body), - async: hasModifier(SyntaxKind.AsyncKeyword, node), - expression: false - }); + // Process typeParameters + if (node.typeParameters && node.typeParameters.length) { + if (result.type !== AST_NODE_TYPES.Property) { + method.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); + } else { + result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); + } + } + return result; + } + + // TypeScript uses this even for static methods named "constructor" + case SyntaxKind.Constructor: { + const lastModifier = getLastModifier(node); + const constructorToken = + (lastModifier && findNextToken(lastModifier, node, this.ast)) || + node.getFirstToken()!; + + const constructor = this.createNode(node, { + type: AST_NODE_TYPES.FunctionExpression, + id: null, + params: this.convertParameters(node.parameters), + generator: false, + expression: false, // is not present in ESTreeNode + async: false, + body: this.convertChild(node.body), + range: [node.parameters.pos - 1, node.end] + }); - // Process returnType - if (node.type) { - result.returnType = convertTypeAnnotation(node.type); - } + // Process typeParameters + if (node.typeParameters && node.typeParameters.length) { + constructor.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); + } - // Process typeParameters - if (node.typeParameters && node.typeParameters.length) { - result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); - } - break; + // Process returnType + if (node.type) { + constructor.returnType = this.convertTypeAnnotation(node.type, node); + } - case SyntaxKind.SuperKeyword: - Object.assign(result, { - type: AST_NODE_TYPES.Super - }); - break; + const constructorKey = this.createNode(node, { + type: AST_NODE_TYPES.Identifier, + name: 'constructor', + range: [constructorToken.getStart(this.ast), constructorToken.end] + }); - case SyntaxKind.ArrayBindingPattern: - Object.assign(result, { - type: AST_NODE_TYPES.ArrayPattern, - elements: node.elements.map(convertPattern) - }); - break; + const isStatic = hasModifier(SyntaxKind.StaticKeyword, node); + const result = this.createNode(node, { + type: hasModifier(SyntaxKind.AbstractKeyword, node) + ? AST_NODE_TYPES.TSAbstractMethodDefinition + : AST_NODE_TYPES.MethodDefinition, + key: constructorKey, + value: constructor, + computed: false, + static: isStatic, + kind: isStatic ? 'method' : 'constructor' + }); - // occurs with missing array elements like [,] - case SyntaxKind.OmittedExpression: - return null; + const accessibility = getTSNodeAccessibility(node); + if (accessibility) { + result.accessibility = accessibility; + } - case SyntaxKind.ObjectBindingPattern: - Object.assign(result, { - type: AST_NODE_TYPES.ObjectPattern, - properties: node.elements.map(convertPattern) - }); - break; + return result; + } - case SyntaxKind.BindingElement: - if (parent!.kind === SyntaxKind.ArrayBindingPattern) { - const arrayItem = convert({ - node: node.name, - parent, - ast, - additionalOptions + case SyntaxKind.FunctionExpression: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.FunctionExpression, + id: this.convertChild(node.name), + generator: !!node.asteriskToken, + params: this.convertParameters(node.parameters), + body: this.convertChild(node.body), + async: hasModifier(SyntaxKind.AsyncKeyword, node), + expression: false }); - if (node.initializer) { - Object.assign(result, { - type: AST_NODE_TYPES.AssignmentPattern, - left: arrayItem, - right: convertChild(node.initializer) - }); - } else if (node.dotDotDotToken) { - Object.assign(result, { - type: AST_NODE_TYPES.RestElement, - argument: arrayItem - }); - } else { - return arrayItem; - } - } else if (parent!.kind === SyntaxKind.ObjectBindingPattern) { - if (node.dotDotDotToken) { - Object.assign(result, { - type: AST_NODE_TYPES.RestElement, - argument: convertChild(node.propertyName || node.name) - }); - } else { - Object.assign(result, { - type: AST_NODE_TYPES.Property, - key: convertChild(node.propertyName || node.name), - value: convertChild(node.name), - computed: Boolean( - node.propertyName && - node.propertyName.kind === SyntaxKind.ComputedPropertyName - ), - method: false, - shorthand: !node.propertyName, - kind: 'init' - }); + // Process returnType + if (node.type) { + result.returnType = this.convertTypeAnnotation(node.type, node); } - if (node.initializer) { - (result as any).value = { - type: AST_NODE_TYPES.AssignmentPattern, - left: convertChild(node.name), - right: convertChild(node.initializer), - range: [node.name.getStart(ast), node.initializer.end], - loc: getLocFor(node.name.getStart(ast), node.initializer.end, ast) - }; + // Process typeParameters + if (node.typeParameters && node.typeParameters.length) { + result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); } - } - break; - - case SyntaxKind.ArrowFunction: - Object.assign(result, { - type: AST_NODE_TYPES.ArrowFunctionExpression, - generator: false, - id: null, - params: convertParameters(node.parameters), - body: convertChild(node.body), - async: hasModifier(SyntaxKind.AsyncKeyword, node), - expression: node.body.kind !== SyntaxKind.Block - }); - - // Process returnType - if (node.type) { - result.returnType = convertTypeAnnotation(node.type); + return result; } - // Process typeParameters - if (node.typeParameters && node.typeParameters.length) { - result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); - } - break; + case SyntaxKind.SuperKeyword: + return this.createNode(node, { + type: AST_NODE_TYPES.Super + }); - case SyntaxKind.YieldExpression: - Object.assign(result, { - type: AST_NODE_TYPES.YieldExpression, - delegate: !!node.asteriskToken, - argument: convertChild(node.expression) - }); - break; + case SyntaxKind.ArrayBindingPattern: + return this.createNode(node, { + type: AST_NODE_TYPES.ArrayPattern, + elements: node.elements.map(el => this.convertPattern(el)) + }); - case SyntaxKind.AwaitExpression: - Object.assign(result, { - type: AST_NODE_TYPES.AwaitExpression, - argument: convertChild(node.expression) - }); - break; + // occurs with missing array elements like [,] + case SyntaxKind.OmittedExpression: + return null; - // Template Literals + case SyntaxKind.ObjectBindingPattern: + return this.createNode(node, { + type: AST_NODE_TYPES.ObjectPattern, + properties: node.elements.map(el => this.convertPattern(el)) + }); - case SyntaxKind.NoSubstitutionTemplateLiteral: - Object.assign(result, { - type: AST_NODE_TYPES.TemplateLiteral, - quasis: [ - { - type: AST_NODE_TYPES.TemplateElement, - value: { - raw: ast.text.slice(node.getStart(ast) + 1, node.end - 1), - cooked: node.text - }, - tail: true, - range: result.range, - loc: result.loc + case SyntaxKind.BindingElement: { + if (parent!.kind === SyntaxKind.ArrayBindingPattern) { + const arrayItem = this.convertChild(node.name, parent); + + if (node.initializer) { + return this.createNode(node, { + type: AST_NODE_TYPES.AssignmentPattern, + left: arrayItem, + right: this.convertChild(node.initializer) + }); + } else if (node.dotDotDotToken) { + return this.createNode(node, { + type: AST_NODE_TYPES.RestElement, + argument: arrayItem + }); + } else { + return arrayItem; + } + } else if (parent!.kind === SyntaxKind.ObjectBindingPattern) { + let result: es.RestElement | es.Property; + if (node.dotDotDotToken) { + result = this.createNode(node, { + type: AST_NODE_TYPES.RestElement, + argument: this.convertChild(node.propertyName || node.name) + }); + } else { + result = this.createNode(node, { + type: AST_NODE_TYPES.Property, + key: this.convertChild(node.propertyName || node.name), + value: this.convertChild(node.name), + computed: Boolean( + node.propertyName && + node.propertyName.kind === SyntaxKind.ComputedPropertyName + ), + method: false, + shorthand: !node.propertyName, + kind: 'init' + }); } - ], - expressions: [] - }); - break; - case SyntaxKind.TemplateExpression: - Object.assign(result, { - type: AST_NODE_TYPES.TemplateLiteral, - quasis: [convertChild(node.head)], - expressions: [] - }); + if (node.initializer) { + result.value = this.createNode(node, { + type: AST_NODE_TYPES.AssignmentPattern, + left: this.convertChild(node.name), + right: this.convertChild(node.initializer), + range: [node.name.getStart(this.ast), node.initializer.end] + }); + } + return result; + } + return null; + } + + case SyntaxKind.ArrowFunction: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.ArrowFunctionExpression, + generator: false, + id: null, + params: this.convertParameters(node.parameters), + body: this.convertChild(node.body), + async: hasModifier(SyntaxKind.AsyncKeyword, node), + expression: node.body.kind !== SyntaxKind.Block + }); - node.templateSpans.forEach(templateSpan => { - (result as any).expressions.push(convertChild(templateSpan.expression)); - (result as any).quasis.push(convertChild(templateSpan.literal)); - }); - break; - - case SyntaxKind.TaggedTemplateExpression: - Object.assign(result, { - type: AST_NODE_TYPES.TaggedTemplateExpression, - typeParameters: node.typeArguments - ? convertTypeArgumentsToTypeParameters(node.typeArguments) - : undefined, - tag: convertChild(node.tag), - quasi: convertChild(node.template) - }); - break; - - case SyntaxKind.TemplateHead: - case SyntaxKind.TemplateMiddle: - case SyntaxKind.TemplateTail: { - const tail = node.kind === SyntaxKind.TemplateTail; - Object.assign(result, { - type: AST_NODE_TYPES.TemplateElement, - value: { - raw: ast.text.slice( - node.getStart(ast) + 1, - node.end - (tail ? 1 : 2) - ), - cooked: node.text - }, - tail - }); - break; - } + // Process returnType + if (node.type) { + result.returnType = this.convertTypeAnnotation(node.type, node); + } - // Patterns + // Process typeParameters + if (node.typeParameters && node.typeParameters.length) { + result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); + } + return result; + } - case SyntaxKind.SpreadAssignment: - case SyntaxKind.SpreadElement: { - if (config.allowPattern) { - Object.assign(result, { - type: AST_NODE_TYPES.RestElement, - argument: convertPattern(node.expression) + case SyntaxKind.YieldExpression: + return this.createNode(node, { + type: AST_NODE_TYPES.YieldExpression, + delegate: !!node.asteriskToken, + argument: this.convertChild(node.expression) }); - } else { - Object.assign(result, { - type: AST_NODE_TYPES.SpreadElement, - argument: convertChild(node.expression) - }); - } - break; - } - case SyntaxKind.Parameter: { - let parameter: ESTreeNode; + case SyntaxKind.AwaitExpression: + return this.createNode(node, { + type: AST_NODE_TYPES.AwaitExpression, + argument: this.convertChild(node.expression) + }); - if (node.dotDotDotToken) { - Object.assign(result, { - type: AST_NODE_TYPES.RestElement, - argument: convertChild(node.name) + // Template Literals + + case SyntaxKind.NoSubstitutionTemplateLiteral: + return this.createNode(node, { + type: AST_NODE_TYPES.TemplateLiteral, + quasis: [ + this.createNode(node, { + type: AST_NODE_TYPES.TemplateElement, + value: { + raw: this.ast.text.slice( + node.getStart(this.ast) + 1, + node.end - 1 + ), + cooked: node.text + }, + tail: true + }) + ], + expressions: [] }); - parameter = result; - } else if (node.initializer) { - parameter = convertChild(node.name)!; - Object.assign(result, { - type: AST_NODE_TYPES.AssignmentPattern, - left: parameter, - right: convertChild(node.initializer) + + case SyntaxKind.TemplateExpression: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.TemplateLiteral, + quasis: [this.convertChild(node.head)], + expressions: [] }); - if (node.modifiers) { - // AssignmentPattern should not contain modifiers in range - result.range[0] = parameter.range[0]; - result.loc = getLocFor(result.range[0], result.range[1], ast); - } - } else { - parameter = result = convert({ - node: node.name, - parent, - ast, - additionalOptions - })!; - } - - if (node.type) { - parameter.typeAnnotation = convertTypeAnnotation(node.type); - fixTypeAnnotationParentLocation(parameter); - } - - if (node.questionToken) { - if (node.questionToken.end > parameter.range[1]) { - parameter.range[1] = node.questionToken.end; - parameter.loc = getLocFor( - parameter.range[0], - parameter.range[1], - ast - ); - } - parameter.optional = true; + node.templateSpans.forEach(templateSpan => { + result.expressions.push(this.convertChild(templateSpan.expression)); + result.quasis.push(this.convertChild(templateSpan.literal)); + }); + return result; } - if (node.modifiers) { - return { - type: AST_NODE_TYPES.TSParameterProperty, - range: [node.getStart(ast), node.end], - loc: getLoc(node, ast), - accessibility: getTSNodeAccessibility(node) || undefined, - readonly: hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined, - static: hasModifier(SyntaxKind.StaticKeyword, node) || undefined, - export: hasModifier(SyntaxKind.ExportKeyword, node) || undefined, - parameter: result - }; + case SyntaxKind.TaggedTemplateExpression: + return this.createNode(node, { + type: AST_NODE_TYPES.TaggedTemplateExpression, + typeParameters: node.typeArguments + ? this.convertTypeArgumentsToTypeParameters(node.typeArguments) + : undefined, + tag: this.convertChild(node.tag), + quasi: this.convertChild(node.template) + }); + + case SyntaxKind.TemplateHead: + case SyntaxKind.TemplateMiddle: + case SyntaxKind.TemplateTail: { + const tail = node.kind === SyntaxKind.TemplateTail; + return this.createNode(node, { + type: AST_NODE_TYPES.TemplateElement, + value: { + raw: this.ast.text.slice( + node.getStart(this.ast) + 1, + node.end - (tail ? 1 : 2) + ), + cooked: node.text + }, + tail + }); } - break; - } + // Patterns - // Classes + case SyntaxKind.SpreadAssignment: + case SyntaxKind.SpreadElement: { + if (this.allowPattern) { + return this.createNode(node, { + type: AST_NODE_TYPES.RestElement, + argument: this.convertPattern(node.expression) + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.SpreadElement, + argument: this.convertChild(node.expression) + }); + } + } - case SyntaxKind.ClassDeclaration: - case SyntaxKind.ClassExpression: { - const heritageClauses = node.heritageClauses || []; - let classNodeType = SyntaxKind[node.kind]; + case SyntaxKind.Parameter: { + let parameter: any; + let result: es.RestElement | es.AssignmentPattern; - if (node.typeParameters && node.typeParameters.length) { - result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); - } + if (node.dotDotDotToken) { + parameter = result = this.createNode(node, { + type: AST_NODE_TYPES.RestElement, + argument: this.convertChild(node.name) + }); + } else if (node.initializer) { + parameter = this.convertChild(node.name)!; + result = this.createNode(node, { + type: AST_NODE_TYPES.AssignmentPattern, + left: parameter, + right: this.convertChild(node.initializer) + }); - const superClass = heritageClauses.find( - clause => clause.token === SyntaxKind.ExtendsKeyword - ); + if (node.modifiers) { + // AssignmentPattern should not contain modifiers in range + result.range![0] = parameter.range[0]; + result.loc = getLocFor( + result.range![0], + result.range![1], + this.ast + ); + } + } else { + parameter = result = this.convertChild(node.name, parent)!; + } - if (superClass) { - if (superClass.types.length > 1) { - throw createError( - ast, - superClass.types[1].pos, - 'Classes can only extend a single class.' + if (node.type) { + parameter.typeAnnotation = this.convertTypeAnnotation( + node.type, + node ); + this.fixTypeAnnotationParentLocation(parameter, node.type); } - if (superClass.types[0] && superClass.types[0].typeArguments) { - (result as any).superTypeParameters = convertTypeArgumentsToTypeParameters( - superClass.types[0].typeArguments - ); + if (node.questionToken) { + if (node.questionToken.end > parameter.range[1]) { + parameter.range[1] = node.questionToken.end; + parameter.loc.end = getLineAndCharacterFor( + parameter.range[1], + this.ast + ); + } + parameter.optional = true; + } + + if (node.modifiers) { + return this.createNode(node, { + type: AST_NODE_TYPES.TSParameterProperty, + accessibility: getTSNodeAccessibility(node) || undefined, + readonly: + hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined, + static: hasModifier(SyntaxKind.StaticKeyword, node) || undefined, + export: hasModifier(SyntaxKind.ExportKeyword, node) || undefined, + parameter: result + }); } + return result; } - const implementsClause = heritageClauses.find( - clause => clause.token === SyntaxKind.ImplementsKeyword - ); + // Classes - const classBodyRange = [node.members.pos - 1, node.end]; - - Object.assign(result, { - type: classNodeType, - id: convertChild(node.name), - body: { - type: AST_NODE_TYPES.ClassBody, - body: [], - range: classBodyRange, - loc: getLocFor(classBodyRange[0], classBodyRange[1], ast) - }, - superClass: - superClass && superClass.types[0] - ? convertChild(superClass.types[0].expression) - : null - }); + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: { + const heritageClauses = node.heritageClauses || []; + let classNodeType = + node.kind === SyntaxKind.ClassDeclaration + ? AST_NODE_TYPES.ClassDeclaration + : AST_NODE_TYPES.ClassExpression; - if (implementsClause) { - result.implements = implementsClause.types.map(convertChild); - } + const superClass = heritageClauses.find( + clause => clause.token === SyntaxKind.ExtendsKeyword + ); - /** - * TypeScript class declarations can be defined as "abstract" - */ - if (hasModifier(SyntaxKind.AbstractKeyword, node)) { - result.abstract = true; - } + const implementsClause = heritageClauses.find( + clause => clause.token === SyntaxKind.ImplementsKeyword + ); - if (hasModifier(SyntaxKind.DeclareKeyword, node)) { - result.declare = true; - } + const result = this.createNode(node, { + type: classNodeType, + id: this.convertChild(node.name), + body: this.createNode(node, { + type: AST_NODE_TYPES.ClassBody, + body: [], + range: [node.members.pos - 1, node.end] + }), + superClass: + superClass && superClass.types[0] + ? this.convertChild(superClass.types[0].expression) + : null + }); - if (node.decorators) { - result.decorators = node.decorators.map(convertChild); - } + if (superClass) { + if (superClass.types.length > 1) { + throw createError( + this.ast, + superClass.types[1].pos, + 'Classes can only extend a single class.' + ); + } - const filteredMembers = node.members.filter(isESTreeClassMember); + if (superClass.types[0] && superClass.types[0].typeArguments) { + result.superTypeParameters = this.convertTypeArgumentsToTypeParameters( + superClass.types[0].typeArguments + ); + } + } - if (filteredMembers.length) { - result.body.body = filteredMembers.map(convertChild); - } + if (node.typeParameters && node.typeParameters.length) { + result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); + } - // check for exports - result = fixExports(node, result, ast); + if (implementsClause) { + result.implements = implementsClause.types.map(el => + this.convertChild(el) + ); + } - break; - } + /** + * TypeScript class declarations can be defined as "abstract" + */ + if (hasModifier(SyntaxKind.AbstractKeyword, node)) { + result.abstract = true; + } - // Modules - case SyntaxKind.ModuleBlock: - Object.assign(result, { - type: AST_NODE_TYPES.TSModuleBlock, - body: convertBodyExpressions(node.statements) - }); - break; + if (hasModifier(SyntaxKind.DeclareKeyword, node)) { + result.declare = true; + } - case SyntaxKind.ImportDeclaration: - Object.assign(result, { - type: AST_NODE_TYPES.ImportDeclaration, - source: convertChild(node.moduleSpecifier), - specifiers: [] - }); + if (node.decorators) { + result.decorators = node.decorators.map(el => this.convertChild(el)); + } - if (node.importClause) { - if (node.importClause.name) { - result.specifiers!.push(convertChild(node.importClause)); - } - - if (node.importClause.namedBindings) { - switch (node.importClause.namedBindings.kind) { - case SyntaxKind.NamespaceImport: - result.specifiers!.push( - convertChild(node.importClause.namedBindings) - ); - break; - case SyntaxKind.NamedImports: - result.specifiers = result.specifiers!.concat( - node.importClause.namedBindings.elements.map(convertChild) - ); - break; - } + const filteredMembers = node.members.filter(isESTreeClassMember); + + if (filteredMembers.length) { + result.body.body = filteredMembers.map(el => this.convertChild(el)); } + + // check for exports + return fixExports(node, result, this.ast); } - break; - case SyntaxKind.NamespaceImport: - Object.assign(result, { - type: AST_NODE_TYPES.ImportNamespaceSpecifier, - local: convertChild(node.name) - }); - break; + // Modules + case SyntaxKind.ModuleBlock: + return this.createNode(node, { + type: AST_NODE_TYPES.TSModuleBlock, + body: this.convertBodyExpressions(node.statements, node) + }); - case SyntaxKind.ImportSpecifier: - Object.assign(result, { - type: AST_NODE_TYPES.ImportSpecifier, - local: convertChild(node.name), - imported: convertChild(node.propertyName || node.name) - }); - break; + case SyntaxKind.ImportDeclaration: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.ImportDeclaration, + source: this.convertChild(node.moduleSpecifier), + specifiers: [] + }); - case SyntaxKind.ImportClause: - Object.assign(result, { - type: AST_NODE_TYPES.ImportDefaultSpecifier, - local: convertChild(node.name) - }); + if (node.importClause) { + if (node.importClause.name) { + result.specifiers!.push(this.convertChild(node.importClause)); + } - // have to adjust location information due to tree differences - result.range[1] = node.name!.end; - result.loc = getLocFor(result.range[0], result.range[1], ast); - break; + if (node.importClause.namedBindings) { + switch (node.importClause.namedBindings.kind) { + case SyntaxKind.NamespaceImport: + result.specifiers!.push( + this.convertChild(node.importClause.namedBindings) + ); + break; + case SyntaxKind.NamedImports: + result.specifiers = result.specifiers!.concat( + node.importClause.namedBindings.elements.map(el => + this.convertChild(el) + ) + ); + break; + } + } + } + return result; + } - case SyntaxKind.ExportDeclaration: - if (node.exportClause) { - Object.assign(result, { - type: AST_NODE_TYPES.ExportNamedDeclaration, - source: convertChild(node.moduleSpecifier), - specifiers: node.exportClause.elements.map(convertChild), - declaration: null - }); - } else { - Object.assign(result, { - type: AST_NODE_TYPES.ExportAllDeclaration, - source: convertChild(node.moduleSpecifier) + case SyntaxKind.NamespaceImport: + return this.createNode(node, { + type: AST_NODE_TYPES.ImportNamespaceSpecifier, + local: this.convertChild(node.name) }); - } - break; - case SyntaxKind.ExportSpecifier: - Object.assign(result, { - type: AST_NODE_TYPES.ExportSpecifier, - local: convertChild(node.propertyName || node.name), - exported: convertChild(node.name) - }); - break; + case SyntaxKind.ImportSpecifier: + return this.createNode(node, { + type: AST_NODE_TYPES.ImportSpecifier, + local: this.convertChild(node.name), + imported: this.convertChild(node.propertyName || node.name) + }); - case SyntaxKind.ExportAssignment: - if (node.isExportEquals) { - Object.assign(result, { - type: AST_NODE_TYPES.TSExportAssignment, - expression: convertChild(node.expression) + case SyntaxKind.ImportClause: + return this.createNode(node, { + type: AST_NODE_TYPES.ImportDefaultSpecifier, + local: this.convertChild(node.name), + range: [node.getStart(this.ast), node.name!.end] }); - } else { - Object.assign(result, { - type: AST_NODE_TYPES.ExportDefaultDeclaration, - declaration: convertChild(node.expression) + + case SyntaxKind.ExportDeclaration: + if (node.exportClause) { + return this.createNode(node, { + type: AST_NODE_TYPES.ExportNamedDeclaration, + source: this.convertChild(node.moduleSpecifier), + specifiers: node.exportClause.elements.map(el => + this.convertChild(el) + ), + declaration: null + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.ExportAllDeclaration, + source: this.convertChild(node.moduleSpecifier) + }); + } + + case SyntaxKind.ExportSpecifier: + return this.createNode(node, { + type: AST_NODE_TYPES.ExportSpecifier, + local: this.convertChild(node.propertyName || node.name), + exported: this.convertChild(node.name) }); - } - break; - // Unary Operations + case SyntaxKind.ExportAssignment: + if (node.isExportEquals) { + return this.createNode(node, { + type: AST_NODE_TYPES.TSExportAssignment, + expression: this.convertChild(node.expression) + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.ExportDefaultDeclaration, + declaration: this.convertChild(node.expression) + }); + } + + // Unary Operations - case SyntaxKind.PrefixUnaryExpression: - case SyntaxKind.PostfixUnaryExpression: { - const operator = getTextForTokenKind(node.operator) || ''; - Object.assign(result, { + case SyntaxKind.PrefixUnaryExpression: + case SyntaxKind.PostfixUnaryExpression: { + const operator = (getTextForTokenKind(node.operator) || '') as any; /** * ESTree uses UpdateExpression for ++/-- */ - type: /^(?:\+\+|--)$/.test(operator) - ? AST_NODE_TYPES.UpdateExpression - : AST_NODE_TYPES.UnaryExpression, - operator, - prefix: node.kind === SyntaxKind.PrefixUnaryExpression, - argument: convertChild(node.operand) - }); - break; - } + if (/^(?:\+\+|--)$/.test(operator)) { + return this.createNode(node, { + type: AST_NODE_TYPES.UpdateExpression, + operator, + prefix: node.kind === SyntaxKind.PrefixUnaryExpression, + argument: this.convertChild(node.operand) + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.UnaryExpression, + operator, + prefix: node.kind === SyntaxKind.PrefixUnaryExpression, + argument: this.convertChild(node.operand) + }); + } + } - case SyntaxKind.DeleteExpression: - Object.assign(result, { - type: AST_NODE_TYPES.UnaryExpression, - operator: 'delete', - prefix: true, - argument: convertChild(node.expression) - }); - break; - - case SyntaxKind.VoidExpression: - Object.assign(result, { - type: AST_NODE_TYPES.UnaryExpression, - operator: 'void', - prefix: true, - argument: convertChild(node.expression) - }); - break; - - case SyntaxKind.TypeOfExpression: - Object.assign(result, { - type: AST_NODE_TYPES.UnaryExpression, - operator: 'typeof', - prefix: true, - argument: convertChild(node.expression) - }); - break; + case SyntaxKind.DeleteExpression: + return this.createNode(node, { + type: AST_NODE_TYPES.UnaryExpression, + operator: 'delete', + prefix: true, + argument: this.convertChild(node.expression) + }); - case SyntaxKind.TypeOperator: - Object.assign(result, { - type: AST_NODE_TYPES.TSTypeOperator, - operator: getTextForTokenKind(node.operator), - typeAnnotation: convertChild(node.type) - }); - break; + case SyntaxKind.VoidExpression: + return this.createNode(node, { + type: AST_NODE_TYPES.UnaryExpression, + operator: 'void', + prefix: true, + argument: this.convertChild(node.expression) + }); - // Binary Operations + case SyntaxKind.TypeOfExpression: + return this.createNode(node, { + type: AST_NODE_TYPES.UnaryExpression, + operator: 'typeof', + prefix: true, + argument: this.convertChild(node.expression) + }); - case SyntaxKind.BinaryExpression: - // TypeScript uses BinaryExpression for sequences as well - if (isComma(node.operatorToken)) { - Object.assign(result, { - type: AST_NODE_TYPES.SequenceExpression, - expressions: [] + case SyntaxKind.TypeOperator: + return this.createNode(node, { + type: AST_NODE_TYPES.TSTypeOperator, + operator: getTextForTokenKind(node.operator) as any, + typeAnnotation: this.convertChild(node.type) }); - const left = convertChild(node.left)!, - right = convertChild(node.right)!; + // Binary Operations - if (left.type === AST_NODE_TYPES.SequenceExpression) { - (result as any).expressions = (result as any).expressions.concat( - (left as any).expressions - ); + case SyntaxKind.BinaryExpression: { + // TypeScript uses BinaryExpression for sequences as well + if (isComma(node.operatorToken)) { + const result = this.createNode(node, { + type: AST_NODE_TYPES.SequenceExpression, + expressions: [] + }); + + const left = this.convertChild(node.left)!, + right = this.convertChild(node.right)!; + + if (left.type === AST_NODE_TYPES.SequenceExpression) { + result.expressions = result.expressions.concat( + (left as any).expressions + ); + } else { + result.expressions.push(left); + } + + if (right.type === AST_NODE_TYPES.SequenceExpression) { + result.expressions = result.expressions.concat( + (right as any).expressions + ); + } else { + result.expressions.push(right); + } + return result; } else { - (result as any).expressions.push(left); + const type = getBinaryExpressionType(node.operatorToken); + switch (type) { + case AST_NODE_TYPES.AssignmentExpression: + if (this.allowPattern) { + return this.createNode(node, { + type: AST_NODE_TYPES.AssignmentPattern, + left: this.convertPattern(node.left, node), + right: this.convertChild(node.right) + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.AssignmentExpression, + operator: getTextForTokenKind(node.operatorToken.kind) as any, + left: this.convertPattern(node.left, node), + right: this.convertChild(node.right) + }); + } + case AST_NODE_TYPES.LogicalExpression: + return this.createNode(node, { + type: AST_NODE_TYPES.LogicalExpression, + operator: getTextForTokenKind(node.operatorToken.kind) as any, + left: this.convertChild(node.left, node), + right: this.convertChild(node.right) + }); + default: + case AST_NODE_TYPES.BinaryExpression: + return this.createNode(node, { + type: AST_NODE_TYPES.BinaryExpression, + operator: getTextForTokenKind(node.operatorToken.kind) as any, + left: this.convertChild(node.left, node), + right: this.convertChild(node.right) + }); + } } + } + + case SyntaxKind.PropertyAccessExpression: + if (isJSXToken(parent!)) { + const jsxMemberExpression: es.MemberExpression = { + type: AST_NODE_TYPES.MemberExpression, + object: this.convertChild(node.expression), + property: this.convertChild(node.name) + }; + const isNestedMemberExpression = + node.expression.kind === SyntaxKind.PropertyAccessExpression; + if (node.expression.kind === SyntaxKind.ThisKeyword) { + (jsxMemberExpression as any).object.name = 'this'; + } - if (right.type === AST_NODE_TYPES.SequenceExpression) { - (result as any).expressions = (result as any).expressions.concat( - (right as any).expressions + (jsxMemberExpression as any).object.type = isNestedMemberExpression + ? AST_NODE_TYPES.MemberExpression + : AST_NODE_TYPES.JSXIdentifier; + (jsxMemberExpression as any).property.type = + AST_NODE_TYPES.JSXIdentifier; + return this.createNode( + node, + jsxMemberExpression ); } else { - (result as any).expressions.push(right); - } - } else { - const type = getBinaryExpressionType(node.operatorToken); - Object.assign(result, { - type, - operator: getTextForTokenKind(node.operatorToken.kind), - left: converter( - node.left, - config.inTypeMode, - type === AST_NODE_TYPES.AssignmentExpression - ), - right: convertChild(node.right) - }); - - // if the binary expression is in a destructured array, switch it - if (result.type === AST_NODE_TYPES.AssignmentExpression) { - if (config.allowPattern) { - delete (result as any).operator; - result.type = AST_NODE_TYPES.AssignmentPattern; - } + return this.createNode(node, { + type: AST_NODE_TYPES.MemberExpression, + object: this.convertChild(node.expression), + property: this.convertChild(node.name), + computed: false + }); } - } - break; - case SyntaxKind.PropertyAccessExpression: - if (isJSXToken(parent!)) { - const jsxMemberExpression = { + case SyntaxKind.ElementAccessExpression: + return this.createNode(node, { type: AST_NODE_TYPES.MemberExpression, - object: convertChild(node.expression), - property: convertChild(node.name) - }; - const isNestedMemberExpression = - node.expression.kind === SyntaxKind.PropertyAccessExpression; - if (node.expression.kind === SyntaxKind.ThisKeyword) { - (jsxMemberExpression as any).object.name = 'this'; - } - - (jsxMemberExpression as any).object.type = isNestedMemberExpression - ? AST_NODE_TYPES.MemberExpression - : AST_NODE_TYPES.JSXIdentifier; - (jsxMemberExpression as any).property.type = - AST_NODE_TYPES.JSXIdentifier; - Object.assign(result, jsxMemberExpression); - } else { - Object.assign(result, { - type: AST_NODE_TYPES.MemberExpression, - object: convertChild(node.expression), - property: convertChild(node.name), - computed: false + object: this.convertChild(node.expression), + property: this.convertChild(node.argumentExpression), + computed: true }); - } - break; - case SyntaxKind.ElementAccessExpression: - Object.assign(result, { - type: AST_NODE_TYPES.MemberExpression, - object: convertChild(node.expression), - property: convertChild(node.argumentExpression), - computed: true - }); - break; - - case SyntaxKind.ConditionalExpression: - Object.assign(result, { - type: AST_NODE_TYPES.ConditionalExpression, - test: convertChild(node.condition), - consequent: convertChild(node.whenTrue), - alternate: convertChild(node.whenFalse) - }); - break; + case SyntaxKind.ConditionalExpression: + return this.createNode(node, { + type: AST_NODE_TYPES.ConditionalExpression, + test: this.convertChild(node.condition), + consequent: this.convertChild(node.whenTrue), + alternate: this.convertChild(node.whenFalse) + }); - case SyntaxKind.CallExpression: - Object.assign(result, { - type: AST_NODE_TYPES.CallExpression, - callee: convertChild(node.expression), - arguments: node.arguments.map(convertChild) - }); - if (node.typeArguments && node.typeArguments.length) { - result.typeParameters = convertTypeArgumentsToTypeParameters( - node.typeArguments - ); + case SyntaxKind.CallExpression: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.CallExpression, + callee: this.convertChild(node.expression), + arguments: node.arguments.map(el => this.convertChild(el)) + }); + if (node.typeArguments && node.typeArguments.length) { + result.typeParameters = this.convertTypeArgumentsToTypeParameters( + node.typeArguments + ); + } + return result; } - break; - case SyntaxKind.NewExpression: - Object.assign(result, { - type: AST_NODE_TYPES.NewExpression, - callee: convertChild(node.expression), - arguments: node.arguments ? node.arguments.map(convertChild) : [] - }); - if (node.typeArguments && node.typeArguments.length) { - result.typeParameters = convertTypeArgumentsToTypeParameters( - node.typeArguments - ); + case SyntaxKind.NewExpression: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.NewExpression, + callee: this.convertChild(node.expression), + arguments: node.arguments + ? node.arguments.map(el => this.convertChild(el)) + : [] + }); + if (node.typeArguments && node.typeArguments.length) { + result.typeParameters = this.convertTypeArgumentsToTypeParameters( + node.typeArguments + ); + } + return result; + } + + case SyntaxKind.MetaProperty: { + const newToken = convertToken(node.getFirstToken()!, this.ast); + return this.createNode(node, { + type: AST_NODE_TYPES.MetaProperty, + meta: { + type: AST_NODE_TYPES.Identifier, + range: newToken.range, + loc: newToken.loc, + name: getTextForTokenKind(node.keywordToken)! + }, + property: this.convertChild(node.name) + }); } - break; - - case SyntaxKind.MetaProperty: { - const newToken = convertToken(node.getFirstToken()!, ast); - Object.assign(result, { - type: AST_NODE_TYPES.MetaProperty, - meta: { - type: AST_NODE_TYPES.Identifier, - range: newToken.range, - loc: newToken.loc, - name: getTextForTokenKind(node.keywordToken) - }, - property: convertChild(node.name) - }); - break; - } - - case SyntaxKind.Decorator: { - Object.assign(result, { - type: AST_NODE_TYPES.Decorator, - expression: convertChild(node.expression) - }); - break; - } - // Literals - - case SyntaxKind.StringLiteral: - Object.assign(result, { - type: AST_NODE_TYPES.Literal, - raw: ast.text.slice(result.range[0], result.range[1]) - }); - if ((parent as any).name && (parent as any).name === node) { - (result as any).value = node.text; - } else { - (result as any).value = unescapeStringLiteralText(node.text); - } - break; - - case SyntaxKind.NumericLiteral: { - Object.assign(result, { - type: AST_NODE_TYPES.Literal, - value: Number(node.text), - raw: node.getText() - }); - break; - } + case SyntaxKind.Decorator: { + return this.createNode(node, { + type: AST_NODE_TYPES.Decorator, + expression: this.convertChild(node.expression) + }); + } - case SyntaxKind.BigIntLiteral: { - const raw = ast.text.slice(result.range[0], result.range[1]); - const value = raw.slice(0, -1); // remove suffix `n` - Object.assign(result, { - type: AST_NODE_TYPES.BigIntLiteral, - raw, - value - }); - break; - } + // Literals - case SyntaxKind.RegularExpressionLiteral: { - const pattern = node.text.slice(1, node.text.lastIndexOf('/')); - const flags = node.text.slice(node.text.lastIndexOf('/') + 1); + case SyntaxKind.StringLiteral: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.Literal, + raw: '', + value: '' + }); + result.raw = this.ast.text.slice(result.range![0], result.range![1]); + if ((parent as any).name && (parent as any).name === node) { + result.value = node.text; + } else { + result.value = unescapeStringLiteralText(node.text); + } + return result; + } - let regex = null; - try { - regex = new RegExp(pattern, flags); - } catch (exception) { - regex = null; + case SyntaxKind.NumericLiteral: { + return this.createNode(node, { + type: AST_NODE_TYPES.Literal, + value: Number(node.text), + raw: node.getText() + }); } - Object.assign(result, { - type: AST_NODE_TYPES.Literal, - value: regex, - raw: node.text, - regex: { - pattern, - flags - } - }); - break; - } + case SyntaxKind.BigIntLiteral: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.BigIntLiteral, + raw: '', + value: '' + }); + result.raw = this.ast.text.slice(result.range![0], result.range![1]); + result.value = result.raw.slice(0, -1); // remove suffix `n` + return result; + } - case SyntaxKind.TrueKeyword: - Object.assign(result, { - type: AST_NODE_TYPES.Literal, - value: true, - raw: 'true' - }); - break; + case SyntaxKind.RegularExpressionLiteral: { + const pattern = node.text.slice(1, node.text.lastIndexOf('/')); + const flags = node.text.slice(node.text.lastIndexOf('/') + 1); - case SyntaxKind.FalseKeyword: - Object.assign(result, { - type: AST_NODE_TYPES.Literal, - value: false, - raw: 'false' - }); - break; + let regex = null; + try { + regex = new RegExp(pattern, flags); + } catch (exception) { + regex = null; + } - case SyntaxKind.NullKeyword: { - if (config.inTypeMode) { - Object.assign(result, { - type: AST_NODE_TYPES.TSNullKeyword - }); - } else { - Object.assign(result, { + return this.createNode(node, { type: AST_NODE_TYPES.Literal, - value: null, - raw: 'null' + value: regex, + raw: node.text, + regex: { + pattern, + flags + } }); } - break; - } - case SyntaxKind.ImportKeyword: - Object.assign(result, { - type: AST_NODE_TYPES.Import - }); - break; + case SyntaxKind.TrueKeyword: + return this.createNode(node, { + type: AST_NODE_TYPES.Literal, + value: true, + raw: 'true' + }); - case SyntaxKind.EmptyStatement: - case SyntaxKind.DebuggerStatement: - Object.assign(result, { - type: SyntaxKind[node.kind] - }); - break; + case SyntaxKind.FalseKeyword: + return this.createNode(node, { + type: AST_NODE_TYPES.Literal, + value: false, + raw: 'false' + }); - // JSX + case SyntaxKind.NullKeyword: { + if (this.inTypeMode) { + return this.createNode(node, { + type: AST_NODE_TYPES.TSNullKeyword + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.Literal, + value: null, + raw: 'null' + }); + } + } - case SyntaxKind.JsxElement: - Object.assign(result, { - type: AST_NODE_TYPES.JSXElement, - openingElement: convertChild(node.openingElement), - closingElement: convertChild(node.closingElement), - children: node.children.map(convertChild) - }); + case SyntaxKind.ImportKeyword: + return this.createNode(node, { + type: AST_NODE_TYPES.Import + }); - break; + case SyntaxKind.EmptyStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.EmptyStatement + }); - case SyntaxKind.JsxFragment: - Object.assign(result, { - type: AST_NODE_TYPES.JSXFragment, - openingFragment: convertChild(node.openingFragment), - closingFragment: convertChild(node.closingFragment), - children: node.children.map(convertChild) - }); - break; + case SyntaxKind.DebuggerStatement: + return this.createNode(node, { + type: AST_NODE_TYPES.DebuggerStatement + }); - case SyntaxKind.JsxSelfClosingElement: { - Object.assign(result, { - type: AST_NODE_TYPES.JSXElement, - /** - * Convert SyntaxKind.JsxSelfClosingElement to SyntaxKind.JsxOpeningElement, - * TypeScript does not seem to have the idea of openingElement when tag is self-closing - */ - openingElement: { + // JSX + + case SyntaxKind.JsxElement: + return this.createNode(node, { + type: AST_NODE_TYPES.JSXElement, + openingElement: this.convertChild(node.openingElement), + closingElement: this.convertChild(node.closingElement), + children: node.children.map(el => this.convertChild(el)) + }); + + case SyntaxKind.JsxFragment: + return this.createNode(node, { + type: AST_NODE_TYPES.JSXFragment, + openingFragment: this.convertChild(node.openingFragment), + closingFragment: this.convertChild(node.closingFragment), + children: node.children.map(el => this.convertChild(el)) + }); + + case SyntaxKind.JsxSelfClosingElement: { + return this.createNode(node, { + type: AST_NODE_TYPES.JSXElement, + /** + * Convert SyntaxKind.JsxSelfClosingElement to SyntaxKind.JsxOpeningElement, + * TypeScript does not seem to have the idea of openingElement when tag is self-closing + */ + openingElement: this.createNode(node, { + type: AST_NODE_TYPES.JSXOpeningElement, + typeParameters: node.typeArguments + ? this.convertTypeArgumentsToTypeParameters(node.typeArguments) + : undefined, + selfClosing: true, + name: this.convertTypeScriptJSXTagNameToESTreeName( + node.tagName, + node + ), + attributes: node.attributes.properties.map(el => + this.convertChild(el) + ), + range: getRange(node, this.ast) + }), + closingElement: null, + children: [] + }); + } + + case SyntaxKind.JsxOpeningElement: + return this.createNode(node, { type: AST_NODE_TYPES.JSXOpeningElement, typeParameters: node.typeArguments - ? convertTypeArgumentsToTypeParameters(node.typeArguments) + ? this.convertTypeArgumentsToTypeParameters(node.typeArguments) : undefined, - selfClosing: true, - name: convertTypeScriptJSXTagNameToESTreeName(node.tagName), - attributes: node.attributes.properties.map(convertChild), - range: result.range, - loc: result.loc - }, - closingElement: null, - children: [] - }); - break; - } - - case SyntaxKind.JsxOpeningElement: - Object.assign(result, { - type: AST_NODE_TYPES.JSXOpeningElement, - typeParameters: node.typeArguments - ? convertTypeArgumentsToTypeParameters(node.typeArguments) - : undefined, - selfClosing: false, - name: convertTypeScriptJSXTagNameToESTreeName(node.tagName), - attributes: node.attributes.properties.map(convertChild) - }); - break; - - case SyntaxKind.JsxClosingElement: - Object.assign(result, { - type: AST_NODE_TYPES.JSXClosingElement, - name: convertTypeScriptJSXTagNameToESTreeName(node.tagName) - }); - break; + selfClosing: false, + name: this.convertTypeScriptJSXTagNameToESTreeName( + node.tagName, + node + ), + attributes: node.attributes.properties.map(el => + this.convertChild(el) + ) + }); - case SyntaxKind.JsxOpeningFragment: - Object.assign(result, { - type: AST_NODE_TYPES.JSXOpeningFragment - }); - break; - case SyntaxKind.JsxClosingFragment: - Object.assign(result, { - type: AST_NODE_TYPES.JSXClosingFragment - }); - break; - - case SyntaxKind.JsxExpression: { - const expression = node.expression - ? convertChild(node.expression) - : { - type: AST_NODE_TYPES.JSXEmptyExpression, - loc: { - start: getLineAndCharacterFor(result.range[0] + 1, ast), - end: { - line: result.loc.end.line, - column: result.loc.end.column - 1 - } - }, - range: [result.range[0] + 1, result.range[1] - 1] - }; + case SyntaxKind.JsxClosingElement: + return this.createNode(node, { + type: AST_NODE_TYPES.JSXClosingElement, + name: this.convertTypeScriptJSXTagNameToESTreeName(node.tagName, node) + }); - Object.assign(result, { - type: node.dotDotDotToken - ? AST_NODE_TYPES.JSXSpreadChild - : AST_NODE_TYPES.JSXExpressionContainer, - expression - }); + case SyntaxKind.JsxOpeningFragment: + return this.createNode(node, { + type: AST_NODE_TYPES.JSXOpeningFragment + }); - break; - } + case SyntaxKind.JsxClosingFragment: + return this.createNode(node, { + type: AST_NODE_TYPES.JSXClosingFragment + }); - case SyntaxKind.JsxAttribute: { - const attributeName = convertToken(node.name, ast); - attributeName.type = AST_NODE_TYPES.JSXIdentifier; - attributeName.name = attributeName.value; - delete attributeName.value; + case SyntaxKind.JsxExpression: { + const expression = node.expression + ? this.convertChild(node.expression) + : this.createNode(node, { + type: AST_NODE_TYPES.JSXEmptyExpression, + range: [node.getStart(this.ast) + 1, node.getEnd() - 1] + }); - Object.assign(result, { - type: AST_NODE_TYPES.JSXAttribute, - name: attributeName, - value: convertChild(node.initializer) - }); + if (node.dotDotDotToken) { + return this.createNode(node, { + type: AST_NODE_TYPES.JSXSpreadChild, + expression + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.JSXExpressionContainer, + expression + }); + } + } - break; - } + case SyntaxKind.JsxAttribute: { + const attributeName = convertToken(node.name, this.ast) as any; + attributeName.type = AST_NODE_TYPES.JSXIdentifier; + attributeName.name = attributeName.value; + delete attributeName.value; - /** - * The JSX AST changed the node type for string literals - * inside a JSX Element from `Literal` to `JSXText`. We - * provide a flag to support both types until `Literal` - * node type is deprecated in ESLint v5. - */ - case SyntaxKind.JsxText: { - const start = node.getFullStart(); - const end = node.getEnd(); - - const type = additionalOptions.useJSXTextNode - ? AST_NODE_TYPES.JSXText - : AST_NODE_TYPES.Literal; - - Object.assign(result, { - type, - value: ast.text.slice(start, end), - raw: ast.text.slice(start, end) - }); + return this.createNode(node, { + type: AST_NODE_TYPES.JSXAttribute, + name: attributeName, + value: this.convertChild(node.initializer) + }); + } - result.loc = getLocFor(start, end, ast); - result.range = [start, end]; + /** + * The JSX AST changed the node type for string literals + * inside a JSX Element from `Literal` to `JSXText`. We + * provide a flag to support both types until `Literal` + * node type is deprecated in ESLint v5. + */ + case SyntaxKind.JsxText: { + const start = node.getFullStart(); + const end = node.getEnd(); + + if (this.options.useJSXTextNode) { + return this.createNode(node, { + type: AST_NODE_TYPES.JSXText, + value: this.ast.text.slice(start, end), + raw: this.ast.text.slice(start, end), + range: [start, end] + }); + } else { + return this.createNode(node, { + type: AST_NODE_TYPES.Literal, + value: this.ast.text.slice(start, end), + raw: this.ast.text.slice(start, end), + range: [start, end] + }); + } + } - break; - } + case SyntaxKind.JsxSpreadAttribute: + return this.createNode(node, { + type: AST_NODE_TYPES.JSXSpreadAttribute, + argument: this.convertChild(node.expression) + }); - case SyntaxKind.JsxSpreadAttribute: - Object.assign(result, { - type: AST_NODE_TYPES.JSXSpreadAttribute, - argument: convertChild(node.expression) - }); - break; + case SyntaxKind.QualifiedName: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSQualifiedName, + left: this.convertChild(node.left), + right: this.convertChild(node.right) + }); + } - case SyntaxKind.QualifiedName: { - Object.assign(result, { - type: AST_NODE_TYPES.TSQualifiedName, - left: convertChild(node.left), - right: convertChild(node.right) - }); - break; - } + // TypeScript specific - // TypeScript specific + case SyntaxKind.TypeReference: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSTypeReference, + typeName: this.convertType(node.typeName), + typeParameters: node.typeArguments + ? this.convertTypeArgumentsToTypeParameters(node.typeArguments) + : undefined + }); + } - case SyntaxKind.TypeReference: { - Object.assign(result, { - type: AST_NODE_TYPES.TSTypeReference, - typeName: convertChildType(node.typeName), - typeParameters: node.typeArguments - ? convertTypeArgumentsToTypeParameters(node.typeArguments) - : undefined - }); - break; - } + case SyntaxKind.TypeParameter: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSTypeParameter, + name: this.convertType(node.name), + constraint: node.constraint + ? this.convertType(node.constraint) + : undefined, + default: node.default ? this.convertType(node.default) : undefined + }); + } - case SyntaxKind.TypeParameter: { - Object.assign(result, { - type: AST_NODE_TYPES.TSTypeParameter, - name: convertChildType(node.name), - constraint: node.constraint - ? convertChildType(node.constraint) - : undefined, - default: node.default ? convertChildType(node.default) : undefined - }); - break; - } + case SyntaxKind.ThisType: + case SyntaxKind.AnyKeyword: + case SyntaxKind.BigIntKeyword: + case SyntaxKind.BooleanKeyword: + case SyntaxKind.NeverKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.ObjectKeyword: + case SyntaxKind.StringKeyword: + case SyntaxKind.SymbolKeyword: + case SyntaxKind.UnknownKeyword: + case SyntaxKind.VoidKeyword: + case SyntaxKind.UndefinedKeyword: { + // TODO: + return this.createNode(node, { + type: AST_NODE_TYPES[`TS${SyntaxKind[node.kind]}` as AST_NODE_TYPES] + }); + } - case SyntaxKind.ThisType: - case SyntaxKind.AnyKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.UnknownKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.UndefinedKeyword: { - Object.assign(result, { - type: AST_NODE_TYPES[`TS${SyntaxKind[node.kind]}` as AST_NODE_TYPES] - }); - break; - } + case SyntaxKind.NonNullExpression: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSNonNullExpression, + expression: this.convertChild(node.expression) + }); + } - case SyntaxKind.NonNullExpression: { - Object.assign(result, { - type: AST_NODE_TYPES.TSNonNullExpression, - expression: convertChild(node.expression) - }); - break; - } + case SyntaxKind.TypeLiteral: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSTypeLiteral, + members: node.members.map(el => this.convertChild(el)) + }); + } - case SyntaxKind.TypeLiteral: { - Object.assign(result, { - type: AST_NODE_TYPES.TSTypeLiteral, - members: node.members.map(convertChild) - }); - break; - } + case SyntaxKind.ArrayType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSArrayType, + elementType: this.convertType(node.elementType) + }); + } - case SyntaxKind.ArrayType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSArrayType, - elementType: convertChildType(node.elementType) - }); - break; - } + case SyntaxKind.IndexedAccessType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSIndexedAccessType, + objectType: this.convertType(node.objectType), + indexType: this.convertType(node.indexType) + }); + } - case SyntaxKind.IndexedAccessType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSIndexedAccessType, - objectType: convertChildType(node.objectType), - indexType: convertChildType(node.indexType) - }); - break; - } + case SyntaxKind.ConditionalType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSConditionalType, + checkType: this.convertType(node.checkType), + extendsType: this.convertType(node.extendsType), + trueType: this.convertType(node.trueType), + falseType: this.convertType(node.falseType) + }); + } - case SyntaxKind.ConditionalType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSConditionalType, - checkType: convertChildType(node.checkType), - extendsType: convertChildType(node.extendsType), - trueType: convertChildType(node.trueType), - falseType: convertChildType(node.falseType) - }); - break; - } + case SyntaxKind.TypeQuery: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSTypeQuery, + exprName: this.convertType(node.exprName) + }); + } - case SyntaxKind.TypeQuery: { - Object.assign(result, { - type: AST_NODE_TYPES.TSTypeQuery, - exprName: convertChildType(node.exprName) - }); - break; - } + case SyntaxKind.MappedType: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.TSMappedType, + typeParameter: this.convertType(node.typeParameter) + }); - case SyntaxKind.MappedType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSMappedType, - typeParameter: convertChildType(node.typeParameter) - }); + if (node.readonlyToken) { + if (node.readonlyToken.kind === SyntaxKind.ReadonlyKeyword) { + result.readonly = true; + } else { + result.readonly = getTextForTokenKind(node.readonlyToken.kind) as + | '+' + | '-'; + } + } - if (node.readonlyToken) { - if (node.readonlyToken.kind === SyntaxKind.ReadonlyKeyword) { - result.readonly = true; - } else { - result.readonly = getTextForTokenKind(node.readonlyToken.kind); + if (node.questionToken) { + if (node.questionToken.kind === SyntaxKind.QuestionToken) { + result.optional = true; + } else { + result.optional = getTextForTokenKind(node.questionToken.kind) as + | '+' + | '-'; + } } - } - if (node.questionToken) { - if (node.questionToken.kind === SyntaxKind.QuestionToken) { - result.optional = true; - } else { - result.optional = getTextForTokenKind(node.questionToken.kind); + if (node.type) { + result.typeAnnotation = this.convertType(node.type); } + return result; } - if (node.type) { - result.typeAnnotation = convertChildType(node.type); - } - break; - } + case SyntaxKind.ParenthesizedExpression: + return this.convertChild(node.expression, parent); - case SyntaxKind.ParenthesizedExpression: - return convert({ - node: node.expression, - parent, - ast, - additionalOptions - }); + case SyntaxKind.TypeAliasDeclaration: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.TSTypeAliasDeclaration, + id: this.convertChild(node.name), + typeAnnotation: this.convertType(node.type) + }); - case SyntaxKind.TypeAliasDeclaration: { - Object.assign(result, { - type: AST_NODE_TYPES.TSTypeAliasDeclaration, - id: convertChild(node.name), - typeAnnotation: convertChildType(node.type) - }); + if (hasModifier(SyntaxKind.DeclareKeyword, node)) { + result.declare = true; + } - if (hasModifier(SyntaxKind.DeclareKeyword, node)) { - result.declare = true; - } + // Process typeParameters + if (node.typeParameters && node.typeParameters.length) { + result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); + } - // Process typeParameters - if (node.typeParameters && node.typeParameters.length) { - result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); + // check for exports + return fixExports(node, result, this.ast); } - // check for exports - result = fixExports(node, result, ast); - break; - } + case SyntaxKind.MethodSignature: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.TSMethodSignature, + computed: isComputedProperty(node.name), + key: this.convertChild(node.name), + params: this.convertParameters(node.parameters) + }); - case SyntaxKind.MethodSignature: { - Object.assign(result, { - type: AST_NODE_TYPES.TSMethodSignature, - computed: isComputedProperty(node.name), - key: convertChild(node.name), - params: convertParameters(node.parameters) - }); + if (isOptional(node)) { + result.optional = true; + } - if (isOptional(node)) { - result.optional = true; - } + if (node.type) { + result.returnType = this.convertTypeAnnotation(node.type, node); + } - if (node.type) { - result.returnType = convertTypeAnnotation(node.type); - } + if (hasModifier(SyntaxKind.ReadonlyKeyword, node)) { + result.readonly = true; + } - if (hasModifier(SyntaxKind.ReadonlyKeyword, node)) { - result.readonly = true; - } + if (node.typeParameters) { + result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); + } - if (node.typeParameters) { - result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); - } + const accessibility = getTSNodeAccessibility(node); + if (accessibility) { + result.accessibility = accessibility; + } - const accessibility = getTSNodeAccessibility(node); - if (accessibility) { - result.accessibility = accessibility; - } + if (hasModifier(SyntaxKind.ExportKeyword, node)) { + result.export = true; + } - if (hasModifier(SyntaxKind.ExportKeyword, node)) { - result.export = true; + if (hasModifier(SyntaxKind.StaticKeyword, node)) { + result.static = true; + } + return result; } - if (hasModifier(SyntaxKind.StaticKeyword, node)) { - result.static = true; - } - break; - } + case SyntaxKind.PropertySignature: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.TSPropertySignature, + optional: isOptional(node) || undefined, + computed: isComputedProperty(node.name), + key: this.convertChild(node.name), + typeAnnotation: node.type + ? this.convertTypeAnnotation(node.type, node) + : 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 + }); - case SyntaxKind.PropertySignature: { - Object.assign(result, { - type: AST_NODE_TYPES.TSPropertySignature, - optional: isOptional(node) || undefined, - computed: isComputedProperty(node.name), - key: convertChild(node.name), - typeAnnotation: node.type - ? convertTypeAnnotation(node.type) - : undefined, - initializer: convertChild(node.initializer) || undefined, - readonly: hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined, - static: hasModifier(SyntaxKind.StaticKeyword, node) || undefined, - export: hasModifier(SyntaxKind.ExportKeyword, node) || undefined - }); + const accessibility = getTSNodeAccessibility(node); + if (accessibility) { + result.accessibility = accessibility; + } - const accessibility = getTSNodeAccessibility(node); - if (accessibility) { - result.accessibility = accessibility; + return result; } - break; - } + case SyntaxKind.IndexSignature: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.TSIndexSignature, + parameters: node.parameters.map(el => this.convertChild(el)) + }); - case SyntaxKind.IndexSignature: { - Object.assign(result, { - type: AST_NODE_TYPES.TSIndexSignature, - parameters: node.parameters.map(convertChild) - }); + if (node.type) { + result.typeAnnotation = this.convertTypeAnnotation(node.type, node); + } - if (node.type) { - result.typeAnnotation = convertTypeAnnotation(node.type); - } + if (hasModifier(SyntaxKind.ReadonlyKeyword, node)) { + result.readonly = true; + } - if (hasModifier(SyntaxKind.ReadonlyKeyword, node)) { - result.readonly = true; - } + const accessibility = getTSNodeAccessibility(node); + if (accessibility) { + result.accessibility = accessibility; + } - const accessibility = getTSNodeAccessibility(node); - if (accessibility) { - result.accessibility = accessibility; - } + if (hasModifier(SyntaxKind.ExportKeyword, node)) { + result.export = true; + } - if (hasModifier(SyntaxKind.ExportKeyword, node)) { - result.export = true; - } + if (hasModifier(SyntaxKind.StaticKeyword, node)) { + result.static = true; + } + return result; + } + case SyntaxKind.ConstructorType: + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructSignature: + case SyntaxKind.CallSignature: { + let type: AST_NODE_TYPES; + switch (node.kind) { + case SyntaxKind.ConstructSignature: + type = AST_NODE_TYPES.TSConstructSignatureDeclaration; + break; + case SyntaxKind.CallSignature: + type = AST_NODE_TYPES.TSCallSignatureDeclaration; + break; + case SyntaxKind.FunctionType: + type = AST_NODE_TYPES.TSFunctionType; + break; + case SyntaxKind.ConstructorType: + default: + type = AST_NODE_TYPES.TSConstructorType; + break; + } + const result = this.createNode(node, { + type: type, + params: this.convertParameters(node.parameters) + }); - if (hasModifier(SyntaxKind.StaticKeyword, node)) { - result.static = true; - } - break; - } - case SyntaxKind.ConstructorType: - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructSignature: - case SyntaxKind.CallSignature: { - let type: AST_NODE_TYPES; - switch (node.kind) { - case SyntaxKind.ConstructSignature: - type = AST_NODE_TYPES.TSConstructSignatureDeclaration; - break; - case SyntaxKind.CallSignature: - type = AST_NODE_TYPES.TSCallSignatureDeclaration; - break; - case SyntaxKind.FunctionType: - type = AST_NODE_TYPES.TSFunctionType; - break; - case SyntaxKind.ConstructorType: - default: - type = AST_NODE_TYPES.TSConstructorType; - break; - } - Object.assign(result, { - type: type, - params: convertParameters(node.parameters) - }); + if (node.type) { + result.returnType = this.convertTypeAnnotation(node.type, node); + } - if (node.type) { - result.returnType = convertTypeAnnotation(node.type); - } + if (node.typeParameters) { + result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); + } - if (node.typeParameters) { - result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); + return result; } - break; - } - - case SyntaxKind.ExpressionWithTypeArguments: { - Object.assign(result, { - type: - parent && parent.kind === SyntaxKind.InterfaceDeclaration - ? AST_NODE_TYPES.TSInterfaceHeritage - : AST_NODE_TYPES.TSClassImplements, - expression: convertChild(node.expression) - }); - - if (node.typeArguments && node.typeArguments.length) { - result.typeParameters = convertTypeArgumentsToTypeParameters( - node.typeArguments + case SyntaxKind.ExpressionWithTypeArguments: { + const result = this.createNode( + node, + { + type: + parent && parent.kind === SyntaxKind.InterfaceDeclaration + ? AST_NODE_TYPES.TSInterfaceHeritage + : AST_NODE_TYPES.TSClassImplements, + expression: this.convertChild(node.expression) + } ); - } - break; - } - case SyntaxKind.InterfaceDeclaration: { - const interfaceHeritageClauses = node.heritageClauses || []; + if (node.typeArguments && node.typeArguments.length) { + result.typeParameters = this.convertTypeArgumentsToTypeParameters( + node.typeArguments + ); + } + return result; + } + + case SyntaxKind.InterfaceDeclaration: { + const interfaceHeritageClauses = node.heritageClauses || []; + const result = this.createNode(node, { + type: AST_NODE_TYPES.TSInterfaceDeclaration, + body: this.createNode(node, { + type: AST_NODE_TYPES.TSInterfaceBody, + body: node.members.map(member => this.convertChild(member)), + range: [node.members.pos - 1, node.end] + }), + id: this.convertChild(node.name) + }); - if (node.typeParameters && node.typeParameters.length) { - result.typeParameters = convertTSTypeParametersToTypeParametersDeclaration( - node.typeParameters - ); - } + if (node.typeParameters && node.typeParameters.length) { + result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration( + node.typeParameters + ); + } - const interfaceBodyRange = [node.members.pos - 1, node.end]; + if (interfaceHeritageClauses.length > 0) { + const interfaceExtends = []; + const interfaceImplements = []; - Object.assign(result, { - type: AST_NODE_TYPES.TSInterfaceDeclaration, - body: { - type: AST_NODE_TYPES.TSInterfaceBody, - body: node.members.map(member => convertChild(member)), - range: interfaceBodyRange, - loc: getLocFor(interfaceBodyRange[0], interfaceBodyRange[1], ast) - }, - id: convertChild(node.name) - }); + for (const heritageClause of interfaceHeritageClauses) { + if (heritageClause.token === SyntaxKind.ExtendsKeyword) { + for (const n of heritageClause.types) { + interfaceExtends.push(this.convertChild(n, node)); + } + } else if (heritageClause.token === SyntaxKind.ImplementsKeyword) { + for (const n of heritageClause.types) { + interfaceImplements.push(this.convertChild(n, node)); + } + } + } - if (interfaceHeritageClauses.length > 0) { - const interfaceExtends = []; - const interfaceImplements = []; + if (interfaceExtends.length) { + result.extends = interfaceExtends; + } - for (const heritageClause of interfaceHeritageClauses) { - if (heritageClause.token === SyntaxKind.ExtendsKeyword) { - for (const n of heritageClause.types) { - interfaceExtends.push(convertChild(n)); - } - } else if (heritageClause.token === SyntaxKind.ImplementsKeyword) { - for (const n of heritageClause.types) { - interfaceImplements.push(convertChild(n)); - } + if (interfaceImplements.length) { + result.implements = interfaceImplements; } } - if (interfaceExtends.length) { - result.extends = interfaceExtends; + /** + * Semantically, decorators are not allowed on interface declarations, + * but the TypeScript compiler will parse them and produce a valid AST, + * so we handle them here too. + */ + if (node.decorators) { + result.decorators = node.decorators.map(el => this.convertChild(el)); } - - if (interfaceImplements.length) { - result.implements = interfaceImplements; + if (hasModifier(SyntaxKind.AbstractKeyword, node)) { + result.abstract = true; } + if (hasModifier(SyntaxKind.DeclareKeyword, node)) { + result.declare = true; + } + // check for exports + return fixExports(node, result, this.ast); } - /** - * Semantically, decorators are not allowed on interface declarations, - * but the TypeScript compiler will parse them and produce a valid AST, - * so we handle them here too. - */ - if (node.decorators) { - result.decorators = node.decorators.map(convertChild); - } - if (hasModifier(SyntaxKind.AbstractKeyword, node)) { - result.abstract = true; - } - if (hasModifier(SyntaxKind.DeclareKeyword, node)) { - result.declare = true; + case SyntaxKind.FirstTypeNode: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.TSTypePredicate, + parameterName: this.convertChild(node.parameterName), + typeAnnotation: this.convertTypeAnnotation(node.type, node) + }); + /** + * Specific fix for type-guard location data + */ + result.typeAnnotation!.loc = result.typeAnnotation!.typeAnnotation!.loc; + result.typeAnnotation!.range = result.typeAnnotation!.typeAnnotation!.range; + return result; } - // check for exports - result = fixExports(node, result, ast); - - break; - } - case SyntaxKind.FirstTypeNode: - Object.assign(result, { - type: AST_NODE_TYPES.TSTypePredicate, - parameterName: convertChild(node.parameterName), - typeAnnotation: convertTypeAnnotation(node.type) - }); - /** - * Specific fix for type-guard location data - */ - result.typeAnnotation!.loc = result.typeAnnotation!.typeAnnotation!.loc; - result.typeAnnotation!.range = result.typeAnnotation!.typeAnnotation!.range; - break; - - case SyntaxKind.ImportType: - Object.assign(result, { - type: AST_NODE_TYPES.TSImportType, - isTypeOf: !!node.isTypeOf, - parameter: convertChild(node.argument), - qualifier: convertChild(node.qualifier), - typeParameters: node.typeArguments - ? convertTypeArgumentsToTypeParameters(node.typeArguments) - : null - }); - break; + case SyntaxKind.ImportType: + return this.createNode(node, { + type: AST_NODE_TYPES.TSImportType, + isTypeOf: !!node.isTypeOf, + parameter: this.convertChild(node.argument), + qualifier: this.convertChild(node.qualifier), + typeParameters: node.typeArguments + ? this.convertTypeArgumentsToTypeParameters(node.typeArguments) + : null + }); - case SyntaxKind.EnumDeclaration: { - Object.assign(result, { - type: AST_NODE_TYPES.TSEnumDeclaration, - id: convertChild(node.name), - members: node.members.map(convertChild) - }); - // apply modifiers first... - applyModifiersToResult(node.modifiers); - // ...then check for exports - result = fixExports(node, result, ast); - /** - * Semantically, decorators are not allowed on enum declarations, - * but the TypeScript compiler will parse them and produce a valid AST, - * so we handle them here too. - */ - if (node.decorators) { - result.decorators = node.decorators.map(convertChild); + case SyntaxKind.EnumDeclaration: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.TSEnumDeclaration, + id: this.convertChild(node.name), + members: node.members.map(el => this.convertChild(el)) + }); + // apply modifiers first... + this.applyModifiersToResult(result, node.modifiers); + /** + * Semantically, decorators are not allowed on enum declarations, + * but the TypeScript compiler will parse them and produce a valid AST, + * so we handle them here too. + */ + if (node.decorators) { + result.decorators = node.decorators.map(el => this.convertChild(el)); + } + // ...then check for exports + return fixExports(node, result, this.ast); } - break; - } - case SyntaxKind.EnumMember: { - Object.assign(result, { - type: AST_NODE_TYPES.TSEnumMember, - id: convertChild(node.name) - }); - if (node.initializer) { - (result as any).initializer = convertChild(node.initializer); + case SyntaxKind.EnumMember: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.TSEnumMember, + id: this.convertChild(node.name) + }); + if (node.initializer) { + result.initializer = this.convertChild(node.initializer); + } + return result; } - break; - } - case SyntaxKind.AbstractKeyword: { - Object.assign(result, { - type: AST_NODE_TYPES.TSAbstractKeyword - }); - break; - } + case SyntaxKind.ModuleDeclaration: { + const result = this.createNode(node, { + type: AST_NODE_TYPES.TSModuleDeclaration, + id: this.convertChild(node.name) + }); + if (node.body) { + result.body = this.convertChild(node.body); + } + // apply modifiers first... + this.applyModifiersToResult(result, node.modifiers); + if (node.flags & ts.NodeFlags.GlobalAugmentation) { + result.global = true; + } + // ...then check for exports + return fixExports(node, result, this.ast); + } - case SyntaxKind.ModuleDeclaration: { - Object.assign(result, { - type: AST_NODE_TYPES.TSModuleDeclaration, - id: convertChild(node.name) - }); - if (node.body) { - result.body = convertChild(node.body); + // TypeScript specific types + case SyntaxKind.OptionalType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSOptionalType, + typeAnnotation: this.convertType(node.type) + }); } - // apply modifiers first... - applyModifiersToResult(node.modifiers); - if (node.flags & ts.NodeFlags.GlobalAugmentation) { - result.global = true; + case SyntaxKind.ParenthesizedType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSParenthesizedType, + typeAnnotation: this.convertType(node.type) + }); } - // ...then check for exports - result = fixExports(node, result, ast); - break; - } - - // TypeScript specific types - case SyntaxKind.OptionalType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSOptionalType, - typeAnnotation: convertChildType(node.type) - }); - break; - } - case SyntaxKind.ParenthesizedType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSParenthesizedType, - typeAnnotation: convertChildType(node.type) - }); - break; - } - case SyntaxKind.TupleType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSTupleType, - elementTypes: node.elementTypes.map(convertChildType) - }); - break; - } - case SyntaxKind.UnionType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSUnionType, - types: node.types.map(convertChildType) - }); - break; - } - case SyntaxKind.IntersectionType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSIntersectionType, - types: node.types.map(convertChildType) - }); - break; - } - case SyntaxKind.RestType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSRestType, - typeAnnotation: convertChildType(node.type) - }); - break; - } - case SyntaxKind.AsExpression: { - Object.assign(result, { - type: AST_NODE_TYPES.TSAsExpression, - expression: convertChild(node.expression), - typeAnnotation: convertChildType(node.type) - }); - break; - } - case SyntaxKind.InferType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSInferType, - typeParameter: convertChildType(node.typeParameter) - }); - break; - } - case SyntaxKind.LiteralType: { - Object.assign(result, { - type: AST_NODE_TYPES.TSLiteralType, - literal: convertChildType(node.literal) - }); - break; - } - case SyntaxKind.TypeAssertionExpression: { - Object.assign(result, { - type: AST_NODE_TYPES.TSTypeAssertion, - typeAnnotation: convertChildType(node.type), - expression: convertChild(node.expression) - }); - break; - } - case SyntaxKind.ImportEqualsDeclaration: { - Object.assign(result, { - type: AST_NODE_TYPES.TSImportEqualsDeclaration, - id: convertChild(node.name), - moduleReference: convertChild(node.moduleReference), - isExport: hasModifier(SyntaxKind.ExportKeyword, node) - }); - break; - } - case SyntaxKind.ExternalModuleReference: { - Object.assign(result, { - type: AST_NODE_TYPES.TSExternalModuleReference, - expression: convertChild(node.expression) - }); - break; - } - case SyntaxKind.NamespaceExportDeclaration: { - Object.assign(result, { - type: AST_NODE_TYPES.TSNamespaceExportDeclaration, - id: convertChild(node.name) - }); - break; + case SyntaxKind.TupleType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSTupleType, + elementTypes: node.elementTypes.map(el => this.convertType(el)) + }); + } + case SyntaxKind.UnionType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSUnionType, + types: node.types.map(el => this.convertType(el)) + }); + } + case SyntaxKind.IntersectionType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSIntersectionType, + types: node.types.map(el => this.convertType(el)) + }); + } + case SyntaxKind.RestType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSRestType, + typeAnnotation: this.convertType(node.type) + }); + } + case SyntaxKind.AsExpression: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSAsExpression, + expression: this.convertChild(node.expression), + typeAnnotation: this.convertType(node.type) + }); + } + case SyntaxKind.InferType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSInferType, + typeParameter: this.convertType(node.typeParameter) + }); + } + case SyntaxKind.LiteralType: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSLiteralType, + literal: this.convertType(node.literal) + }); + } + case SyntaxKind.TypeAssertionExpression: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSTypeAssertion, + typeAnnotation: this.convertType(node.type), + expression: this.convertChild(node.expression) + }); + } + case SyntaxKind.ImportEqualsDeclaration: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSImportEqualsDeclaration, + id: this.convertChild(node.name), + moduleReference: this.convertChild(node.moduleReference), + isExport: hasModifier(SyntaxKind.ExportKeyword, node) + }); + } + case SyntaxKind.ExternalModuleReference: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSExternalModuleReference, + expression: this.convertChild(node.expression) + }); + } + case SyntaxKind.NamespaceExportDeclaration: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSNamespaceExportDeclaration, + id: this.convertChild(node.name) + }); + } + case SyntaxKind.AbstractKeyword: { + return this.createNode(node, { + type: AST_NODE_TYPES.TSAbstractKeyword + }); + } + default: + return this.deeplyCopy(node); } - - default: - deeplyCopy(); - } - - if (additionalOptions.shouldProvideParserServices) { - tsNodeToESTreeNodeMap.set(node, result); - esTreeNodeToTSNodeMap.set(result, node); } +} - return result; +export default function convert(config: ConvertConfig): es.Program | null { + const converter = new Converter(config.ast, config.options); + return converter.convertProgram(); } diff --git a/packages/typescript-estree/src/estree/experimental.ts b/packages/typescript-estree/src/estree/experimental.ts deleted file mode 100644 index 103d9ffd53a5..000000000000 --- a/packages/typescript-estree/src/estree/experimental.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Node, Expression, MethodDefinition, Property, Class } from './spec'; - -/** - * Decorator - */ -export interface Decorator extends Node { - type: 'Decorator'; - expression: Expression; -} - -/** - * MethodDefinition - */ -export interface ExtendedMethodDefinition extends MethodDefinition { - decorators: Decorator[]; -} - -/** - * Property - */ -export interface ExtendedProperty extends Property { - decorators: Decorator[]; -} - -/** - * Class - */ -export interface ExtendedClass extends Class { - decorators: Decorator[]; -} diff --git a/packages/typescript-estree/src/estree/extensions.ts b/packages/typescript-estree/src/estree/extensions.ts deleted file mode 100644 index 5e036917a3b3..000000000000 --- a/packages/typescript-estree/src/estree/extensions.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Based on https://github.com/estree/estree/blob/master/extensions/type-annotations.md - */ - -import { - Identifier, - Function, - ObjectPattern, - ArrayPattern, - RestElement -} from './spec'; - -/** - * Type Annotations - */ - -/** - * Any type annotation. - */ -export interface TypeAnnotation extends Node {} - -/** - * Identifier - * - * The `typeAnnotation` property is used only in the case of variable declarations with type annotations or function arguments with type annotations. - */ -export interface ExtendedIdentifier extends Identifier { - typeAnnotation: TypeAnnotation | null; -} - -/** - * Functions - * - * The `returnType` property is used to specify the type annotation for the return value of the function. - */ -export interface ExtendedFunction extends Function { - returnType: TypeAnnotation | null; -} - -/** - * Patterns - */ - -/** - * ObjectPattern - */ -export interface ExtendedObjectPattern extends ObjectPattern { - typeAnnotation: TypeAnnotation | null; -} - -/** - * ArrayPattern - */ -export interface ExtendedArrayPattern extends ArrayPattern { - typeAnnotation: TypeAnnotation | null; -} - -/** - * RestElement - */ -export interface ExtendedRestElement extends RestElement { - typeAnnotation: TypeAnnotation | null; -} diff --git a/packages/typescript-estree/src/estree/spec.ts b/packages/typescript-estree/src/estree/spec.ts deleted file mode 100644 index 1d2a0a765ee6..000000000000 --- a/packages/typescript-estree/src/estree/spec.ts +++ /dev/null @@ -1,985 +0,0 @@ -/** - * This document specifies the core ESTree AST node types based on: - * - ES5: https://github.com/estree/estree/blob/master/es5.md - * - ES2015: https://github.com/estree/estree/blob/master/es2015.md - * - ES2016: https://github.com/estree/estree/blob/master/es2016.md - * - ES2017: https://github.com/estree/estree/blob/master/es2017.md - * - ES2018: https://github.com/estree/estree/blob/master/es2018.md - */ - -/** - * Node objects - * - * ESTree AST nodes are represented as `Node` objects, which may have any prototype inheritance but which implement the following interface: - */ - -export interface Node { - type: string; - loc: SourceLocation | null; -} - -/** - * The `type` field is a string representing the AST variant type. Each subtype of `Node` is documented below with the specific string of its `type` field. You can use this field to determine which interface a node implements. - * - * The `loc` field represents the source location information of the node. If the node contains no information about the source location, the field is `null`; otherwise it is an object consisting of a start position (the position of the first character of the parsed source region) and an end position (the position of the first character after the parsed source region): - */ -export interface SourceLocation { - source: string | null; - start: Position; - end: Position; -} - -/** - * Each `Position` object consists of a `line` number (1-indexed) and a `column` number (0-indexed): - */ -export interface Position { - line: number; // >= 1 - column: number; // >= 0 -} - -/** - * Identifier - * - * An identifier. Note that an identifier may be an expression or a destructuring pattern. - */ -export interface Identifier extends Expression, Pattern { - type: 'Identifier'; - name: string; -} - -/** - * Literal - * - * A literal token. Note that a literal can be an expression. - */ -export interface Literal extends Expression { - type: 'Literal'; - value: string | boolean | null | number | RegExp; -} - -/** - * RegExpLiteral - * - * The `regex` property allows regexes to be represented in environments that don’t - * support certain flags such as `y` or `u`. In environments that don't support - * these flags `value` will be `null` as the regex can't be represented natively. - */ -export interface RegExpLiteral extends Literal { - regex: { - pattern: string; - flags: string; - }; -} - -/** - * Programs - * - * A complete program source tree. - * - * ES2015+ Parsers must specify sourceType as "module" if the source has been parsed as an ES6 module. Otherwise, sourceType must be "script". - */ -export interface Program extends Node { - type: 'Program'; - body: Array; - sourceType: 'script' | 'module'; -} - -/** - * Functions - * - * A function declaration or expression. - */ -export interface Function extends Node { - id: Identifier | null; - params: Pattern[]; - body: FunctionBody; - generator: boolean; - async: boolean; -} - -/** - * Statements - * - * Any statement. - */ -export interface Statement extends Node {} - -/** - * ExpressionStatement - * - * An expression statement, i.e., a statement consisting of a single expression. - */ -export interface ExpressionStatement extends Statement { - type: 'ExpressionStatement'; - expression: Expression; -} - -/** - * Directive - * - * A directive from the directive prologue of a script or function. - * The `directive` property is the raw string source of the directive without quotes. - */ -export interface Directive extends Node { - type: 'ExpressionStatement'; - expression: Literal; - directive: string; -} - -/** - * BlockStatement - * - * A block statement, i.e., a sequence of statements surrounded by braces. - */ -export interface BlockStatement extends Statement { - type: 'BlockStatement'; - body: Statement[]; -} - -/** - * FunctionBody - * - * The body of a function, which is a block statement that may begin with directives. - */ -export interface FunctionBody extends BlockStatement { - body: Array; -} - -/** - * EmptyStatement - * - * An empty statement, i.e., a solitary semicolon. - */ -export interface EmptyStatement extends Statement { - type: 'EmptyStatement'; -} - -/** - * DebuggerStatement - * - * A `debugger` statement. - */ -export interface DebuggerStatement extends Statement { - type: 'DebuggerStatement'; -} - -/** - * WithStatement - * - * A `with` statement. - */ -export interface WithStatement extends Statement { - type: 'WithStatement'; - object: Expression; - body: Statement; -} - -/** - * Control flow - */ - -/** - * ReturnStatement - * - * A `return` statement. - */ -export interface ReturnStatement extends Statement { - type: 'ReturnStatement'; - argument: Expression | null; -} - -/** - * LabeledStatement - * - * A labeled statement, i.e., a statement prefixed by a `break`/`continue` label. - */ -export interface LabeledStatement extends Statement { - type: 'LabeledStatement'; - label: Identifier; - body: Statement; -} - -/** - * BreakStatement - * - * A `break` statement. - */ -export interface BreakStatement extends Statement { - type: 'BreakStatement'; - label: Identifier | null; -} - -/** - * ContinueStatement - * - * A `continue` statement. - */ -export interface ContinueStatement extends Statement { - type: 'ContinueStatement'; - label: Identifier | null; -} - -/** - * Choice - */ - -/** - * IfStatement - * - * An `if` statement. - */ -export interface IfStatement extends Statement { - type: 'IfStatement'; - test: Expression; - consequent: Statement; - alternate: Statement | null; -} - -/** - * SwitchStatement - * - * A `switch` statement. - */ -export interface SwitchStatement extends Statement { - type: 'SwitchStatement'; - discriminant: Expression; - cases: SwitchCase[]; -} - -/** - * SwitchCase - * - * A `case` (if `test` is an `Expression`) or `default` (if `test === null`) clause in the body of a `switch` statement. - */ -export interface SwitchCase extends Node { - type: 'SwitchCase'; - test: Expression | null; - consequent: Statement[]; -} - -/** - * Exceptions - */ - -/** - * ThrowStatement - * - * A `throw` statement. - */ -export interface ThrowStatement extends Statement { - type: 'ThrowStatement'; - argument: Expression; -} - -/** - * TryStatement - * - * A `try` statement. If `handler` is `null` then `finalizer` must be a `BlockStatement`. - */ -export interface TryStatement extends Statement { - type: 'TryStatement'; - block: BlockStatement; - handler: CatchClause | null; - finalizer: BlockStatement | null; -} - -/** - * CatchClause - * - * A `catch` clause following a `try` block. - * - * The param is null if the catch binding is omitted. E.g., try { foo() } catch { bar() } - */ -export interface CatchClause extends Node { - type: 'CatchClause'; - param: Pattern | null; - body: BlockStatement; -} - -/** - * Loops - */ - -/** - * WhileStatement - * - * A `while` statement. - */ -export interface WhileStatement extends Statement { - type: 'WhileStatement'; - test: Expression; - body: Statement; -} - -/** - * DoWhileStatement - * - * A `do`/`while` statement. - */ -export interface DoWhileStatement extends Statement { - type: 'DoWhileStatement'; - body: Statement; - test: Expression; -} - -/** - * ForStatement - * - * A `for` statement. - */ -export interface ForStatement extends Statement { - type: 'ForStatement'; - init: VariableDeclaration | Expression | null; - test: Expression | null; - update: Expression | null; - body: Statement; -} - -/** - * ForInStatement - * - * A `for`/`in` statement. - */ -export interface ForInStatement extends Statement { - type: 'ForInStatement'; - left: VariableDeclaration | Pattern; - right: Expression; - body: Statement; -} - -/** - * ForOfStatement - * - * A `for`/`of` statement and for-await-of statements, e.g., for await (const x of xs) { - */ -export interface ForOfStatement { - type: 'ForOfStatement'; - left: VariableDeclaration | Pattern; - right: Expression; - body: Statement; - await: boolean; -} - -/** - * Declarations - * - * Any declaration node. Note that declarations are considered statements; this is because declarations can appear in any statement context. - */ -export interface Declaration extends Statement {} - -/** - * FunctionDeclaration - * - * A function declaration. Note that unlike in the parent interface `Function`, the `id` cannot be `null`. - */ -export interface FunctionDeclaration extends Function, Declaration { - type: 'FunctionDeclaration'; - id: Identifier; -} - -/** - * VariableDeclaration - * - * A variable declaration. - */ -export interface VariableDeclaration extends Declaration { - type: 'VariableDeclaration'; - declarations: VariableDeclarator[]; - kind: 'var' | 'let' | 'const'; -} - -/** - * VariableDeclarator - * - * A variable declarator. - */ -export interface VariableDeclarator extends Node { - type: 'VariableDeclarator'; - id: Pattern; - init: Expression | null; -} - -/** - * Expressions - * - * Any expression node. Since the left-hand side of an assignment may be any expression in general, an expression can also be a pattern. - */ -export interface Expression extends Node {} - -/** - * Super - * - * A super pseudo-expression. - */ -export interface Super extends Node { - type: 'Super'; -} - -/** - * ThisExpression - * - * A `this` expression. - */ -export interface ThisExpression extends Expression { - type: 'ThisExpression'; -} - -/** - * SpreadElement - * - * Spread expression, e.g., [head, ...iter, tail], f(head, ...iter, ...tail). - */ -export interface SpreadElement extends Node { - type: 'SpreadElement'; - argument: Expression; -} - -/** - * ArrayExpression - * - * An array expression. - */ -export interface ArrayExpression extends Expression { - type: 'ArrayExpression'; - elements: Array; -} - -/** - * ObjectExpression - * - * An object expression. - * - * Spread properties, e.g., {a: 1, ...obj, b: 2}. - */ -export interface ObjectExpression extends Expression { - type: 'ObjectExpression'; - properties: Array; -} - -/** - * Property - * - * A literal property in an object expression can have either a string or number as its `value`. Ordinary property initializers have a `kind` value `"init"`; getters and setters have the kind values `"get"` and `"set"`, respectively. - */ -export interface Property extends Node { - type: 'Property'; - key: Literal | Identifier | Expression; - value: Expression; - kind: 'init' | 'get' | 'set'; - method: boolean; - shorthand: boolean; - computed: boolean; -} - -/** - * FunctionExpression - * - * A `function` expression. - */ -export interface FunctionExpression extends Function, Expression { - type: 'FunctionExpression'; -} - -/** - * ArrowFunctionExpression - * - * A fat arrow function expression, e.g., let foo = (bar) => { / body / }. - */ -export interface ArrowFunctionExpression extends Expression { - id: Identifier | null; - params: Pattern[]; - type: 'ArrowFunctionExpression'; - body: FunctionBody | Expression; - generator: boolean; - expression: boolean; -} - -/** - * Unary operations - */ - -/** - * UnaryExpression - * - * A unary operator expression. - */ -export interface UnaryExpression extends Expression { - type: 'UnaryExpression'; - operator: UnaryOperator; - prefix: boolean; - argument: Expression; -} - -/** - * UnaryOperator - * - * A unary operator token. - */ -export type UnaryOperator = - | '-' - | '+' - | '!' - | '~' - | 'typeof' - | 'void' - | 'delete'; - -/** - * UpdateExpression - * - * An update (increment or decrement) operator expression. - */ -export interface UpdateExpression extends Expression { - type: 'UpdateExpression'; - operator: UpdateOperator; - argument: Expression; - prefix: boolean; -} - -/** - * UpdateOperator - * - * An update (increment or decrement) operator token. - */ -export type UpdateOperator = '++' | '--'; - -/** - * Binary operations - */ - -/** - * BinaryExpression - * - * A binary operator expression. - */ -export interface BinaryExpression extends Expression { - type: 'BinaryExpression'; - operator: BinaryOperator; - left: Expression; - right: Expression; -} - -/** - * BinaryOperator - * - * A binary operator token. - */ -export type BinaryOperator = - | '==' - | '!=' - | '===' - | '!==' - | '<' - | '<=' - | '>' - | '>=' - | '<<' - | '>>' - | '>>>' - | '+' - | '-' - | '*' - | '/' - | '%' - | '|' - | '^' - | '&' - | 'in' - | 'instanceof' - | '**'; - -/** - * AssignmentExpression - * - * An assignment operator expression. - * - * FROM ESTREE DOCS: - * - * ``` - * FIXME: This describes the Esprima and Acorn behaviors, which is not currently aligned with the SpiderMonkey behavior. - * - * extend interface AssignmentExpression { - * left: Pattern; - * } - * - * Note that pre-ES6 code was allowed to pass references around and so left was much more liberal; an implementation might choose to continue using old definition if it needs to support such legacy code. - * ``` - */ -export interface AssignmentExpression extends Expression { - type: 'AssignmentExpression'; - operator: AssignmentOperator; - left: Pattern | Expression; - right: Expression; -} - -/** - * AssignmentOperator - * - * An assignment operator token. - */ -export type AssignmentOperator = - | '=' - | '+=' - | '-=' - | '*=' - | '/=' - | '%=' - | '<<=' - | '>>=' - | '>>>=' - | '|=' - | '^=' - | '&=' - | '**='; - -/** - * LogicalExpression - * - * A logical operator expression. - */ -export interface LogicalExpression extends Expression { - type: 'LogicalExpression'; - operator: LogicalOperator; - left: Expression; - right: Expression; -} - -/** - * LogicalOperator - * - * A logical operator token. - */ -export type LogicalOperator = '||' | '&&'; - -/** - * MemberExpression - * - * A member expression. If `computed` is `true`, the node corresponds to a computed (`a[b]`) member expression and `property` is an `Expression`. If `computed` is `false`, the node corresponds to a static (`a.b`) member expression and `property` is an `Identifier`. - */ -export interface MemberExpression extends Expression, Pattern { - type: 'MemberExpression'; - object: Expression | Super; - property: Expression; - computed: boolean; -} - -/** - * ConditionalExpression - * - * A conditional expression, i.e., a ternary `?`/`:` expression. - */ -export interface ConditionalExpression extends Expression { - type: 'ConditionalExpression'; - test: Expression; - alternate: Expression; - consequent: Expression; -} - -/** - * CallExpression - * - * A function or method call expression. - */ -export interface CallExpression extends Expression { - type: 'CallExpression'; - callee: Expression | Super; - arguments: Array; -} - -/** - * NewExpression - * - * A `new` expression. - */ -export interface NewExpression extends Expression { - type: 'NewExpression'; - callee: Expression; - arguments: Array; -} - -/** - * SequenceExpression - * - * A sequence expression, i.e., a comma-separated sequence of expressions. - */ -export interface SequenceExpression extends Expression { - type: 'SequenceExpression'; - expressions: Expression[]; -} - -/** - * YieldExpression - * - * A yield expression. - */ -export interface YieldExpression extends Expression { - type: 'YieldExpression'; - argument: Expression | null; - delegate: boolean; -} - -/** - * AwaitExpression - */ -export interface AwaitExpression extends Expression { - type: 'AwaitExpression'; - argument: Expression; -} - -/** - * Template Literals - */ - -/** - * TemplateLiteral - */ -export interface TemplateLiteral extends Expression { - type: 'TemplateLiteral'; - quasis: TemplateElement[]; - expressions: Expression[]; -} - -/** - * TaggedTemplateExpression - */ -export interface TaggedTemplateExpression extends Expression { - type: 'TaggedTemplateExpression'; - tag: Expression; - quasi: TemplateLiteral; -} - -/** - * TemplateElement - * - * If the template literal is tagged and the text has an invalid escape, cooked will be null, e.g., tag`\unicode and \u{55}` - */ -export interface TemplateElement extends Node { - type: 'TemplateElement'; - tail: boolean; - value: { - cooked: string | null; - raw: string; - }; -} - -/** - * Patterns - * - * Destructuring binding and assignment are not part of ES5, but all binding positions accept Pattern to allow for destructuring in ES6. Nevertheless, for ES5, the only Pattern subtype is Identifier. - */ -export interface Pattern extends Node {} - -/** - * AssignmentProperty - */ -export interface AssignmentProperty extends Property { - type: 'Property'; // inherited - value: Pattern; - kind: 'init'; - method: false; -} - -/** - * ObjectPattern - * - * Rest properties, e.g., {a, ...rest} = obj. - */ -export interface ObjectPattern extends Pattern { - type: 'ObjectPattern'; - properties: Array; -} - -/** - * ArrayPattern - */ -export interface ArrayPattern extends Pattern { - type: 'ArrayPattern'; - elements: Array; -} - -/** - * RestElement - */ -export interface RestElement extends Pattern { - type: 'RestElement'; - argument: Pattern; -} - -/** - * AssignmentPattern - */ -export interface AssignmentPattern extends Pattern { - type: 'AssignmentPattern'; - left: Pattern; - right: Expression; -} - -/** - * Classes - */ - -/** - * Class - */ -export interface Class extends Node { - id: Identifier | null; - superClass: Expression | null; - body: ClassBody; -} - -/** - * ClassBody - */ -export interface ClassBody extends Node { - type: 'ClassBody'; - body: MethodDefinition[]; -} - -/** - * MethodDefinition - */ -export interface MethodDefinition extends Node { - type: 'MethodDefinition'; - key: Expression; - value: FunctionExpression; - kind: 'constructor' | 'method' | 'get' | 'set'; - computed: boolean; - static: boolean; -} - -/** - * ClassDeclaration - */ -export interface ClassDeclaration extends Class, Declaration { - type: 'ClassDeclaration'; - id: Identifier; -} - -/** - * ClassExpression - */ -export interface ClassExpression extends Class, Expression { - type: 'ClassExpression'; -} - -/** - * MetaProperty - */ -export interface MetaProperty extends Expression { - type: 'MetaProperty'; - meta: Identifier; - property: Identifier; -} - -/** - * Modules - */ - -/** - * ModuleDeclaration - * - * A module `import` or `export` declaration. - */ -export interface ModuleDeclaration extends Node {} - -/** - * ModuleSpecifier - * - * A specifier in an import or export declaration. - */ -export interface ModuleSpecifier extends Node { - local: Identifier; -} - -/** - * Imports - */ - -/** - * ImportDeclaration - * - * An import declaration, e.g., `import foo from "mod";`. - */ -export interface ImportDeclaration extends ModuleDeclaration { - type: 'ImportDeclaration'; - specifiers: Array< - ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier - >; - source: Literal; -} - -/** - * ImportSpecifier - * - * An imported variable binding, e.g., `{foo}` in `import {foo} from "mod"` or `{foo as bar}` in `import {foo as bar} from "mod"`. The `imported` field refers to the name of the export imported from the module. The `local` field refers to the binding imported into the local module scope. If it is a basic named import, such as in `import {foo} from "mod"`, both `imported` and `local` are equivalent `Identifier` nodes; in this case an `Identifier` node representing `foo`. If it is an aliased import, such as in `import {foo as bar} from "mod"`, the `imported` field is an `Identifier` node representing `foo`, and the `local` field is an `Identifier` node representing `bar`. - */ -export interface ImportSpecifier extends ModuleSpecifier { - type: 'ImportSpecifier'; - imported: Identifier; -} - -/** - * ImportDefaultSpecifier - * - * A default import specifier, e.g., `foo` in `import foo from "mod.js"`. - */ -export interface ImportDefaultSpecifier extends ModuleSpecifier { - type: 'ImportDefaultSpecifier'; -} - -/** - * ImportNamespaceSpecifier - * - * A namespace import specifier, e.g., `* as foo` in `import * as foo from "mod.js"`. - */ -export interface ImportNamespaceSpecifier extends ModuleSpecifier { - type: 'ImportNamespaceSpecifier'; -} - -/** - * Exports - */ - -/** - * ExportNamedDeclaration - * - * An export named declaration, e.g., `export {foo, bar};`, `export {foo} from "mod";` or `export var foo = 1;`. - * - * _Note: Having `declaration` populated with non-empty `specifiers` or non-null `source` results in an invalid state._ - */ -export interface ExportNamedDeclaration extends ModuleDeclaration { - type: 'ExportNamedDeclaration'; - declaration: Declaration | null; - specifiers: [ExportSpecifier]; - source: Literal | null; -} - -/** - * ExportSpecifier - * - * An exported variable binding, e.g., `{foo}` in `export {foo}` or `{bar as foo}` in `export {bar as foo}`. The `exported` field refers to the name exported in the module. The `local` field refers to the binding into the local module scope. If it is a basic named export, such as in `export {foo}`, both `exported` and `local` are equivalent `Identifier` nodes; in this case an `Identifier` node representing `foo`. If it is an aliased export, such as in `export {bar as foo}`, the `exported` field is an `Identifier` node representing `foo`, and the `local` field is an `Identifier` node representing `bar`. - */ -export interface ExportSpecifier extends ModuleSpecifier { - type: 'ExportSpecifier'; - exported: Identifier; -} - -/** - * ExportDefaultDeclaration - * - * An export default declaration, e.g., `export default function () {};` or `export default 1;`. - */ -export interface ExportDefaultDeclaration extends ModuleDeclaration { - type: 'ExportDefaultDeclaration'; - declaration: Declaration | Expression; -} - -/** - * ExportAllDeclaration - * - * An export batch declaration, e.g., `export * from "mod";`. - */ -export interface ExportAllDeclaration extends ModuleDeclaration { - type: 'ExportAllDeclaration'; - source: Literal; -} diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index d79353f755e6..d995032388b9 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -6,12 +6,7 @@ */ import ts from 'typescript'; import unescape from 'lodash.unescape'; -import { - ESTreeNodeLoc, - ESTreeNode, - ESTreeToken, - LineAndColumnData -} from './temp-types-based-on-js-source'; +import * as es from './ast-tree-nodes'; import { AST_NODE_TYPES } from './ast-node-types'; const SyntaxKind = ts.SyntaxKind; @@ -229,7 +224,7 @@ export function getBinaryExpressionType( export function getLineAndCharacterFor( pos: number, ast: ts.SourceFile -): LineAndColumnData { +): es.Position { const loc = ast.getLineAndCharacterOfPosition(pos); return { line: loc.line + 1, @@ -243,13 +238,13 @@ export function getLineAndCharacterFor( * @param {number} start start data * @param {number} end end data * @param {ts.SourceFile} ast the AST object - * @returns {ESTreeNodeLoc} the loc data + * @returns {es.SourceLocation} the loc data */ export function getLocFor( start: number, end: number, ast: ts.SourceFile -): ESTreeNodeLoc { +): es.SourceLocation { return { start: getLineAndCharacterFor(start, ast), end: getLineAndCharacterFor(end, ast) @@ -294,10 +289,20 @@ export function canContainDirective(node: ts.Node): boolean { export function getLoc( nodeOrToken: ts.Node, ast: ts.SourceFile -): ESTreeNodeLoc { +): es.SourceLocation { return getLocFor(nodeOrToken.getStart(ast), nodeOrToken.end, ast); } +/** + * Returns range for the given ts.Node + * @param node the ts.Node or ts.Token + * @param ast the AST object + * @returns the range data + */ +export function getRange(node: ts.Node, ast: ts.SourceFile): [number, number] { + return [node.getStart(ast), node.getEnd()]; +} + /** * Returns true if a given ts.Node is a token * @param {ts.Node} node the ts.Node @@ -459,16 +464,16 @@ export function isOptional(node: { /** * Fixes the exports of the given ts.Node - * @param {ts.Node} node the ts.Node - * @param {ESTreeNode} result result - * @param {ts.SourceFile} ast the AST - * @returns {ESTreeNode} the ESTreeNode with fixed exports + * @param node the ts.Node + * @param result result + * @param ast the AST + * @returns the ESTreeNode with fixed exports */ -export function fixExports( +export function fixExports( node: ts.Node, - result: ESTreeNode, + result: T, ast: ts.SourceFile -): ESTreeNode { +): es.ExportDefaultDeclaration | es.ExportNamedDeclaration | T { // check for exports if (node.modifiers && node.modifiers[0].kind === SyntaxKind.ExportKeyword) { const exportKeyword = node.modifiers[0]; @@ -480,26 +485,26 @@ export function fixExports( ? findNextToken(nextModifier, ast, ast) : findNextToken(exportKeyword, ast, ast); - result.range[0] = varToken!.getStart(ast); - result.loc = getLocFor(result.range[0], result.range[1], ast); - - const declarationType = declarationIsDefault - ? AST_NODE_TYPES.ExportDefaultDeclaration - : AST_NODE_TYPES.ExportNamedDeclaration; + result.range![0] = varToken!.getStart(ast); + result.loc = getLocFor(result.range![0], result.range![1], ast); - const newResult: any = { - type: declarationType, - declaration: result, - range: [exportKeyword.getStart(ast), result.range[1]], - loc: getLocFor(exportKeyword.getStart(ast), result.range[1], ast) - }; - - if (!declarationIsDefault) { - newResult.specifiers = []; - newResult.source = null; + if (declarationIsDefault) { + return { + type: AST_NODE_TYPES.ExportDefaultDeclaration, + declaration: result as any, + range: [exportKeyword.getStart(ast), result.range![1]], + loc: getLocFor(exportKeyword.getStart(ast), result.range![1], ast) + }; + } else { + return { + type: AST_NODE_TYPES.ExportNamedDeclaration, + declaration: result as any, + range: [exportKeyword.getStart(ast), result.range![1]], + loc: getLocFor(exportKeyword.getStart(ast), result.range![1], ast), + specifiers: [], + source: null + }; } - - return newResult; } return result; @@ -614,11 +619,11 @@ export function getTokenType(token: any): string { /** * Extends and formats a given ts.Token, for a given AST - * @param {ts.Node} token the ts.Token - * @param {ts.SourceFile} ast the AST object - * @returns {ESTreeToken} the converted ESTreeToken + * @param token the ts.Token + * @param ast the AST object + * @returns the converted es.Token */ -export function convertToken(token: ts.Node, ast: ts.SourceFile): ESTreeToken { +export function convertToken(token: ts.Node, ast: ts.SourceFile): es.Token { const start = token.kind === SyntaxKind.JsxText ? token.getFullStart() @@ -644,11 +649,11 @@ export function convertToken(token: ts.Node, ast: ts.SourceFile): ESTreeToken { /** * Converts all tokens for the given AST - * @param {ts.SourceFile} ast the AST object - * @returns {ESTreeToken[]} the converted ESTreeTokens + * @param ast the AST object + * @returns the converted Tokens */ -export function convertTokens(ast: ts.SourceFile): ESTreeToken[] { - const result: ESTreeToken[] = []; +export function convertTokens(ast: ts.SourceFile): es.Token[] { + const result: es.Token[] = []; /** * @param {ts.Node} node the ts.Node * @returns {void} diff --git a/packages/typescript-estree/src/parser-options.ts b/packages/typescript-estree/src/parser-options.ts new file mode 100644 index 000000000000..b4e60b58e5a4 --- /dev/null +++ b/packages/typescript-estree/src/parser-options.ts @@ -0,0 +1,35 @@ +import { Token, Comment, Program } from "./ast-tree-nodes"; + +export interface Extra { + errorOnUnknownASTType: boolean; + errorOnTypeScriptSyntacticAndSemanticIssues: boolean; + useJSXTextNode: boolean; + tokens: null | Token[]; + comment: boolean; + code: string; + range: boolean; + loc: boolean; + comments: Comment[]; + strict: boolean; + jsx: boolean; + log: Function; + projects: string[]; + tsconfigRootDir: string; + extraFileExtensions: string[]; +} + +export interface ParserOptions { + range?: boolean; + loc?: boolean; + tokens?: boolean; + comment?: boolean; + jsx?: boolean; + errorOnUnknownASTType?: boolean; + errorOnTypeScriptSyntacticAndSemanticIssues?: boolean; + useJSXTextNode?: boolean; + loggerFn?: Function | false; + project?: string | string[]; + filePath?: string; + tsconfigRootDir?: string; + extraFileExtensions?: string[]; +} diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index ff2784aa9963..2d762f2a2b8e 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -13,14 +13,9 @@ import semver from 'semver'; import ts from 'typescript'; import convert from './ast-converter'; import { convertError } from './convert'; -import { Program } from './estree/spec'; import { firstDefined } from './node-utils'; -import { - ESTreeComment, - ESTreeToken, - Extra, - ParserOptions -} from './temp-types-based-on-js-source'; +import * as es from './ast-tree-nodes'; +import { Extra, ParserOptions } from './parser-options'; import { getFirstSemanticOrSyntacticError } from './semantic-errors'; const packageJSON = require('../package.json'); @@ -182,10 +177,10 @@ function getProgramAndAST( // Parser //------------------------------------------------------------------------------ -type AST = Program & +type AST = es.Program & (T['range'] extends true ? { range: [number, number] } : {}) & - (T['tokens'] extends true ? { tokens: ESTreeToken[] } : {}) & - (T['comment'] extends true ? { comments: ESTreeComment[] } : {}); + (T['tokens'] extends true ? { tokens: es.Token[] } : {}) & + (T['comment'] extends true ? { comments: es.Comment[] } : {}); /** * Parses the given source code to produce a valid AST @@ -336,7 +331,7 @@ function generateAST( } return { - estree, + estree: estree as any, program: shouldProvideParserServices ? program : undefined, astMaps: shouldProvideParserServices ? astMaps! diff --git a/packages/typescript-estree/src/temp-types-based-on-js-source.ts b/packages/typescript-estree/src/temp-types-based-on-js-source.ts deleted file mode 100644 index a2234fc1308a..000000000000 --- a/packages/typescript-estree/src/temp-types-based-on-js-source.ts +++ /dev/null @@ -1,106 +0,0 @@ -/** - * NOTE: The following types are inferred from usage within the original JavaScript source. - * - * They will be gradually replaced with the more accurate types derived from the ESTree spec, and its - * applicable extensions - */ -import { AST_NODE_TYPES } from './ast-node-types'; - -export interface ESTreeToken { - type: AST_NODE_TYPES; - range: [number, number]; - loc: ESTreeNodeLoc; - value: string; - regex?: { - pattern: string; - flags: string; - }; - object?: any; - property?: any; - name?: any; -} - -export interface ESTreeNode { - type: AST_NODE_TYPES; - range: [number, number]; - loc: ESTreeNodeLoc; - declaration?: ESTreeNode; - specifiers?: (ESTreeNode | null)[]; - source?: any; - typeAnnotation?: ESTreeNode | null; - typeParameters?: ESTreeNode | null; - id?: ESTreeNode | null; - raw?: string; - value?: string; - expression?: ESTreeNode | null; - decorators?: (ESTreeNode | null)[]; - implements?: (ESTreeNode | null)[]; - extends?: (ESTreeNode | null)[]; - const?: boolean; - declare?: boolean; - global?: boolean; - modifiers?: any; - body?: any; - params?: any; - accessibility?: 'public' | 'protected' | 'private'; - readonly?: boolean | string; - static?: boolean; - export?: boolean; - parameter?: any; - abstract?: boolean; - typeName?: ESTreeNode | null; - directive?: string; - returnType?: ESTreeNode; - optional?: boolean | string; -} - -export interface ESTreeComment { - type: 'Block' | 'Line'; - range?: [number, number]; - loc?: ESTreeNodeLoc; - value: string; -} - -export interface LineAndColumnData { - line: number; - column: number; -} - -export interface ESTreeNodeLoc { - start: LineAndColumnData; - end: LineAndColumnData; -} - -export interface Extra { - errorOnUnknownASTType: boolean; - errorOnTypeScriptSyntacticAndSemanticIssues: boolean; - useJSXTextNode: boolean; - tokens: null | ESTreeToken[]; - comment: boolean; - code: string; - range: boolean; - loc: boolean; - comments: ESTreeComment[]; - strict: boolean; - jsx: boolean; - log: Function; - projects: string[]; - tsconfigRootDir: string; - extraFileExtensions: string[]; -} - -export interface ParserOptions { - range?: boolean; - loc?: boolean; - tokens?: boolean; - comment?: boolean; - jsx?: boolean; - errorOnUnknownASTType?: boolean; - errorOnTypeScriptSyntacticAndSemanticIssues?: boolean; - useJSXTextNode?: boolean; - loggerFn?: Function | false; - project?: string | string[]; - filePath?: string; - tsconfigRootDir?: string; - extraFileExtensions?: string[]; -} diff --git a/packages/typescript-estree/src/tsconfig-parser.ts b/packages/typescript-estree/src/tsconfig-parser.ts index 2212c4d0b1d0..1a150c2efd60 100644 --- a/packages/typescript-estree/src/tsconfig-parser.ts +++ b/packages/typescript-estree/src/tsconfig-parser.ts @@ -2,7 +2,7 @@ import path from 'path'; import ts from 'typescript'; -import { Extra } from './temp-types-based-on-js-source'; +import { Extra } from './parser-options'; //------------------------------------------------------------------------------ // Environment calculation diff --git a/packages/typescript-estree/tests/lib/comments.ts b/packages/typescript-estree/tests/lib/comments.ts index e469c39f00ef..1d02e2fa6715 100644 --- a/packages/typescript-estree/tests/lib/comments.ts +++ b/packages/typescript-estree/tests/lib/comments.ts @@ -8,7 +8,7 @@ import { readFileSync } from 'fs'; import glob from 'glob'; import { extname } from 'path'; -import { ParserOptions } from '../../src/temp-types-based-on-js-source'; +import { ParserOptions } from '../../src/parser-options'; import { createSnapshotTestBlock, formatSnapshotName diff --git a/packages/typescript-estree/tests/lib/javascript.ts b/packages/typescript-estree/tests/lib/javascript.ts index aca646998b3b..d254f8fd612c 100644 --- a/packages/typescript-estree/tests/lib/javascript.ts +++ b/packages/typescript-estree/tests/lib/javascript.ts @@ -7,7 +7,7 @@ */ import { readFileSync } from 'fs'; import glob from 'glob'; -import { ParserOptions } from '../../src/temp-types-based-on-js-source'; +import { ParserOptions } from '../../src/parser-options'; import { createSnapshotTestBlock, formatSnapshotName diff --git a/packages/typescript-estree/tests/lib/jsx.ts b/packages/typescript-estree/tests/lib/jsx.ts index 8b2f9f2c19de..b887911ab008 100644 --- a/packages/typescript-estree/tests/lib/jsx.ts +++ b/packages/typescript-estree/tests/lib/jsx.ts @@ -7,7 +7,7 @@ */ import { readFileSync } from 'fs'; import glob from 'glob'; -import { ParserOptions } from '../../src/temp-types-based-on-js-source'; +import { ParserOptions } from '../../src/parser-options'; import { createSnapshotTestBlock, formatSnapshotName diff --git a/packages/typescript-estree/tests/lib/parse.ts b/packages/typescript-estree/tests/lib/parse.ts index 74f02d03792c..542527d5d937 100644 --- a/packages/typescript-estree/tests/lib/parse.ts +++ b/packages/typescript-estree/tests/lib/parse.ts @@ -7,7 +7,7 @@ */ import * as parser from '../../src/parser'; import * as astConverter from '../../src/ast-converter'; -import { ParserOptions } from '../../src/temp-types-based-on-js-source'; +import { ParserOptions } from '../../src/parser-options'; import { createSnapshotTestBlock } from '../../tools/test-utils'; //------------------------------------------------------------------------------ diff --git a/packages/typescript-estree/tests/lib/semanticInfo.ts b/packages/typescript-estree/tests/lib/semanticInfo.ts index eb5af8677e97..94c370be273c 100644 --- a/packages/typescript-estree/tests/lib/semanticInfo.ts +++ b/packages/typescript-estree/tests/lib/semanticInfo.ts @@ -11,7 +11,7 @@ import { readFileSync } from 'fs'; import glob from 'glob'; import { extname, join, resolve } from 'path'; import ts from 'typescript'; -import { ParserOptions } from '../../src/temp-types-based-on-js-source'; +import { ParserOptions } from '../../src/parser-options'; import { createSnapshotTestBlock, formatSnapshotName, diff --git a/packages/typescript-estree/tests/lib/tsx.ts b/packages/typescript-estree/tests/lib/tsx.ts index 8d4230a2c91f..21dbbd57efe0 100644 --- a/packages/typescript-estree/tests/lib/tsx.ts +++ b/packages/typescript-estree/tests/lib/tsx.ts @@ -7,7 +7,7 @@ import { readFileSync } from 'fs'; import glob from 'glob'; import { extname } from 'path'; -import { ParserOptions } from '../../src/temp-types-based-on-js-source'; +import { ParserOptions } from '../../src/parser-options'; import { createSnapshotTestBlock, formatSnapshotName diff --git a/packages/typescript-estree/tests/lib/typescript.ts b/packages/typescript-estree/tests/lib/typescript.ts index dabfac14def4..9740c4570e74 100644 --- a/packages/typescript-estree/tests/lib/typescript.ts +++ b/packages/typescript-estree/tests/lib/typescript.ts @@ -8,7 +8,7 @@ import { readFileSync } from 'fs'; import glob from 'glob'; import { extname } from 'path'; -import { ParserOptions } from '../../src/temp-types-based-on-js-source'; +import { ParserOptions } from '../../src/parser-options'; import { createSnapshotTestBlock, formatSnapshotName diff --git a/packages/typescript-estree/tools/test-utils.ts b/packages/typescript-estree/tools/test-utils.ts index 9191ae5e518a..c2d57246ca09 100644 --- a/packages/typescript-estree/tools/test-utils.ts +++ b/packages/typescript-estree/tools/test-utils.ts @@ -6,7 +6,7 @@ * MIT License */ import * as parser from '../src/parser'; -import { ParserOptions } from '../src/temp-types-based-on-js-source'; +import { ParserOptions } from '../src/parser-options'; /** * Returns a raw copy of the given AST From 98fa7e2534510719489e0cce895f7d3940568163 Mon Sep 17 00:00:00 2001 From: Armano Date: Mon, 28 Jan 2019 22:36:32 +0100 Subject: [PATCH 02/18] refactor: remove dead code --- packages/typescript-estree/src/convert.ts | 14 -------------- packages/typescript-estree/src/parser-options.ts | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index d98fb82ce080..36228a07a0a8 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -41,15 +41,6 @@ interface ConverterOptions { shouldProvideParserServices: boolean; } -interface ConvertConfig { - node: ts.Node; - parent?: ts.Node | null; - inTypeMode?: boolean; - allowPattern?: boolean; - ast: ts.SourceFile; - options: ConverterOptions; -} - /** * Extends and formats a given error object * @param {Object} error the error object @@ -2508,8 +2499,3 @@ export class Converter { } } } - -export default function convert(config: ConvertConfig): es.Program | null { - const converter = new Converter(config.ast, config.options); - return converter.convertProgram(); -} diff --git a/packages/typescript-estree/src/parser-options.ts b/packages/typescript-estree/src/parser-options.ts index b4e60b58e5a4..8c2f4c1d3a16 100644 --- a/packages/typescript-estree/src/parser-options.ts +++ b/packages/typescript-estree/src/parser-options.ts @@ -1,4 +1,4 @@ -import { Token, Comment, Program } from "./ast-tree-nodes"; +import { Token, Comment } from './ast-tree-nodes'; export interface Extra { errorOnUnknownASTType: boolean; From fbcfdcf97a2394505251e1dde36c2769615145f0 Mon Sep 17 00:00:00 2001 From: Armano Date: Mon, 28 Jan 2019 22:47:01 +0100 Subject: [PATCH 03/18] refactor: remove dead code --- packages/typescript-estree/src/node-utils.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index d995032388b9..8e5f1de9af6e 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -279,20 +279,6 @@ export function canContainDirective(node: ts.Node): boolean { } } -/** - * Returns line and column data for the given ts.Node or ts.Token, - * for the given AST - * @param {ts.Node} nodeOrToken the ts.Node or ts.Token - * @param {ts.SourceFile} ast the AST object - * @returns {ESTreeLoc} the loc data - */ -export function getLoc( - nodeOrToken: ts.Node, - ast: ts.SourceFile -): es.SourceLocation { - return getLocFor(nodeOrToken.getStart(ast), nodeOrToken.end, ast); -} - /** * Returns range for the given ts.Node * @param node the ts.Node or ts.Token From d10cb7f8e237a6a8e8bbaa97a9e054d283b0c8d3 Mon Sep 17 00:00:00 2001 From: Armano Date: Tue, 29 Jan 2019 00:32:42 +0100 Subject: [PATCH 04/18] refactor: add missing type checks --- packages/typescript-estree/src/ast-nodes.ts | 2 +- .../typescript-estree/src/ast-tree-nodes.ts | 1 - packages/typescript-estree/src/convert.ts | 23 +++++++------------ packages/typescript-estree/src/node-utils.ts | 2 +- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/packages/typescript-estree/src/ast-nodes.ts b/packages/typescript-estree/src/ast-nodes.ts index d17de7363e54..f4041055cf1c 100644 --- a/packages/typescript-estree/src/ast-nodes.ts +++ b/packages/typescript-estree/src/ast-nodes.ts @@ -1,6 +1,6 @@ import * as es from './ast-tree-nodes'; -export type ASTTreeNodes = +export type ASTNode = | es.ArrayExpression | es.ArrayPattern | es.ArrowFunctionExpression diff --git a/packages/typescript-estree/src/ast-tree-nodes.ts b/packages/typescript-estree/src/ast-tree-nodes.ts index 6259afaebb4e..78ecc4e9d5ad 100644 --- a/packages/typescript-estree/src/ast-tree-nodes.ts +++ b/packages/typescript-estree/src/ast-tree-nodes.ts @@ -27,7 +27,6 @@ export interface BaseNode { } export interface Token extends BaseNode { - type: AST_NODE_TYPES; value: string; regex?: { pattern: string; diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 36228a07a0a8..f72299c7ee8c 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -31,7 +31,7 @@ import { } from './node-utils'; import { AST_NODE_TYPES } from './ast-node-types'; import { TSNode } from './ts-nodes'; -import { ASTTreeNodes } from './ast-nodes'; +import { ASTNode } from './ast-nodes'; const SyntaxKind = ts.SyntaxKind; @@ -160,7 +160,7 @@ export class Converter { return this.converter(child, parent, true, false); } - protected createNode( + protected createNode( node: ts.Node, data: T ): T { @@ -186,7 +186,6 @@ export class Converter { child: ts.TypeNode, parent: ts.Node ): es.TSTypeAnnotation { - const annotation = this.convertType(child); // in FunctionType and ConstructorType typeAnnotation has 2 characters `=>` and in other places is just colon const offset = parent.kind === SyntaxKind.FunctionType || @@ -200,7 +199,7 @@ export class Converter { type: AST_NODE_TYPES.TSTypeAnnotation, loc, range: [annotationStartCol, child.end], - typeAnnotation: annotation + typeAnnotation: this.convertType(child) }; } @@ -484,8 +483,7 @@ export class Converter { node: ts.TypeNode ): void { typeAnnotationParent.range![1] = node.getEnd(); - typeAnnotationParent.loc = getLocFor( - typeAnnotationParent.range![0], + typeAnnotationParent.loc!.end = getLineAndCharacterFor( typeAnnotationParent.range![1], this.ast ); @@ -499,7 +497,7 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - protected convertNode(node: TSNode, parent: ts.Node): ASTTreeNodes | null { + protected convertNode(node: TSNode, parent: ts.Node): ASTNode | null { switch (node.kind) { case SyntaxKind.SourceFile: { return this.createNode(node, { @@ -1705,15 +1703,12 @@ export class Converter { } case SyntaxKind.MetaProperty: { - const newToken = convertToken(node.getFirstToken()!, this.ast); return this.createNode(node, { type: AST_NODE_TYPES.MetaProperty, - meta: { + meta: this.createNode(node.getFirstToken()!, { type: AST_NODE_TYPES.Identifier, - range: newToken.range, - loc: newToken.loc, name: getTextForTokenKind(node.keywordToken)! - }, + }), property: this.convertChild(node.name) }); } @@ -1925,10 +1920,8 @@ export class Converter { } case SyntaxKind.JsxAttribute: { - const attributeName = convertToken(node.name, this.ast) as any; + const attributeName = this.convertChild(node.name); attributeName.type = AST_NODE_TYPES.JSXIdentifier; - attributeName.name = attributeName.value; - delete attributeName.value; return this.createNode(node, { type: AST_NODE_TYPES.JSXAttribute, diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index 8e5f1de9af6e..aa9b20a3e928 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -616,7 +616,7 @@ export function convertToken(token: ts.Node, ast: ts.SourceFile): es.Token { : token.getStart(ast), end = token.getEnd(), value = ast.text.slice(start, end), - newToken: any = { + newToken: es.Token = { type: getTokenType(token), value, range: [start, end], From 8b998a350f6fa45a978b9d0af397842eb5b08554 Mon Sep 17 00:00:00 2001 From: Armano Date: Tue, 29 Jan 2019 00:40:13 +0100 Subject: [PATCH 05/18] refactor: remove unnecessary type casings --- packages/typescript-estree/src/convert.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index f72299c7ee8c..318d7c5334e7 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -172,7 +172,7 @@ export class Converter { result.loc = getLocFor(result.range[0], result.range[1], this.ast); } - return result as T & { range: [number, number]; loc: es.SourceLocation }; + return result; } /** @@ -246,7 +246,7 @@ export class Converter { * @returns TypeParameterInstantiation node */ protected convertTypeArgumentsToTypeParameters( - typeArguments: ts.NodeArray + typeArguments: ts.NodeArray ): es.TSTypeParameterInstantiation { const greaterThanToken = findNextToken(typeArguments, this.ast, this.ast)!; @@ -264,7 +264,7 @@ export class Converter { * @returns TypeParameterDeclaration node */ protected convertTSTypeParametersToTypeParametersDeclaration( - typeParameters: ts.NodeArray + typeParameters: ts.NodeArray ): es.TSTypeParameterDeclaration { const greaterThanToken = findNextToken(typeParameters, this.ast, this.ast)!; From eed071cb66c8db970595ee53010637053bebea47 Mon Sep 17 00:00:00 2001 From: Armano Date: Fri, 1 Feb 2019 18:46:44 +0100 Subject: [PATCH 06/18] chore(ts-estree): remove unneeded types from comments --- packages/typescript-estree/src/convert.ts | 4 +- packages/typescript-estree/src/node-utils.ts | 131 +++++++++--------- packages/typescript-estree/src/parser.ts | 25 ++-- .../typescript-estree/src/tsconfig-parser.ts | 23 ++- 4 files changed, 87 insertions(+), 96 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 318d7c5334e7..7f9e7eff6b26 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -43,8 +43,8 @@ interface ConverterOptions { /** * Extends and formats a given error object - * @param {Object} error the error object - * @returns {Object} converted error object + * @param error the error object + * @returns converted error object */ export function convertError(error: any) { return createError( diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index aa9b20a3e928..b8437820773b 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -97,8 +97,8 @@ const TOKEN_TO_TEXT: { readonly [P in ts.SyntaxKind]?: string } = { /** * Returns true if the given ts.Token is the assignment operator - * @param {ts.Token} operator the operator token - * @returns {boolean} is assignment + * @param operator the operator token + * @returns is assignment */ export function isAssignmentOperator( operator: ts.Token @@ -108,8 +108,8 @@ export function isAssignmentOperator( /** * Returns true if the given ts.Token is a logical operator - * @param {ts.Token} operator the operator token - * @returns {boolean} is a logical operator + * @param operator the operator token + * @returns is a logical operator */ export function isLogicalOperator( operator: ts.Token @@ -119,8 +119,8 @@ export function isLogicalOperator( /** * Returns the string form of the given TSToken SyntaxKind - * @param {number} kind the token's SyntaxKind - * @returns {string} the token applicable token as a string + * @param kind the token's SyntaxKind + * @returns the token applicable token as a string */ export function getTextForTokenKind(kind: ts.SyntaxKind): string | undefined { return TOKEN_TO_TEXT[kind]; @@ -128,8 +128,8 @@ export function getTextForTokenKind(kind: ts.SyntaxKind): string | undefined { /** * Returns true if the given ts.Node is a valid ESTree class member - * @param {ts.Node} node TypeScript AST node - * @returns {boolean} is valid ESTree class member + * @param node TypeScript AST node + * @returns is valid ESTree class member */ export function isESTreeClassMember(node: ts.Node): boolean { return node.kind !== SyntaxKind.SemicolonClassElement; @@ -137,9 +137,9 @@ export function isESTreeClassMember(node: ts.Node): boolean { /** * Checks if a ts.Node has a modifier - * @param {ts.KeywordSyntaxKind} modifierKind TypeScript SyntaxKind modifier - * @param {ts.Node} node TypeScript AST node - * @returns {boolean} has the modifier specified + * @param modifierKind TypeScript SyntaxKind modifier + * @param node TypeScript AST node + * @returns has the modifier specified */ export function hasModifier( modifierKind: ts.KeywordSyntaxKind, @@ -168,8 +168,8 @@ export function getLastModifier(node: ts.Node): ts.Modifier | null { /** * Returns true if the given ts.Token is a comma - * @param {ts.Node} token the TypeScript token - * @returns {boolean} is comma + * @param token the TypeScript token + * @returns is comma */ export function isComma(token: ts.Node): boolean { return token.kind === SyntaxKind.CommaToken; @@ -177,8 +177,8 @@ export function isComma(token: ts.Node): boolean { /** * Returns true if the given ts.Node is a comment - * @param {ts.Node} node the TypeScript node - * @returns {boolean} is comment + * @param node the TypeScript node + * @returns is comment */ export function isComment(node: ts.Node): boolean { return ( @@ -189,8 +189,8 @@ export function isComment(node: ts.Node): boolean { /** * Returns true if the given ts.Node is a JSDoc comment - * @param {ts.Node} node the TypeScript node - * @returns {boolean} is JSDoc comment + * @param node the TypeScript node + * @returns is JSDoc comment */ export function isJSDocComment(node: ts.Node): boolean { return node.kind === SyntaxKind.JSDocComment; @@ -198,8 +198,8 @@ export function isJSDocComment(node: ts.Node): boolean { /** * Returns the binary expression type of the given ts.Token - * @param {ts.Token} operator the operator token - * @returns {string} the binary expression type + * @param operator the operator token + * @returns the binary expression type */ export function getBinaryExpressionType( operator: ts.Token @@ -235,10 +235,10 @@ export function getLineAndCharacterFor( /** * Returns line and column data for the given start and end positions, * for the given AST - * @param {number} start start data - * @param {number} end end data - * @param {ts.SourceFile} ast the AST object - * @returns {es.SourceLocation} the loc data + * @param start start data + * @param end end data + * @param ast the AST object + * @returns the loc data */ export function getLocFor( start: number, @@ -253,8 +253,8 @@ export function getLocFor( /** * Check whatever node can contain directive - * @param {ts.Node} node - * @returns {boolean} returns true if node can contain directive + * @param node + * @returns returns true if node can contain directive */ export function canContainDirective(node: ts.Node): boolean { switch (node.kind) { @@ -291,8 +291,8 @@ export function getRange(node: ts.Node, ast: ts.SourceFile): [number, number] { /** * Returns true if a given ts.Node is a token - * @param {ts.Node} node the ts.Node - * @returns {boolean} is a token + * @param node the ts.Node + * @returns is a token */ export function isToken(node: ts.Node): boolean { return ( @@ -302,8 +302,8 @@ export function isToken(node: ts.Node): boolean { /** * Returns true if a given ts.Node is a JSX token - * @param {ts.Node} node ts.Node to be checked - * @returns {boolean} is a JSX token + * @param node ts.Node to be checked + * @returns is a JSX token */ export function isJSXToken(node: ts.Node): boolean { return ( @@ -313,8 +313,8 @@ export function isJSXToken(node: ts.Node): boolean { /** * Returns the declaration kind of the given ts.Node - * @param {ts.VariableDeclarationList} node TypeScript AST node - * @returns {string} declaration kind + * @param node TypeScript AST node + * @returns declaration kind */ export function getDeclarationKind( node: ts.VariableDeclarationList @@ -330,8 +330,8 @@ export function getDeclarationKind( /** * Gets a ts.Node's accessibility level - * @param {ts.Node} node The ts.Node - * @returns {string | null} accessibility "public", "protected", "private", or null + * @param node The ts.Node + * @returns accessibility "public", "protected", "private", or null */ export function getTSNodeAccessibility( node: ts.Node @@ -359,10 +359,10 @@ export function getTSNodeAccessibility( /** * Finds the next token based on the previous one and its parent * Had to copy this from TS instead of using TS's version because theirs doesn't pass the ast to getChildren - * @param {ts.TextRange} previousToken The previous TSToken - * @param {ts.Node} parent The parent TSNode - * @param {ts.SourceFile} ast The TS AST - * @returns {ts.Node|undefined} the next TSToken + * @param previousToken The previous TSToken + * @param parent The parent TSNode + * @param ast The TS AST + * @returns the next TSToken */ export function findNextToken( previousToken: ts.TextRange, @@ -391,9 +391,9 @@ export function findNextToken( /** * Find the first matching ancestor based on the given predicate function. - * @param {ts.Node} node The current ts.Node - * @param {Function} predicate The predicate function to apply to each checked ancestor - * @returns {ts.Node|undefined} a matching parent ts.Node + * @param node The current ts.Node + * @param predicate The predicate function to apply to each checked ancestor + * @returns a matching parent ts.Node */ export function findFirstMatchingAncestor( node: ts.Node, @@ -410,8 +410,8 @@ export function findFirstMatchingAncestor( /** * Returns true if a given ts.Node has a JSX token within its hierarchy - * @param {ts.Node} node ts.Node to be checked - * @returns {boolean} has JSX ancestor + * @param node ts.Node to be checked + * @returns has JSX ancestor */ export function hasJSXAncestor(node: ts.Node): boolean { return !!findFirstMatchingAncestor(node, isJSXToken); @@ -419,8 +419,8 @@ export function hasJSXAncestor(node: ts.Node): boolean { /** * Unescape the text content of string literals, e.g. & -> & - * @param {string} text The escaped string literal text. - * @returns {string} The unescaped string literal text. + * @param text The escaped string literal text. + * @returns The unescaped string literal text. */ export function unescapeStringLiteralText(text: string): string { return unescape(text); @@ -428,8 +428,8 @@ export function unescapeStringLiteralText(text: string): string { /** * Returns true if a given ts.Node is a computed property - * @param {ts.Node} node ts.Node to be checked - * @returns {boolean} is Computed Property + * @param node ts.Node to be checked + * @returns is Computed Property */ export function isComputedProperty(node: ts.Node): boolean { return node.kind === SyntaxKind.ComputedPropertyName; @@ -437,8 +437,8 @@ export function isComputedProperty(node: ts.Node): boolean { /** * Returns true if a given ts.Node is optional (has QuestionToken) - * @param {ts.Node} node ts.Node to be checked - * @returns {boolean} is Optional + * @param node ts.Node to be checked + * @returns is Optional */ export function isOptional(node: { questionToken?: ts.QuestionToken; @@ -498,8 +498,8 @@ export function fixExports( /** * Returns the type of a given ts.Token - * @param {ts.Token} token the ts.Token - * @returns {string} the token type + * @param token the ts.Token + * @returns the token type */ export function getTokenType(token: any): string { // Need two checks for keywords since some are also identifiers @@ -641,8 +641,7 @@ export function convertToken(token: ts.Node, ast: ts.SourceFile): es.Token { export function convertTokens(ast: ts.SourceFile): es.Token[] { const result: es.Token[] = []; /** - * @param {ts.Node} node the ts.Node - * @returns {void} + * @param node the ts.Node */ function walk(node: ts.Node): void { // TypeScript generates tokens for types in JSDoc blocks. Comment tokens @@ -667,10 +666,10 @@ export function convertTokens(ast: ts.SourceFile): es.Token[] { /** * Get container token node between range - * @param {ts.SourceFile} ast the AST object - * @param {number} start The index at which the comment starts. - * @param {number} end The index at which the comment ends. - * @returns {ts.Node} typescript container token + * @param ast the AST object + * @param start The index at which the comment starts. + * @param end The index at which the comment ends. + * @returns typescript container token * @private */ export function getNodeContainer( @@ -681,8 +680,7 @@ export function getNodeContainer( let container: ts.Node | null = null; /** - * @param {ts.Node} node the ts.Node - * @returns {void} + * @param node the ts.Node */ function walk(node: ts.Node): void { const nodeStart = node.pos; @@ -702,10 +700,10 @@ export function getNodeContainer( } /** - * @param {ts.SourceFile} ast the AST object - * @param {number} start the index at which the error starts - * @param {string} message the error message - * @returns {Object} converted error object + * @param ast the AST object + * @param start the index at which the error starts + * @param message the error message + * @returns converted error object */ export function createError( ast: ts.SourceFile, @@ -722,8 +720,8 @@ export function createError( } /** - * @param {ts.Node} n the TSNode - * @param {ts.SourceFile} ast the TS AST + * @param n the TSNode + * @param ast the TS AST */ export function nodeHasTokens(n: ts.Node, ast: ts.SourceFile) { // If we have a token or node that has a non-zero width, it must have tokens. @@ -737,9 +735,8 @@ export function nodeHasTokens(n: ts.Node, ast: ts.SourceFile) { * Like `forEach`, but suitable for use with numbers and strings (which may be falsy). * @template T * @template U - * @param {ReadonlyArray|undefined} array - * @param {(element: T, index: number) => (U|undefined)} callback - * @returns {U|undefined} + * @param array + * @param callback */ export function firstDefined( array: ReadonlyArray | undefined, diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index 296115763ded..6df67bea0016 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -44,7 +44,6 @@ function getFileName({ jsx }: { jsx?: boolean }) { /** * Resets the extra config object - * @returns {void} */ function resetExtra(): void { extra = { @@ -67,9 +66,9 @@ function resetExtra(): void { } /** - * @param {string} code The code of the file being linted - * @param {Object} options The config object - * @returns {{ast: ts.SourceFile, program: ts.Program} | undefined} If found, returns the source file corresponding to the code and the containing program + * @param code The code of the file being linted + * @param options The config object + * @returns If found, returns the source file corresponding to the code and the containing program */ function getASTFromProject(code: string, options: ParserOptions) { return firstDefined( @@ -88,9 +87,9 @@ function getASTFromProject(code: string, options: ParserOptions) { } /** - * @param {string} code The code of the file being linted - * @param {Object} options The config object - * @returns {{ast: ts.SourceFile, program: ts.Program} | undefined} If found, returns the source file corresponding to the code and the containing program + * @param code The code of the file being linted + * @param options The config object + * @returns If found, returns the source file corresponding to the code and the containing program */ function getASTAndDefaultProject(code: string, options: ParserOptions) { const fileName = options.filePath || getFileName(options); @@ -100,8 +99,8 @@ function getASTAndDefaultProject(code: string, options: ParserOptions) { } /** - * @param {string} code The code of the file being linted - * @returns {{ast: ts.SourceFile, program: ts.Program}} Returns a new source file and program corresponding to the linted code + * @param code The code of the file being linted + * @returns Returns a new source file and program corresponding to the linted code */ function createNewProgram(code: string) { const FILENAME = getFileName(extra); @@ -157,10 +156,10 @@ function createNewProgram(code: string) { } /** - * @param {string} code The code of the file being linted - * @param {Object} options The config object - * @param {boolean} shouldProvideParserServices True iff the program should be attempted to be calculated from provided tsconfig files - * @returns {{ast: ts.SourceFile, program: ts.Program}} Returns a source file and program corresponding to the linted code + * @param code The code of the file being linted + * @param options The config object + * @param shouldProvideParserServices True iff the program should be attempted to be calculated from provided tsconfig files + * @returns Returns a source file and program corresponding to the linted code */ function getProgramAndAST( code: string, diff --git a/packages/typescript-estree/src/tsconfig-parser.ts b/packages/typescript-estree/src/tsconfig-parser.ts index 1a150c2efd60..3d68a034c16e 100644 --- a/packages/typescript-estree/src/tsconfig-parser.ts +++ b/packages/typescript-estree/src/tsconfig-parser.ts @@ -10,7 +10,6 @@ import { Extra } from './parser-options'; /** * Default compiler options for program generation from single root file - * @type {ts.CompilerOptions} */ const defaultCompilerOptions: ts.CompilerOptions = { allowNonTsExtensions: true, @@ -19,7 +18,6 @@ const defaultCompilerOptions: ts.CompilerOptions = { /** * Maps tsconfig paths to their corresponding file contents and resulting watches - * @type {Map>} */ const knownWatchProgramMap = new Map< string, @@ -29,13 +27,11 @@ const knownWatchProgramMap = new Map< /** * Maps file paths to their set of corresponding watch callbacks * There may be more than one per file if a file is shared between projects - * @type {Map} */ const watchCallbackTrackingMap = new Map(); /** * Holds information about the file currently being linted - * @type {{code: string, filePath: string}} */ const currentLintOperationState = { code: '', @@ -44,8 +40,7 @@ const currentLintOperationState = { /** * Appropriately report issues found when reading a config file - * @param {ts.Diagnostic} diagnostic The diagnostic raised when creating a program - * @returns {void} + * @param diagnostic The diagnostic raised when creating a program */ function diagnosticReporter(diagnostic: ts.Diagnostic): void { throw new Error( @@ -57,11 +52,11 @@ const noopFileWatcher = { close: () => {} }; /** * Calculate project environments using options provided by consumer and paths from config - * @param {string} code The code being linted - * @param {string} filePath The path of the file being parsed - * @param {string} extra.tsconfigRootDir The root directory for relative tsconfig paths - * @param {string[]} extra.project Provided tsconfig paths - * @returns {ts.Program[]} The programs corresponding to the supplied tsconfig paths + * @param code The code being linted + * @param filePath The path of the file being parsed + * @param extra.tsconfigRootDir The root directory for relative tsconfig paths + * @param extra.project Provided tsconfig paths + * @returns The programs corresponding to the supplied tsconfig paths */ export function calculateProjectParserOptions( code: string, @@ -187,9 +182,9 @@ export function calculateProjectParserOptions( * Create program from single root file. Requires a single tsconfig to be specified. * @param code The code being linted * @param filePath The file being linted - * @param {string} extra.tsconfigRootDir The root directory for relative tsconfig paths - * @param {string[]} extra.project Provided tsconfig paths - * @returns {ts.Program} The program containing just the file being linted and associated library files + * @param extra.tsconfigRootDir The root directory for relative tsconfig paths + * @param extra.project Provided tsconfig paths + * @returns The program containing just the file being linted and associated library files */ export function createProgram(code: string, filePath: string, extra: Extra) { if (!extra.projects || extra.projects.length !== 1) { From 97b1736d2478195a5a266da91a36d6ddc6f04180 Mon Sep 17 00:00:00 2001 From: Armano Date: Fri, 1 Feb 2019 21:49:09 +0100 Subject: [PATCH 07/18] chore: add typedefs --- packages/typescript-estree/src/typedefs.ts | 1380 ++++++++++++++++++++ 1 file changed, 1380 insertions(+) create mode 100644 packages/typescript-estree/src/typedefs.ts diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts new file mode 100644 index 000000000000..f8fac2f818ff --- /dev/null +++ b/packages/typescript-estree/src/typedefs.ts @@ -0,0 +1,1380 @@ +export interface LineAndColumnData { + /** + * Line number (1-indexed) + */ + line: number; + /** + * Column number on the line (0-indexed) + */ + column: number; +} +export interface NodeLocation { + /** + * The position of the first character of the parsed source region + */ + start: LineAndColumnData; + /** + * The position of the first character after the parsed source region + */ + end: LineAndColumnData; +} + +interface NodeBase { + /** + * The source location information of the node. + */ + loc: NodeLocation; + /** + * An array of two numbers. + * Both numbers are a 0-based index which is the position in the array of source code characters. + * The first is the start position of the node, the second is the end position of the node. + */ + range: [number, number]; + /** + * The parent node of the current node + */ + parent?: Node; + + // every node *will* have a type, but let the nodes define their own exact string + // type: string; + + // we don't ever set this from within ts-estree + // source?: string | null; +} + +export type Node = + | ArrayExpression + | ArrayPattern + | ArrowFunctionExpression + | AssignmentExpression + | AssignmentPattern + | AwaitExpression + | BigIntLiteral + | BinaryExpression + | BlockStatement + | BreakStatement + | CallExpression + | CatchClause + | ClassBody + | ClassDeclaration + | ClassExpression + | ClassProperty + | ConditionalExpression + | ContinueStatement + | DebuggerStatement + | Decorator + | DoWhileStatement + | EmptyStatement + | ExportAllDeclaration + | ExportDefaultDeclaration + | ExportNamedDeclaration + | ExportSpecifier + | ExpressionStatement + | ForInStatement + | ForOfStatement + | ForStatement + | FunctionDeclaration + | FunctionExpression + | Identifier + | IfStatement + | Import + | ImportDeclaration + | ImportDefaultSpecifier + | ImportNamespaceSpecifier + | ImportSpecifier + | JSXAttribute + | JSXClosingElement + | JSXClosingFragment + | JSXElement + | JSXEmptyExpression + | JSXExpressionContainer + | JSXFragment + | JSXIdentifier + | JSXOpeningElement + | JSXOpeningFragment + | JSXSpreadAttribute + | JSXSpreadChild + | JSXText + | LabeledStatement + | Literal + | LogicalExpression + | MemberExpression + | MetaProperty + | MethodDefinition + | NewExpression + | ObjectExpression + | ObjectPattern + | Program + | Property + | RestElement + | ReturnStatement + | SequenceExpression + | SpreadElement + | Super + | SwitchCase + | SwitchStatement + | TaggedTemplateExpression + | TemplateElement + | TemplateLiteral + | ThisExpression + | ThrowStatement + | TryStatement + | TSAbstractClassProperty + | TSAbstractKeyword + | TSAbstractMethodDefinition + | TSAnyKeyword + | TSArrayType + | TSAsExpression + | TSAsyncKeyword + | TSBigIntKeyword + | TSBooleanKeyword + | TSCallSignatureDeclaration + | TSClassImplements + | TSConditionalType + | TSConstKeyword + | TSConstructorType + | TSConstructSignatureDeclaration + | TSDeclareFunction + | TSDeclareKeyword + | TSDefaultKeyword + | TSEnumDeclaration + | TSEnumMember + | TSExportAssignment + | TSExportKeyword + | TSExternalModuleReference + | TSFunctionType + | TSImportEqualsDeclaration + | TSImportType + | TSIndexedAccessType + | TSIndexSignature + | TSInferType + | TSInterfaceDeclaration + | TSInterfaceBody + | TSInterfaceHeritage + | TSIntersectionType + | TSLiteralType + | TSMappedType + | TSMethodSignature + | TSModuleBlock + | TSModuleDeclaration + | TSNamespaceExportDeclaration + | TSNeverKeyword + | TSNonNullExpression + | TSNullKeyword + | TSNumberKeyword + | TSObjectKeyword + | TSOptionalType + | TSParameterProperty + | TSParenthesizedType + | TSPropertySignature + | TSPublicKeyword + | TSPrivateKeyword + | TSProtectedKeyword + | TSQualifiedName + | TSReadonlyKeyword + | TSRestType + | TSStaticKeyword + | TSStringKeyword + | TSSymbolKeyword + | TSThisType + | TSTupleType + | TSTypeAliasDeclaration + | TSTypeAnnotation + | TSTypeAssertion + | TSTypeLiteral + | TSTypeOperator + | TSTypeParameter + | TSTypeParameterDeclaration + | TSTypeParameterInstantiation + | TSTypePredicate + | TSTypeQuery + | TSTypeReference + | TSUndefinedKeyword + | TSUnionType + | TSUnknownKeyword + | TSVoidKeyword + | UpdateExpression + | UnaryExpression + | VariableDeclaration + | VariableDeclarator + | WhileStatement + | WithStatement + | YieldExpression; + +////////// +// Reusable Unions +// These are based off of types used in the Typescript AST definitions +// **Ensure you sort the union members alphabetically** +////////// + +export type Accessibility = 'public' | 'protected' | 'private'; +export type BindingPattern = ArrayPattern | ObjectPattern; +export type BindingName = BindingPattern | Identifier; +export type ClassElement = + | ClassProperty + | FunctionExpression + | MethodDefinition + | TSAbstractClassProperty + | TSAbstractMethodDefinition + | TSIndexSignature; +export type DeclarationStatement = + | ClassDeclaration + | ClassExpression + | ExportAllDeclaration + | ExportNamedDeclaration + | FunctionDeclaration + | TSDeclareFunction + | TSImportEqualsDeclaration + | TSInterfaceDeclaration + | TSModuleDeclaration + | TSNamespaceExportDeclaration + | TSTypeAliasDeclaration + | TSEnumDeclaration; +export type EntityName = Identifier | TSQualifiedName; +export type ExportDeclaration = + | ClassDeclaration + | ClassExpression + | FunctionDeclaration + | TSDeclareFunction + | TSEnumDeclaration + | TSInterfaceDeclaration + | TSModuleDeclaration + | TSTypeAliasDeclaration + | VariableDeclarator; +export type Expression = + | ArrowFunctionExpression + | AssignmentExpression + | BinaryExpression + | ConditionalExpression + | JSXClosingElement + | JSXClosingFragment + | JSXExpressionContainer + | JSXOpeningElement + | JSXOpeningFragment + | JSXSpreadChild + | LogicalExpression + | RestElement + | SequenceExpression + | SpreadElement + | TSAsExpression + | TSUnaryExpression + | YieldExpression; +export type ExpressionWithTypeArguments = + | TSClassImplements + | TSInterfaceHeritage; +export type ForInitialiser = Expression | VariableDeclaration; +export type ImportClause = + | ImportDefaultSpecifier + | ImportNamespaceSpecifier + | ImportSpecifier; +export type IterationStatement = + | DoWhileStatement + | ForInStatement + | ForOfStatement + | ForStatement + | WhileStatement; +export type JSXChild = JSXElement | JSXExpression | JSXFragment | JSXText; +export type JSXExpression = + | JSXEmptyExpression + | JSXSpreadChild + | JSXExpressionContainer; +export type JSXTagNameExpression = JSXIdentifier | JSXMemberExpression; +export type LeftHandSideExpression = + | CallExpression + | ClassExpression + | ClassDeclaration + | FunctionExpression + | LiteralExpression + | MemberExpression + | PrimaryExpression + | TaggedTemplateExpression + | TSNonNullExpression; +export type LiteralExpression = BigIntLiteral | Literal | TemplateLiteral; +export type Modifier = + | TSAbstractKeyword + | TSAsyncKeyword + | TSConstKeyword + | TSDeclareKeyword + | TSDefaultKeyword + | TSExportKeyword + | TSPublicKeyword + | TSPrivateKeyword + | TSProtectedKeyword + | TSReadonlyKeyword + | TSStaticKeyword; +export type ObjectLiteralElementLike = + | MethodDefinition + | Property + | RestElement + | SpreadElement + | TSAbstractMethodDefinition; +export type Parameter = AssignmentPattern | RestElement | TSParameterProperty; +export type PrimaryExpression = + | ArrayExpression + | ArrayPattern + | ClassExpression + | FunctionExpression + | Identifier + | Import + | JSXElement + | JSXFragment + | JSXOpeningElement + | Literal + | LiteralExpression + | MetaProperty + | ObjectExpression + | ObjectPattern + | Super + | TemplateLiteral + | ThisExpression + | TSNullKeyword; +export type PropertyName = Identifier | Literal; +export type Statement = + | BlockStatement + | BreakStatement + | ContinueStatement + | DebuggerStatement + | DeclarationStatement + | EmptyStatement + | ExpressionStatement + | IfStatement + | IterationStatement + | ImportDeclaration + | LabeledStatement + | TSModuleBlock + | ReturnStatement + | SwitchStatement + | ThrowStatement + | TryStatement + | VariableDeclaration + | WithStatement; +export type TypeElement = + | TSCallSignatureDeclaration + | TSConstructSignatureDeclaration + | TSIndexSignature + | TSMethodSignature + | TSPropertySignature; +export type TypeNode = + | ThisExpression + | TSAnyKeyword + | TSArrayType + | TSBigIntKeyword + | TSBooleanKeyword + | TSClassImplements + | TSConditionalType + | TSConstructorType + | TSFunctionType + | TSImportType + | TSIndexedAccessType + | TSInferType + | TSInterfaceHeritage + | TSIntersectionType + | TSLiteralType + | TSMappedType + | TSNeverKeyword + | TSNullKeyword + | TSNumberKeyword + | TSObjectKeyword + | TSOptionalType + | TSParenthesizedType + | TSRestType + | TSStringKeyword + | TSSymbolKeyword + | TSThisType + | TSTupleType + | TSTypeLiteral + | TSTypeOperator + | TSTypeReference + | TSTypePredicate + | TSTypeQuery + | TSUndefinedKeyword + | TSUnionType + | TSUnknownKeyword + | TSVoidKeyword; +export type TSUnaryExpression = + | AwaitExpression + | LeftHandSideExpression + | TSTypeAssertion + | UnaryExpression + | UpdateExpression; + +/////////////// +// Base, common types +// **Ensure you sort the interfaces alphabetically** +/////////////// + +interface BinaryExpressionBase extends NodeBase { + operator: string; + left: Expression; + right: Expression; +} + +interface ClassDeclarationBase extends NodeBase { + typeParameters?: TSTypeParameterDeclaration; + superTypeParameters?: TSTypeParameterInstantiation; + id?: Identifier; + body: ClassBody; + superClass?: LeftHandSideExpression; + implements?: ExpressionWithTypeArguments[]; + abstract?: boolean; + declare?: boolean; + decorators?: Decorator[]; +} + +interface ClassPropertyBase extends NodeBase { + key: PropertyName; + value: Expression; + computed: boolean; + static: boolean; + readonly?: boolean; + decorators?: Decorator[]; + accessibility?: Accessibility; + optional?: boolean; + definite?: boolean; + typeAnnotation?: TSTypeAnnotation; +} + +interface FunctionDeclarationBase extends NodeBase { + id: Identifier | null; + generator: boolean; + expression: boolean; + async: boolean; + params: Parameter[]; + body?: BlockStatement | null; + returnType?: TSTypeAnnotation; + typeParameters?: TSTypeParameterDeclaration; +} + +interface FunctionSignatureBase extends NodeBase { + params: Parameter[]; + returnType?: TSTypeAnnotation; + typeParameters?: TSTypeParameterDeclaration; +} + +interface LiteralBase extends NodeBase { + raw: boolean | number | RegExp | string | null; + value: string; + regex?: { + pattern: string; + flags: string; + }; +} + +interface MethodDefinitionBase extends NodeBase { + key: PropertyName; + value: FunctionExpression; + computed: boolean; + static: boolean; + kind: 'method' | 'get' | 'set' | 'constructor'; + decorators?: Decorator[]; + accessibility?: Accessibility; + typeParameters?: TSTypeParameterDeclaration; +} + +interface TSHeritageBase extends NodeBase { + expression: Expression; + typeParameters?: TSTypeParameterDeclaration; +} + +interface UnaryExpressionBase extends NodeBase { + operator: string; + prefix: boolean; + argument: LeftHandSideExpression | Literal | UnaryExpression; +} + +/////////////// +// Typescript ESTree Nodes +// **Ensure you sort the interfaces alphabetically** +/////////////// + +export interface ArrayExpression extends NodeBase { + type: 'ArrayExpression'; + elements: Expression[]; +} + +export interface ArrayPattern extends NodeBase { + type: 'ArrayPattern'; + elements: Expression[]; + typeAnnotation?: TSTypeAnnotation; + optional?: boolean; +} + +export interface ArrowFunctionExpression extends NodeBase { + type: 'ArrowFunctionExpression'; + generator: boolean; + id: null; + params: Parameter[]; + body: Expression | BlockStatement; + async: boolean; + expression: boolean; + returnType: TSTypeAnnotation; + typeParameters: TSTypeParameterDeclaration; +} + +export interface AssignmentExpression extends BinaryExpressionBase { + type: 'AssignmentExpression'; +} + +export interface AssignmentPattern extends NodeBase { + type: 'AssignmentPattern'; + left: BindingName; + right?: Expression; + typeAnnotation?: TSTypeAnnotation; + optional?: boolean; +} + +export interface AwaitExpression extends NodeBase { + type: 'AwaitExpression'; + argument: TSUnaryExpression; +} + +export interface BigIntLiteral extends LiteralBase { + type: 'BigIntLiteral'; +} + +export interface BinaryExpression extends BinaryExpressionBase { + type: 'BinaryExpression'; +} + +export interface BlockStatement extends NodeBase { + type: 'BlockStatement'; + body: Statement[]; +} + +export interface BreakStatement extends NodeBase { + type: 'BreakStatement'; + label: Identifier | null; +} + +export interface CallExpression extends NodeBase { + type: 'CallExpression'; + callee: LeftHandSideExpression; + arguments: Expression[]; + typeParameters?: TSTypeParameterInstantiation; +} + +export interface CatchClause extends NodeBase { + type: 'CatchClause'; + param: BindingName | null; + body: BlockStatement; +} + +export interface ClassBody extends NodeBase { + type: 'ClassBody'; + body: ClassElement[]; +} + +export interface ClassDeclaration extends ClassDeclarationBase { + type: 'ClassDeclaration'; +} + +export interface ClassExpression extends ClassDeclarationBase { + type: 'ClassExpression'; +} + +export interface ClassProperty extends ClassPropertyBase { + type: 'ClassProperty'; +} + +export interface Comment extends NodeBase { + type: 'Line' | 'Block'; + value: string; +} + +export interface ConditionalExpression extends NodeBase { + type: 'ConditionalExpression'; + test: Expression; + consequent: Expression; + alternate: Expression; +} + +export interface ContinueStatement extends NodeBase { + type: 'ContinueStatement'; + label: Identifier | null; +} + +export interface DebuggerStatement extends NodeBase { + type: 'DebuggerStatement'; +} + +export interface Decorator extends NodeBase { + type: 'Decorator'; + expression: LeftHandSideExpression; +} + +export interface DoWhileStatement extends NodeBase { + type: 'DoWhileStatement'; + test: Expression; + body: Statement; +} + +export interface EmptyStatement extends NodeBase { + type: 'EmptyStatement'; +} + +export interface ExportAllDeclaration extends NodeBase { + type: 'ExportAllDeclaration'; + source: Expression | null; +} + +export interface ExportDefaultDeclaration extends NodeBase { + type: 'ExportDefaultDeclaration'; + declaration: ExportDeclaration; +} + +export interface ExportNamedDeclaration extends NodeBase { + type: 'ExportNamedDeclaration'; + declaration: ExportDeclaration | null; + specifiers: ExportSpecifier[]; + source: Expression | null; +} + +export interface ExportSpecifier extends NodeBase { + type: 'ExportSpecifier'; + local: Identifier; + exported: Identifier; +} + +export interface ExpressionStatement extends NodeBase { + type: 'ExpressionStatement'; + expression: Expression; +} + +export interface ForInStatement extends NodeBase { + type: 'ForInStatement'; + left: ForInitialiser; + right: Expression; + body: Statement; +} + +export interface ForOfStatement extends NodeBase { + type: 'ForOfStatement'; + left: ForInitialiser; + right: Expression; + body: Statement; + await: boolean; +} + +export interface ForStatement extends NodeBase { + type: 'ForStatement'; + init: Expression | ForInitialiser | null; + test: Expression | null; + update: Expression | null; + body: Statement; +} + +export interface FunctionDeclaration extends FunctionDeclarationBase { + type: 'FunctionDeclaration'; +} + +export interface FunctionExpression extends FunctionDeclarationBase { + type: 'FunctionExpression'; +} + +export interface Identifier extends NodeBase { + type: 'Identifier'; + name: string; + typeAnnotation?: TSTypeAnnotation; + optional?: boolean; +} + +export interface IfStatement extends NodeBase { + type: 'IfStatement'; + test: Expression; + consequent: Statement; + alternate: Statement | null; +} + +export interface Import extends NodeBase { + type: 'Import'; +} + +export interface ImportDeclaration extends NodeBase { + type: 'ImportDeclaration'; + source: Expression; + specifiers: ImportClause[]; +} + +export interface ImportDefaultSpecifier extends NodeBase { + type: 'ImportDefaultSpecifier'; + local: Identifier; +} + +export interface ImportNamespaceSpecifier extends NodeBase { + type: 'ImportNamespaceSpecifier'; + local: Identifier; +} + +export interface ImportSpecifier extends NodeBase { + type: 'ImportSpecifier'; + local: Identifier; + imported: Identifier; +} + +export interface JSXAttribute extends NodeBase { + type: 'JSXAttribute'; + name: JSXIdentifier; + value: Literal | JSXExpression | null; +} + +export interface JSXClosingElement extends NodeBase { + type: 'JSXClosingElement'; + name: JSXTagNameExpression; +} + +export interface JSXClosingFragment extends NodeBase { + type: 'JSXClosingFragment'; +} + +export interface JSXElement extends NodeBase { + type: 'JSXElement'; + openingElement: JSXOpeningElement; + closingElement: JSXClosingElement | null; + children: JSXChild[]; +} + +export interface JSXEmptyExpression extends NodeBase { + type: 'JSXEmptyExpression'; +} + +export interface JSXExpressionContainer extends NodeBase { + type: 'JSXExpressionContainer'; + expression: Expression | JSXEmptyExpression; +} + +export interface JSXFragment extends NodeBase { + type: 'JSXFragment'; + openingFragment: JSXOpeningFragment; + closingFragment: JSXClosingFragment; + children: JSXChild[]; +} + +export interface JSXIdentifier extends NodeBase { + type: 'JSXIdentifier'; + name: string; +} + +export interface JSXMemberExpression extends NodeBase { + type: 'JSXMemberExpression'; + name: string; +} + +export interface JSXOpeningElement extends NodeBase { + type: 'JSXOpeningElement'; + typeParameters?: TSTypeParameterInstantiation; + selfClosing: boolean; + name: JSXTagNameExpression; + attributes: JSXAttribute[]; +} + +export interface JSXOpeningFragment extends NodeBase { + type: 'JSXOpeningFragment'; +} + +export interface JSXSpreadAttribute extends NodeBase { + type: 'JSXSpreadAttribute'; + argument: Expression; +} + +export interface JSXSpreadChild extends NodeBase { + type: 'JSXSpreadChild'; + expression: Expression | JSXEmptyExpression; +} + +export interface JSXText extends NodeBase { + type: 'JSXText'; + value: string; + raw: string; +} + +export interface LabeledStatement extends NodeBase { + type: 'LabeledStatement'; + label: Identifier; + body: Statement; +} + +export interface Literal extends LiteralBase { + type: 'Literal'; +} + +export interface LogicalExpression extends BinaryExpressionBase { + type: 'LogicalExpression'; +} + +export interface MemberExpression extends NodeBase { + type: 'MemberExpression'; + object: LeftHandSideExpression; + property: Expression | Identifier; + computed?: boolean; +} + +export interface MetaProperty extends NodeBase { + type: 'MetaProperty'; + meta: Identifier; + property: Identifier; +} + +export interface MethodDefinition extends MethodDefinitionBase { + type: 'MethodDefinition'; +} + +export interface NewExpression extends NodeBase { + type: 'NewExpression'; + callee: LeftHandSideExpression; + arguments: Expression[]; + typeParameters?: TSTypeParameterInstantiation; +} + +export interface ObjectExpression extends NodeBase { + type: 'ObjectExpression'; + properties: ObjectLiteralElementLike[]; +} + +export interface ObjectPattern extends NodeBase { + type: 'ObjectPattern'; + properties: ObjectLiteralElementLike[]; + typeAnnotation?: TSTypeAnnotation; + optional?: boolean; +} + +export interface Program extends NodeBase { + type: 'Program'; + body: Statement[]; + sourceType: 'module' | 'script'; +} + +export interface Property extends NodeBase { + type: 'Property'; + key: PropertyName; + value: Expression | AssignmentPattern | BindingName; // TODO + computed: boolean; + method: boolean; + shorthand: boolean; + kind: 'init'; +} + +export interface RestElement extends NodeBase { + type: 'RestElement'; + argument: BindingName | Expression | PropertyName; + typeAnnotation?: TSTypeAnnotation; + optional?: boolean; +} + +export interface ReturnStatement extends NodeBase { + type: 'ReturnStatement'; + argument: Expression | null; +} + +export interface SequenceExpression extends NodeBase { + type: 'SequenceExpression'; + expressions: Expression[]; +} + +export interface SpreadElement extends NodeBase { + type: 'SpreadElement'; + argument: BindingName | Expression | PropertyName; +} + +export interface Super extends NodeBase { + type: 'Super'; +} + +export interface SwitchCase extends NodeBase { + type: 'SwitchCase'; + test: Expression; + consequent: Statement[]; +} + +export interface SwitchStatement extends NodeBase { + type: 'SwitchStatement'; + discriminant: Expression; + cases: SwitchCase[]; +} + +export interface TaggedTemplateExpression extends NodeBase { + type: 'TaggedTemplateExpression'; + typeParameters: TSTypeParameterInstantiation; + tag: LeftHandSideExpression; + quasi: TemplateLiteral; +} + +export interface TemplateElement extends NodeBase { + type: 'TemplateElement'; + value: { + raw: string; + cooked: string; + }; + tail: boolean; +} + +export interface TemplateLiteral extends NodeBase { + type: 'TemplateLiteral'; + quasis: TemplateElement[]; + expressions: Expression[]; +} + +export interface ThisExpression extends NodeBase { + type: 'ThisExpression'; +} + +export interface ThrowStatement extends NodeBase { + type: 'ThrowStatement'; + argument: Statement | null; +} + +export interface TryStatement extends NodeBase { + type: 'TryStatement'; + block: BlockStatement; + handler: CatchClause | null; + finalizer: BlockStatement; +} + +export interface TSAbstractClassProperty extends ClassPropertyBase { + type: 'TSAbstractClassProperty'; +} + +export interface TSAbstractKeyword extends NodeBase { + type: 'TSAbstractKeyword'; +} + +export interface TSAbstractMethodDefinition extends MethodDefinitionBase { + type: 'TSAbstractMethodDefinition'; +} + +export interface TSAnyKeyword extends NodeBase { + type: 'TSAnyKeyword'; +} + +export interface TSArrayType extends NodeBase { + type: 'TSArrayType'; + elementType: TypeNode; +} + +export interface TSAsExpression extends NodeBase { + type: 'TSAsExpression'; + expression: Expression; + typeAnnotation: TypeNode; +} + +export interface TSAsyncKeyword extends NodeBase { + type: 'TSAsyncKeyword'; +} + +export interface TSBigIntKeyword extends NodeBase { + type: 'TSBigIntKeyword'; +} + +export interface TSBooleanKeyword extends NodeBase { + type: 'TSBooleanKeyword'; +} + +export interface TSCallSignatureDeclaration extends FunctionSignatureBase { + type: 'TSCallSignatureDeclaration'; +} + +export interface TSClassImplements extends TSHeritageBase { + type: 'TSClassImplements'; +} + +export interface TSConditionalType extends NodeBase { + type: 'TSConditionalType'; + checkType: TypeNode; + extendsType: TypeNode; + trueType: TypeNode; + falseType: TypeNode; +} + +export interface TSConstKeyword extends NodeBase { + type: 'TSConstKeyword'; +} + +export interface TSConstructorType extends FunctionSignatureBase { + type: 'TSConstructorType'; +} + +export interface TSConstructSignatureDeclaration extends FunctionSignatureBase { + type: 'TSConstructSignatureDeclaration'; +} + +export interface TSDeclareFunction extends NodeBase { + type: 'TSDeclareFunction'; + id: Identifier | null; + generator: boolean; + expression: boolean; + async: boolean; + params: Parameter[]; + body?: BlockStatement | null; + returnType?: TSTypeAnnotation; + declare: boolean; + typeParameters?: TSTypeParameterDeclaration; +} + +export interface TSDeclareKeyword extends NodeBase { + type: 'TSDeclareKeyword'; +} + +export interface TSDefaultKeyword extends NodeBase { + type: 'TSDefaultKeyword'; +} + +export interface TSEnumDeclaration extends NodeBase { + type: 'TSEnumDeclaration'; + id: Identifier; + members: TSEnumMember[]; + const?: boolean; + declare?: boolean; + modifiers?: Modifier[]; + decorators?: Decorator[]; +} + +export interface TSEnumMember extends NodeBase { + type: 'TSEnumMember'; + id: PropertyName; + initializer?: Expression; +} + +export interface TSExportAssignment extends NodeBase { + type: 'TSExportAssignment'; + expression: Expression; +} + +export interface TSExportKeyword extends NodeBase { + type: 'TSExportKeyword'; +} + +export interface TSExternalModuleReference extends NodeBase { + type: 'TSExternalModuleReference'; + expression: Expression; +} + +export interface TSFunctionType extends FunctionSignatureBase { + type: 'TSFunctionType'; +} + +export interface TSImportEqualsDeclaration extends NodeBase { + type: 'TSImportEqualsDeclaration'; + id: Identifier; + moduleReference: EntityName | TSExternalModuleReference; + isExport: boolean; +} + +export interface TSImportType extends NodeBase { + type: 'TSImportType'; + isTypeOf: boolean; + parameter: TypeNode; + qualifier: EntityName | null; + typeParameters: TSTypeParameterInstantiation | null; +} + +export interface TSIndexedAccessType extends NodeBase { + type: 'TSIndexedAccessType'; + objectType: TypeNode; + indexType: TypeNode; +} + +export interface TSIndexSignature extends NodeBase { + type: 'TSIndexSignature'; + parameters: Parameter[]; + typeAnnotation?: TSTypeAnnotation; + readonly?: boolean; + accessibility?: Accessibility; + export?: boolean; + static?: boolean; +} + +export interface TSInferType extends NodeBase { + type: 'TSInferType'; + typeParameter: TSTypeParameterDeclaration; +} + +export interface TSInterfaceDeclaration extends NodeBase { + type: 'TSInterfaceDeclaration'; + body: TSInterfaceBody; + id: Identifier; + typeParameters?: TSTypeParameterDeclaration; + extends?: ExpressionWithTypeArguments[]; + implements?: ExpressionWithTypeArguments[]; + decorators?: Decorator[]; + abstract?: boolean; + declare?: boolean; +} + +export interface TSInterfaceBody extends NodeBase { + type: 'TSInterfaceBody'; + body: TypeElement[]; +} + +export interface TSInterfaceHeritage extends TSHeritageBase { + type: 'TSInterfaceHeritage'; +} + +export interface TSIntersectionType extends NodeBase { + type: 'TSIntersectionType'; + types: TypeNode[]; +} + +export interface TSLiteralType extends NodeBase { + type: 'TSLiteralType'; + literal: LiteralExpression | UnaryExpression | UpdateExpression; +} + +export interface TSMappedType extends NodeBase { + type: 'TSMappedType'; + typeParameter: TSTypeParameterDeclaration; + readonly?: boolean | '-' | '+'; + optional?: boolean | '-' | '+'; + typeAnnotation?: TypeNode; +} + +export interface TSMethodSignature extends NodeBase { + type: 'TSMethodSignature'; + computed: boolean; + key: PropertyName; + params: Parameter[]; + optional?: boolean; + returnType?: TypeNode; + readonly?: boolean; + typeParameters?: TSTypeParameterDeclaration; + accessibility?: Accessibility; + export?: boolean; + static?: boolean; +} + +export interface TSModuleBlock extends NodeBase { + type: 'TSModuleBlock'; + body: Statement[]; +} + +export interface TSModuleDeclaration extends NodeBase { + type: 'TSModuleDeclaration'; + id: Identifier | Literal; + body?: TSModuleBlock | Identifier; + global?: boolean; +} + +export interface TSNamespaceExportDeclaration extends NodeBase { + type: 'TSNamespaceExportDeclaration'; + id: Identifier; +} + +export interface TSNeverKeyword extends NodeBase { + type: 'TSNeverKeyword'; +} + +export interface TSNonNullExpression extends NodeBase { + type: 'TSNonNullExpression'; + expression: Expression; +} + +export interface TSNullKeyword extends NodeBase { + type: 'TSNullKeyword'; +} + +export interface TSNumberKeyword extends NodeBase { + type: 'TSNumberKeyword'; +} + +export interface TSObjectKeyword extends NodeBase { + type: 'TSObjectKeyword'; +} + +export interface TSOptionalType extends NodeBase { + type: 'TSOptionalType'; + typeAnnotation: TypeNode; +} + +export interface TSParameterProperty extends NodeBase { + type: 'TSParameterProperty'; + accessibility?: Accessibility; + readonly?: boolean; + static?: boolean; + export?: boolean; + parameter: AssignmentPattern | BindingName | RestElement; +} + +export interface TSParenthesizedType extends NodeBase { + type: 'TSParenthesizedType'; + typeAnnotation: TypeNode; +} + +export interface TSPropertySignature extends NodeBase { + type: 'TSPropertySignature'; + optional?: boolean; + computed: boolean; + key: PropertyName; + typeAnnotation?: TSTypeAnnotation; + initializer?: Expression; + readonly?: boolean; + static?: boolean; + export?: boolean; + accessability?: Accessibility; +} + +export interface TSPublicKeyword extends NodeBase { + type: 'TSPublicKeyword'; +} + +export interface TSPrivateKeyword extends NodeBase { + type: 'TSPrivateKeyword'; +} + +export interface TSProtectedKeyword extends NodeBase { + type: 'TSProtectedKeyword'; +} + +export interface TSQualifiedName extends NodeBase { + type: 'TSQualifiedName'; + left: EntityName; + right: Identifier; +} + +export interface TSReadonlyKeyword extends NodeBase { + type: 'TSReadonlyKeyword'; +} + +export interface TSRestType extends NodeBase { + type: 'TSRestType'; + typeAnnotation: TypeNode; +} + +export interface TSStaticKeyword extends NodeBase { + type: 'TSStaticKeyword'; +} + +export interface TSStringKeyword extends NodeBase { + type: 'TSStringKeyword'; +} + +export interface TSSymbolKeyword extends NodeBase { + type: 'TSSymbolKeyword'; +} + +export interface TSThisType extends NodeBase { + type: 'TSThisType'; +} + +export interface TSTupleType extends NodeBase { + type: 'TSTupleType'; + elementTypes: TypeNode[]; +} + +export interface TSTypeAliasDeclaration extends NodeBase { + type: 'TSTypeAliasDeclaration'; + id: Identifier; + typeAnnotation: TypeNode; + declare?: boolean; + typeParameters?: TSTypeParameterDeclaration; +} + +export interface TSTypeAnnotation extends NodeBase { + type: 'TSTypeAnnotation'; + typeAnnotation: TypeNode; +} + +export interface TSTypeAssertion extends NodeBase { + type: 'TSTypeAssertion'; + typeAnnotation: TypeNode; + expression: UnaryExpression; +} + +export interface TSTypeLiteral extends NodeBase { + type: 'TSTypeLiteral'; + members: TypeElement[]; +} + +export interface TSTypeOperator extends NodeBase { + type: 'TSTypeOperator'; + operator: 'keyof' | 'unique'; + typeAnnotation?: TSTypeAnnotation; +} + +export interface TSTypeParameter extends NodeBase { + type: 'TSTypeParameter'; + name: Identifier; + constraint?: TypeNode; + default?: TypeNode; +} + +export interface TSTypeParameterDeclaration extends NodeBase { + type: 'TSTypeParameterDeclaration'; + params: TSTypeParameter[]; +} + +export interface TSTypeParameterInstantiation extends NodeBase { + type: 'TSTypeParameterInstantiation'; + params: TypeNode[]; +} + +export interface TSTypePredicate extends NodeBase { + type: 'TSTypePredicate'; + parameterName: Identifier | TSThisType; + typeAnnotation: TypeNode; +} + +export interface TSTypeQuery extends NodeBase { + type: 'TSTypeQuery'; + exprName: EntityName; +} + +export interface TSTypeReference extends NodeBase { + type: 'TSTypeReference'; + typeName: EntityName; + typeParameters?: TSTypeParameterInstantiation; +} + +export interface TSUndefinedKeyword extends NodeBase { + type: 'TSUndefinedKeyword'; +} + +export interface TSUnionType extends NodeBase { + type: 'TSUnionType'; + types: TypeNode[]; +} + +export interface TSUnknownKeyword extends NodeBase { + type: 'TSUnknownKeyword'; +} + +export interface TSVoidKeyword extends NodeBase { + type: 'TSVoidKeyword'; +} + +export interface UpdateExpression extends UnaryExpressionBase { + type: 'UpdateExpression'; +} + +export interface UnaryExpression extends UnaryExpressionBase { + type: 'UnaryExpression'; +} + +export interface VariableDeclaration extends NodeBase { + type: 'VariableDeclaration'; + declarations: VariableDeclarator[]; + kind: 'let' | 'const' | 'var'; + declare?: boolean; +} + +export interface VariableDeclarator extends NodeBase { + type: 'VariableDeclarator'; + id: BindingName; + init: Expression | null; + definite?: boolean; +} + +export interface WhileStatement extends NodeBase { + type: 'WhileStatement'; + test: Expression; + body: Statement; +} + +export interface WithStatement extends NodeBase { + type: 'WithStatement'; + object: Expression; + body: Statement; +} + +export interface YieldExpression extends NodeBase { + type: 'YieldExpression'; + delegate: boolean; + argument?: Expression; +} From 567fbd71115e926003d3474fe519d46bfea8d61c Mon Sep 17 00:00:00 2001 From: Armano Date: Fri, 1 Feb 2019 22:56:15 +0100 Subject: [PATCH 08/18] chore: rename types and add check with AST_NODE_TYPES --- packages/typescript-estree/src/typedefs.ts | 636 +++++++++++---------- 1 file changed, 319 insertions(+), 317 deletions(-) diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index f8fac2f818ff..465d6b30ba0e 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -1,4 +1,6 @@ -export interface LineAndColumnData { +import { AST_NODE_TYPES } from './ast-node-types'; + +export interface Position { /** * Line number (1-indexed) */ @@ -8,22 +10,22 @@ export interface LineAndColumnData { */ column: number; } -export interface NodeLocation { +export interface SourceLocation { /** * The position of the first character of the parsed source region */ - start: LineAndColumnData; + start: Position; /** * The position of the first character after the parsed source region */ - end: LineAndColumnData; + end: Position; } -interface NodeBase { +interface BaseNode { /** * The source location information of the node. */ - loc: NodeLocation; + loc: SourceLocation; /** * An array of two numbers. * Both numbers are a 0-based index which is the position in the array of source code characters. @@ -131,12 +133,12 @@ export type Node = | TSCallSignatureDeclaration | TSClassImplements | TSConditionalType - | TSConstKeyword + // | TSConstKeyword | TSConstructorType | TSConstructSignatureDeclaration | TSDeclareFunction | TSDeclareKeyword - | TSDefaultKeyword + // | TSDefaultKeyword | TSEnumDeclaration | TSEnumMember | TSExportAssignment @@ -293,9 +295,9 @@ export type LiteralExpression = BigIntLiteral | Literal | TemplateLiteral; export type Modifier = | TSAbstractKeyword | TSAsyncKeyword - | TSConstKeyword + // | TSConstKeyword | TSDeclareKeyword - | TSDefaultKeyword + // | TSDefaultKeyword | TSExportKeyword | TSPublicKeyword | TSPrivateKeyword @@ -403,13 +405,13 @@ export type TSUnaryExpression = // **Ensure you sort the interfaces alphabetically** /////////////// -interface BinaryExpressionBase extends NodeBase { +interface BinaryExpressionBase extends BaseNode { operator: string; left: Expression; right: Expression; } -interface ClassDeclarationBase extends NodeBase { +interface ClassDeclarationBase extends BaseNode { typeParameters?: TSTypeParameterDeclaration; superTypeParameters?: TSTypeParameterInstantiation; id?: Identifier; @@ -421,7 +423,7 @@ interface ClassDeclarationBase extends NodeBase { decorators?: Decorator[]; } -interface ClassPropertyBase extends NodeBase { +interface ClassPropertyBase extends BaseNode { key: PropertyName; value: Expression; computed: boolean; @@ -434,7 +436,7 @@ interface ClassPropertyBase extends NodeBase { typeAnnotation?: TSTypeAnnotation; } -interface FunctionDeclarationBase extends NodeBase { +interface FunctionDeclarationBase extends BaseNode { id: Identifier | null; generator: boolean; expression: boolean; @@ -445,13 +447,13 @@ interface FunctionDeclarationBase extends NodeBase { typeParameters?: TSTypeParameterDeclaration; } -interface FunctionSignatureBase extends NodeBase { +interface FunctionSignatureBase extends BaseNode { params: Parameter[]; returnType?: TSTypeAnnotation; typeParameters?: TSTypeParameterDeclaration; } -interface LiteralBase extends NodeBase { +interface LiteralBase extends BaseNode { raw: boolean | number | RegExp | string | null; value: string; regex?: { @@ -460,7 +462,7 @@ interface LiteralBase extends NodeBase { }; } -interface MethodDefinitionBase extends NodeBase { +interface MethodDefinitionBase extends BaseNode { key: PropertyName; value: FunctionExpression; computed: boolean; @@ -471,12 +473,12 @@ interface MethodDefinitionBase extends NodeBase { typeParameters?: TSTypeParameterDeclaration; } -interface TSHeritageBase extends NodeBase { +interface TSHeritageBase extends BaseNode { expression: Expression; typeParameters?: TSTypeParameterDeclaration; } -interface UnaryExpressionBase extends NodeBase { +interface UnaryExpressionBase extends BaseNode { operator: string; prefix: boolean; argument: LeftHandSideExpression | Literal | UnaryExpression; @@ -487,20 +489,20 @@ interface UnaryExpressionBase extends NodeBase { // **Ensure you sort the interfaces alphabetically** /////////////// -export interface ArrayExpression extends NodeBase { - type: 'ArrayExpression'; +export interface ArrayExpression extends BaseNode { + type: AST_NODE_TYPES.ArrayExpression; elements: Expression[]; } -export interface ArrayPattern extends NodeBase { - type: 'ArrayPattern'; +export interface ArrayPattern extends BaseNode { + type: AST_NODE_TYPES.ArrayPattern; elements: Expression[]; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -export interface ArrowFunctionExpression extends NodeBase { - type: 'ArrowFunctionExpression'; +export interface ArrowFunctionExpression extends BaseNode { + type: AST_NODE_TYPES.ArrowFunctionExpression; generator: boolean; id: null; params: Parameter[]; @@ -512,151 +514,151 @@ export interface ArrowFunctionExpression extends NodeBase { } export interface AssignmentExpression extends BinaryExpressionBase { - type: 'AssignmentExpression'; + type: AST_NODE_TYPES.AssignmentExpression; } -export interface AssignmentPattern extends NodeBase { - type: 'AssignmentPattern'; +export interface AssignmentPattern extends BaseNode { + type: AST_NODE_TYPES.AssignmentPattern; left: BindingName; right?: Expression; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -export interface AwaitExpression extends NodeBase { - type: 'AwaitExpression'; +export interface AwaitExpression extends BaseNode { + type: AST_NODE_TYPES.AwaitExpression; argument: TSUnaryExpression; } export interface BigIntLiteral extends LiteralBase { - type: 'BigIntLiteral'; + type: AST_NODE_TYPES.BigIntLiteral; } export interface BinaryExpression extends BinaryExpressionBase { - type: 'BinaryExpression'; + type: AST_NODE_TYPES.BinaryExpression; } -export interface BlockStatement extends NodeBase { - type: 'BlockStatement'; +export interface BlockStatement extends BaseNode { + type: AST_NODE_TYPES.BlockStatement; body: Statement[]; } -export interface BreakStatement extends NodeBase { - type: 'BreakStatement'; +export interface BreakStatement extends BaseNode { + type: AST_NODE_TYPES.BreakStatement; label: Identifier | null; } -export interface CallExpression extends NodeBase { - type: 'CallExpression'; +export interface CallExpression extends BaseNode { + type: AST_NODE_TYPES.CallExpression; callee: LeftHandSideExpression; arguments: Expression[]; typeParameters?: TSTypeParameterInstantiation; } -export interface CatchClause extends NodeBase { - type: 'CatchClause'; +export interface CatchClause extends BaseNode { + type: AST_NODE_TYPES.CatchClause; param: BindingName | null; body: BlockStatement; } -export interface ClassBody extends NodeBase { - type: 'ClassBody'; +export interface ClassBody extends BaseNode { + type: AST_NODE_TYPES.ClassBody; body: ClassElement[]; } export interface ClassDeclaration extends ClassDeclarationBase { - type: 'ClassDeclaration'; + type: AST_NODE_TYPES.ClassDeclaration; } export interface ClassExpression extends ClassDeclarationBase { - type: 'ClassExpression'; + type: AST_NODE_TYPES.ClassExpression; } export interface ClassProperty extends ClassPropertyBase { - type: 'ClassProperty'; + type: AST_NODE_TYPES.ClassProperty; } -export interface Comment extends NodeBase { +export interface Comment extends BaseNode { type: 'Line' | 'Block'; value: string; } -export interface ConditionalExpression extends NodeBase { - type: 'ConditionalExpression'; +export interface ConditionalExpression extends BaseNode { + type: AST_NODE_TYPES.ConditionalExpression; test: Expression; consequent: Expression; alternate: Expression; } -export interface ContinueStatement extends NodeBase { - type: 'ContinueStatement'; +export interface ContinueStatement extends BaseNode { + type: AST_NODE_TYPES.ContinueStatement; label: Identifier | null; } -export interface DebuggerStatement extends NodeBase { - type: 'DebuggerStatement'; +export interface DebuggerStatement extends BaseNode { + type: AST_NODE_TYPES.DebuggerStatement; } -export interface Decorator extends NodeBase { - type: 'Decorator'; +export interface Decorator extends BaseNode { + type: AST_NODE_TYPES.Decorator; expression: LeftHandSideExpression; } -export interface DoWhileStatement extends NodeBase { - type: 'DoWhileStatement'; +export interface DoWhileStatement extends BaseNode { + type: AST_NODE_TYPES.DoWhileStatement; test: Expression; body: Statement; } -export interface EmptyStatement extends NodeBase { - type: 'EmptyStatement'; +export interface EmptyStatement extends BaseNode { + type: AST_NODE_TYPES.EmptyStatement; } -export interface ExportAllDeclaration extends NodeBase { - type: 'ExportAllDeclaration'; +export interface ExportAllDeclaration extends BaseNode { + type: AST_NODE_TYPES.ExportAllDeclaration; source: Expression | null; } -export interface ExportDefaultDeclaration extends NodeBase { - type: 'ExportDefaultDeclaration'; +export interface ExportDefaultDeclaration extends BaseNode { + type: AST_NODE_TYPES.ExportDefaultDeclaration; declaration: ExportDeclaration; } -export interface ExportNamedDeclaration extends NodeBase { - type: 'ExportNamedDeclaration'; +export interface ExportNamedDeclaration extends BaseNode { + type: AST_NODE_TYPES.ExportNamedDeclaration; declaration: ExportDeclaration | null; specifiers: ExportSpecifier[]; source: Expression | null; } -export interface ExportSpecifier extends NodeBase { - type: 'ExportSpecifier'; +export interface ExportSpecifier extends BaseNode { + type: AST_NODE_TYPES.ExportSpecifier; local: Identifier; exported: Identifier; } -export interface ExpressionStatement extends NodeBase { - type: 'ExpressionStatement'; +export interface ExpressionStatement extends BaseNode { + type: AST_NODE_TYPES.ExpressionStatement; expression: Expression; } -export interface ForInStatement extends NodeBase { - type: 'ForInStatement'; +export interface ForInStatement extends BaseNode { + type: AST_NODE_TYPES.ForInStatement; left: ForInitialiser; right: Expression; body: Statement; } -export interface ForOfStatement extends NodeBase { - type: 'ForOfStatement'; +export interface ForOfStatement extends BaseNode { + type: AST_NODE_TYPES.ForOfStatement; left: ForInitialiser; right: Expression; body: Statement; await: boolean; } -export interface ForStatement extends NodeBase { - type: 'ForStatement'; +export interface ForStatement extends BaseNode { + type: AST_NODE_TYPES.ForStatement; init: Expression | ForInitialiser | null; test: Expression | null; update: Expression | null; @@ -664,187 +666,187 @@ export interface ForStatement extends NodeBase { } export interface FunctionDeclaration extends FunctionDeclarationBase { - type: 'FunctionDeclaration'; + type: AST_NODE_TYPES.FunctionDeclaration; } export interface FunctionExpression extends FunctionDeclarationBase { - type: 'FunctionExpression'; + type: AST_NODE_TYPES.FunctionExpression; } -export interface Identifier extends NodeBase { - type: 'Identifier'; +export interface Identifier extends BaseNode { + type: AST_NODE_TYPES.Identifier; name: string; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -export interface IfStatement extends NodeBase { - type: 'IfStatement'; +export interface IfStatement extends BaseNode { + type: AST_NODE_TYPES.IfStatement; test: Expression; consequent: Statement; alternate: Statement | null; } -export interface Import extends NodeBase { - type: 'Import'; +export interface Import extends BaseNode { + type: AST_NODE_TYPES.Import; } -export interface ImportDeclaration extends NodeBase { - type: 'ImportDeclaration'; +export interface ImportDeclaration extends BaseNode { + type: AST_NODE_TYPES.ImportDeclaration; source: Expression; specifiers: ImportClause[]; } -export interface ImportDefaultSpecifier extends NodeBase { - type: 'ImportDefaultSpecifier'; +export interface ImportDefaultSpecifier extends BaseNode { + type: AST_NODE_TYPES.ImportDefaultSpecifier; local: Identifier; } -export interface ImportNamespaceSpecifier extends NodeBase { - type: 'ImportNamespaceSpecifier'; +export interface ImportNamespaceSpecifier extends BaseNode { + type: AST_NODE_TYPES.ImportNamespaceSpecifier; local: Identifier; } -export interface ImportSpecifier extends NodeBase { - type: 'ImportSpecifier'; +export interface ImportSpecifier extends BaseNode { + type: AST_NODE_TYPES.ImportSpecifier; local: Identifier; imported: Identifier; } -export interface JSXAttribute extends NodeBase { - type: 'JSXAttribute'; +export interface JSXAttribute extends BaseNode { + type: AST_NODE_TYPES.JSXAttribute; name: JSXIdentifier; value: Literal | JSXExpression | null; } -export interface JSXClosingElement extends NodeBase { - type: 'JSXClosingElement'; +export interface JSXClosingElement extends BaseNode { + type: AST_NODE_TYPES.JSXClosingElement; name: JSXTagNameExpression; } -export interface JSXClosingFragment extends NodeBase { - type: 'JSXClosingFragment'; +export interface JSXClosingFragment extends BaseNode { + type: AST_NODE_TYPES.JSXClosingFragment; } -export interface JSXElement extends NodeBase { - type: 'JSXElement'; +export interface JSXElement extends BaseNode { + type: AST_NODE_TYPES.JSXElement; openingElement: JSXOpeningElement; closingElement: JSXClosingElement | null; children: JSXChild[]; } -export interface JSXEmptyExpression extends NodeBase { - type: 'JSXEmptyExpression'; +export interface JSXEmptyExpression extends BaseNode { + type: AST_NODE_TYPES.JSXEmptyExpression; } -export interface JSXExpressionContainer extends NodeBase { - type: 'JSXExpressionContainer'; +export interface JSXExpressionContainer extends BaseNode { + type: AST_NODE_TYPES.JSXExpressionContainer; expression: Expression | JSXEmptyExpression; } -export interface JSXFragment extends NodeBase { - type: 'JSXFragment'; +export interface JSXFragment extends BaseNode { + type: AST_NODE_TYPES.JSXFragment; openingFragment: JSXOpeningFragment; closingFragment: JSXClosingFragment; children: JSXChild[]; } -export interface JSXIdentifier extends NodeBase { - type: 'JSXIdentifier'; +export interface JSXIdentifier extends BaseNode { + type: AST_NODE_TYPES.JSXIdentifier; name: string; } -export interface JSXMemberExpression extends NodeBase { - type: 'JSXMemberExpression'; +export interface JSXMemberExpression extends BaseNode { + type: AST_NODE_TYPES.JSXMemberExpression; name: string; } -export interface JSXOpeningElement extends NodeBase { - type: 'JSXOpeningElement'; +export interface JSXOpeningElement extends BaseNode { + type: AST_NODE_TYPES.JSXOpeningElement; typeParameters?: TSTypeParameterInstantiation; selfClosing: boolean; name: JSXTagNameExpression; attributes: JSXAttribute[]; } -export interface JSXOpeningFragment extends NodeBase { - type: 'JSXOpeningFragment'; +export interface JSXOpeningFragment extends BaseNode { + type: AST_NODE_TYPES.JSXOpeningFragment; } -export interface JSXSpreadAttribute extends NodeBase { - type: 'JSXSpreadAttribute'; +export interface JSXSpreadAttribute extends BaseNode { + type: AST_NODE_TYPES.JSXSpreadAttribute; argument: Expression; } -export interface JSXSpreadChild extends NodeBase { - type: 'JSXSpreadChild'; +export interface JSXSpreadChild extends BaseNode { + type: AST_NODE_TYPES.JSXSpreadChild; expression: Expression | JSXEmptyExpression; } -export interface JSXText extends NodeBase { - type: 'JSXText'; +export interface JSXText extends BaseNode { + type: AST_NODE_TYPES.JSXText; value: string; raw: string; } -export interface LabeledStatement extends NodeBase { - type: 'LabeledStatement'; +export interface LabeledStatement extends BaseNode { + type: AST_NODE_TYPES.LabeledStatement; label: Identifier; body: Statement; } export interface Literal extends LiteralBase { - type: 'Literal'; + type: AST_NODE_TYPES.Literal; } export interface LogicalExpression extends BinaryExpressionBase { - type: 'LogicalExpression'; + type: AST_NODE_TYPES.LogicalExpression; } -export interface MemberExpression extends NodeBase { - type: 'MemberExpression'; +export interface MemberExpression extends BaseNode { + type: AST_NODE_TYPES.MemberExpression; object: LeftHandSideExpression; property: Expression | Identifier; computed?: boolean; } -export interface MetaProperty extends NodeBase { - type: 'MetaProperty'; +export interface MetaProperty extends BaseNode { + type: AST_NODE_TYPES.MetaProperty; meta: Identifier; property: Identifier; } export interface MethodDefinition extends MethodDefinitionBase { - type: 'MethodDefinition'; + type: AST_NODE_TYPES.MethodDefinition; } -export interface NewExpression extends NodeBase { - type: 'NewExpression'; +export interface NewExpression extends BaseNode { + type: AST_NODE_TYPES.NewExpression; callee: LeftHandSideExpression; arguments: Expression[]; typeParameters?: TSTypeParameterInstantiation; } -export interface ObjectExpression extends NodeBase { - type: 'ObjectExpression'; +export interface ObjectExpression extends BaseNode { + type: AST_NODE_TYPES.ObjectExpression; properties: ObjectLiteralElementLike[]; } -export interface ObjectPattern extends NodeBase { - type: 'ObjectPattern'; +export interface ObjectPattern extends BaseNode { + type: AST_NODE_TYPES.ObjectPattern; properties: ObjectLiteralElementLike[]; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -export interface Program extends NodeBase { - type: 'Program'; +export interface Program extends BaseNode { + type: AST_NODE_TYPES.Program; body: Statement[]; sourceType: 'module' | 'script'; } -export interface Property extends NodeBase { - type: 'Property'; +export interface Property extends BaseNode { + type: AST_NODE_TYPES.Property; key: PropertyName; value: Expression | AssignmentPattern | BindingName; // TODO computed: boolean; @@ -853,53 +855,53 @@ export interface Property extends NodeBase { kind: 'init'; } -export interface RestElement extends NodeBase { - type: 'RestElement'; +export interface RestElement extends BaseNode { + type: AST_NODE_TYPES.RestElement; argument: BindingName | Expression | PropertyName; typeAnnotation?: TSTypeAnnotation; optional?: boolean; } -export interface ReturnStatement extends NodeBase { - type: 'ReturnStatement'; +export interface ReturnStatement extends BaseNode { + type: AST_NODE_TYPES.ReturnStatement; argument: Expression | null; } -export interface SequenceExpression extends NodeBase { - type: 'SequenceExpression'; +export interface SequenceExpression extends BaseNode { + type: AST_NODE_TYPES.SequenceExpression; expressions: Expression[]; } -export interface SpreadElement extends NodeBase { - type: 'SpreadElement'; +export interface SpreadElement extends BaseNode { + type: AST_NODE_TYPES.SpreadElement; argument: BindingName | Expression | PropertyName; } -export interface Super extends NodeBase { - type: 'Super'; +export interface Super extends BaseNode { + type: AST_NODE_TYPES.Super; } -export interface SwitchCase extends NodeBase { - type: 'SwitchCase'; +export interface SwitchCase extends BaseNode { + type: AST_NODE_TYPES.SwitchCase; test: Expression; consequent: Statement[]; } -export interface SwitchStatement extends NodeBase { - type: 'SwitchStatement'; +export interface SwitchStatement extends BaseNode { + type: AST_NODE_TYPES.SwitchStatement; discriminant: Expression; cases: SwitchCase[]; } -export interface TaggedTemplateExpression extends NodeBase { - type: 'TaggedTemplateExpression'; +export interface TaggedTemplateExpression extends BaseNode { + type: AST_NODE_TYPES.TaggedTemplateExpression; typeParameters: TSTypeParameterInstantiation; tag: LeftHandSideExpression; quasi: TemplateLiteral; } -export interface TemplateElement extends NodeBase { - type: 'TemplateElement'; +export interface TemplateElement extends BaseNode { + type: AST_NODE_TYPES.TemplateElement; value: { raw: string; cooked: string; @@ -907,97 +909,97 @@ export interface TemplateElement extends NodeBase { tail: boolean; } -export interface TemplateLiteral extends NodeBase { - type: 'TemplateLiteral'; +export interface TemplateLiteral extends BaseNode { + type: AST_NODE_TYPES.TemplateLiteral; quasis: TemplateElement[]; expressions: Expression[]; } -export interface ThisExpression extends NodeBase { - type: 'ThisExpression'; +export interface ThisExpression extends BaseNode { + type: AST_NODE_TYPES.ThisExpression; } -export interface ThrowStatement extends NodeBase { - type: 'ThrowStatement'; +export interface ThrowStatement extends BaseNode { + type: AST_NODE_TYPES.ThrowStatement; argument: Statement | null; } -export interface TryStatement extends NodeBase { - type: 'TryStatement'; +export interface TryStatement extends BaseNode { + type: AST_NODE_TYPES.TryStatement; block: BlockStatement; handler: CatchClause | null; finalizer: BlockStatement; } export interface TSAbstractClassProperty extends ClassPropertyBase { - type: 'TSAbstractClassProperty'; + type: AST_NODE_TYPES.TSAbstractClassProperty; } -export interface TSAbstractKeyword extends NodeBase { - type: 'TSAbstractKeyword'; +export interface TSAbstractKeyword extends BaseNode { + type: AST_NODE_TYPES.TSAbstractKeyword; } export interface TSAbstractMethodDefinition extends MethodDefinitionBase { - type: 'TSAbstractMethodDefinition'; + type: AST_NODE_TYPES.TSAbstractMethodDefinition; } -export interface TSAnyKeyword extends NodeBase { - type: 'TSAnyKeyword'; +export interface TSAnyKeyword extends BaseNode { + type: AST_NODE_TYPES.TSAnyKeyword; } -export interface TSArrayType extends NodeBase { - type: 'TSArrayType'; +export interface TSArrayType extends BaseNode { + type: AST_NODE_TYPES.TSArrayType; elementType: TypeNode; } -export interface TSAsExpression extends NodeBase { - type: 'TSAsExpression'; +export interface TSAsExpression extends BaseNode { + type: AST_NODE_TYPES.TSAsExpression; expression: Expression; typeAnnotation: TypeNode; } -export interface TSAsyncKeyword extends NodeBase { - type: 'TSAsyncKeyword'; +export interface TSAsyncKeyword extends BaseNode { + type: AST_NODE_TYPES.TSAsyncKeyword; } -export interface TSBigIntKeyword extends NodeBase { - type: 'TSBigIntKeyword'; +export interface TSBigIntKeyword extends BaseNode { + type: AST_NODE_TYPES.TSBigIntKeyword; } -export interface TSBooleanKeyword extends NodeBase { - type: 'TSBooleanKeyword'; +export interface TSBooleanKeyword extends BaseNode { + type: AST_NODE_TYPES.TSBooleanKeyword; } export interface TSCallSignatureDeclaration extends FunctionSignatureBase { - type: 'TSCallSignatureDeclaration'; + type: AST_NODE_TYPES.TSCallSignatureDeclaration; } export interface TSClassImplements extends TSHeritageBase { - type: 'TSClassImplements'; + type: AST_NODE_TYPES.TSClassImplements; } -export interface TSConditionalType extends NodeBase { - type: 'TSConditionalType'; +export interface TSConditionalType extends BaseNode { + type: AST_NODE_TYPES.TSConditionalType; checkType: TypeNode; extendsType: TypeNode; trueType: TypeNode; falseType: TypeNode; } -export interface TSConstKeyword extends NodeBase { - type: 'TSConstKeyword'; -} +// export interface TSConstKeyword extends BaseNode { +// type: AST_NODE_TYPES.TSConstKeyword; +// } export interface TSConstructorType extends FunctionSignatureBase { - type: 'TSConstructorType'; + type: AST_NODE_TYPES.TSConstructorType; } export interface TSConstructSignatureDeclaration extends FunctionSignatureBase { - type: 'TSConstructSignatureDeclaration'; + type: AST_NODE_TYPES.TSConstructSignatureDeclaration; } -export interface TSDeclareFunction extends NodeBase { - type: 'TSDeclareFunction'; +export interface TSDeclareFunction extends BaseNode { + type: AST_NODE_TYPES.TSDeclareFunction; id: Identifier | null; generator: boolean; expression: boolean; @@ -1009,16 +1011,16 @@ export interface TSDeclareFunction extends NodeBase { typeParameters?: TSTypeParameterDeclaration; } -export interface TSDeclareKeyword extends NodeBase { - type: 'TSDeclareKeyword'; +export interface TSDeclareKeyword extends BaseNode { + type: AST_NODE_TYPES.TSDeclareKeyword; } -export interface TSDefaultKeyword extends NodeBase { - type: 'TSDefaultKeyword'; -} +// export interface TSDefaultKeyword extends BaseNode { +// type: AST_NODE_TYPES.TSDefaultKeyword; +// } -export interface TSEnumDeclaration extends NodeBase { - type: 'TSEnumDeclaration'; +export interface TSEnumDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSEnumDeclaration; id: Identifier; members: TSEnumMember[]; const?: boolean; @@ -1027,53 +1029,53 @@ export interface TSEnumDeclaration extends NodeBase { decorators?: Decorator[]; } -export interface TSEnumMember extends NodeBase { - type: 'TSEnumMember'; +export interface TSEnumMember extends BaseNode { + type: AST_NODE_TYPES.TSEnumMember; id: PropertyName; initializer?: Expression; } -export interface TSExportAssignment extends NodeBase { - type: 'TSExportAssignment'; +export interface TSExportAssignment extends BaseNode { + type: AST_NODE_TYPES.TSExportAssignment; expression: Expression; } -export interface TSExportKeyword extends NodeBase { - type: 'TSExportKeyword'; +export interface TSExportKeyword extends BaseNode { + type: AST_NODE_TYPES.TSExportKeyword; } -export interface TSExternalModuleReference extends NodeBase { - type: 'TSExternalModuleReference'; +export interface TSExternalModuleReference extends BaseNode { + type: AST_NODE_TYPES.TSExternalModuleReference; expression: Expression; } export interface TSFunctionType extends FunctionSignatureBase { - type: 'TSFunctionType'; + type: AST_NODE_TYPES.TSFunctionType; } -export interface TSImportEqualsDeclaration extends NodeBase { - type: 'TSImportEqualsDeclaration'; +export interface TSImportEqualsDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSImportEqualsDeclaration; id: Identifier; moduleReference: EntityName | TSExternalModuleReference; isExport: boolean; } -export interface TSImportType extends NodeBase { - type: 'TSImportType'; +export interface TSImportType extends BaseNode { + type: AST_NODE_TYPES.TSImportType; isTypeOf: boolean; parameter: TypeNode; qualifier: EntityName | null; typeParameters: TSTypeParameterInstantiation | null; } -export interface TSIndexedAccessType extends NodeBase { - type: 'TSIndexedAccessType'; +export interface TSIndexedAccessType extends BaseNode { + type: AST_NODE_TYPES.TSIndexedAccessType; objectType: TypeNode; indexType: TypeNode; } -export interface TSIndexSignature extends NodeBase { - type: 'TSIndexSignature'; +export interface TSIndexSignature extends BaseNode { + type: AST_NODE_TYPES.TSIndexSignature; parameters: Parameter[]; typeAnnotation?: TSTypeAnnotation; readonly?: boolean; @@ -1082,13 +1084,13 @@ export interface TSIndexSignature extends NodeBase { static?: boolean; } -export interface TSInferType extends NodeBase { - type: 'TSInferType'; +export interface TSInferType extends BaseNode { + type: AST_NODE_TYPES.TSInferType; typeParameter: TSTypeParameterDeclaration; } -export interface TSInterfaceDeclaration extends NodeBase { - type: 'TSInterfaceDeclaration'; +export interface TSInterfaceDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSInterfaceDeclaration; body: TSInterfaceBody; id: Identifier; typeParameters?: TSTypeParameterDeclaration; @@ -1099,35 +1101,35 @@ export interface TSInterfaceDeclaration extends NodeBase { declare?: boolean; } -export interface TSInterfaceBody extends NodeBase { - type: 'TSInterfaceBody'; +export interface TSInterfaceBody extends BaseNode { + type: AST_NODE_TYPES.TSInterfaceBody; body: TypeElement[]; } export interface TSInterfaceHeritage extends TSHeritageBase { - type: 'TSInterfaceHeritage'; + type: AST_NODE_TYPES.TSInterfaceHeritage; } -export interface TSIntersectionType extends NodeBase { - type: 'TSIntersectionType'; +export interface TSIntersectionType extends BaseNode { + type: AST_NODE_TYPES.TSIntersectionType; types: TypeNode[]; } -export interface TSLiteralType extends NodeBase { - type: 'TSLiteralType'; +export interface TSLiteralType extends BaseNode { + type: AST_NODE_TYPES.TSLiteralType; literal: LiteralExpression | UnaryExpression | UpdateExpression; } -export interface TSMappedType extends NodeBase { - type: 'TSMappedType'; +export interface TSMappedType extends BaseNode { + type: AST_NODE_TYPES.TSMappedType; typeParameter: TSTypeParameterDeclaration; readonly?: boolean | '-' | '+'; optional?: boolean | '-' | '+'; typeAnnotation?: TypeNode; } -export interface TSMethodSignature extends NodeBase { - type: 'TSMethodSignature'; +export interface TSMethodSignature extends BaseNode { + type: AST_NODE_TYPES.TSMethodSignature; computed: boolean; key: PropertyName; params: Parameter[]; @@ -1140,51 +1142,51 @@ export interface TSMethodSignature extends NodeBase { static?: boolean; } -export interface TSModuleBlock extends NodeBase { - type: 'TSModuleBlock'; +export interface TSModuleBlock extends BaseNode { + type: AST_NODE_TYPES.TSModuleBlock; body: Statement[]; } -export interface TSModuleDeclaration extends NodeBase { - type: 'TSModuleDeclaration'; +export interface TSModuleDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSModuleDeclaration; id: Identifier | Literal; body?: TSModuleBlock | Identifier; global?: boolean; } -export interface TSNamespaceExportDeclaration extends NodeBase { - type: 'TSNamespaceExportDeclaration'; +export interface TSNamespaceExportDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSNamespaceExportDeclaration; id: Identifier; } -export interface TSNeverKeyword extends NodeBase { - type: 'TSNeverKeyword'; +export interface TSNeverKeyword extends BaseNode { + type: AST_NODE_TYPES.TSNeverKeyword; } -export interface TSNonNullExpression extends NodeBase { - type: 'TSNonNullExpression'; +export interface TSNonNullExpression extends BaseNode { + type: AST_NODE_TYPES.TSNonNullExpression; expression: Expression; } -export interface TSNullKeyword extends NodeBase { - type: 'TSNullKeyword'; +export interface TSNullKeyword extends BaseNode { + type: AST_NODE_TYPES.TSNullKeyword; } -export interface TSNumberKeyword extends NodeBase { - type: 'TSNumberKeyword'; +export interface TSNumberKeyword extends BaseNode { + type: AST_NODE_TYPES.TSNumberKeyword; } -export interface TSObjectKeyword extends NodeBase { - type: 'TSObjectKeyword'; +export interface TSObjectKeyword extends BaseNode { + type: AST_NODE_TYPES.TSObjectKeyword; } -export interface TSOptionalType extends NodeBase { - type: 'TSOptionalType'; +export interface TSOptionalType extends BaseNode { + type: AST_NODE_TYPES.TSOptionalType; typeAnnotation: TypeNode; } -export interface TSParameterProperty extends NodeBase { - type: 'TSParameterProperty'; +export interface TSParameterProperty extends BaseNode { + type: AST_NODE_TYPES.TSParameterProperty; accessibility?: Accessibility; readonly?: boolean; static?: boolean; @@ -1192,13 +1194,13 @@ export interface TSParameterProperty extends NodeBase { parameter: AssignmentPattern | BindingName | RestElement; } -export interface TSParenthesizedType extends NodeBase { - type: 'TSParenthesizedType'; +export interface TSParenthesizedType extends BaseNode { + type: AST_NODE_TYPES.TSParenthesizedType; typeAnnotation: TypeNode; } -export interface TSPropertySignature extends NodeBase { - type: 'TSPropertySignature'; +export interface TSPropertySignature extends BaseNode { + type: AST_NODE_TYPES.TSPropertySignature; optional?: boolean; computed: boolean; key: PropertyName; @@ -1210,171 +1212,171 @@ export interface TSPropertySignature extends NodeBase { accessability?: Accessibility; } -export interface TSPublicKeyword extends NodeBase { - type: 'TSPublicKeyword'; +export interface TSPublicKeyword extends BaseNode { + type: AST_NODE_TYPES.TSPublicKeyword; } -export interface TSPrivateKeyword extends NodeBase { - type: 'TSPrivateKeyword'; +export interface TSPrivateKeyword extends BaseNode { + type: AST_NODE_TYPES.TSPrivateKeyword; } -export interface TSProtectedKeyword extends NodeBase { - type: 'TSProtectedKeyword'; +export interface TSProtectedKeyword extends BaseNode { + type: AST_NODE_TYPES.TSProtectedKeyword; } -export interface TSQualifiedName extends NodeBase { - type: 'TSQualifiedName'; +export interface TSQualifiedName extends BaseNode { + type: AST_NODE_TYPES.TSQualifiedName; left: EntityName; right: Identifier; } -export interface TSReadonlyKeyword extends NodeBase { - type: 'TSReadonlyKeyword'; +export interface TSReadonlyKeyword extends BaseNode { + type: AST_NODE_TYPES.TSReadonlyKeyword; } -export interface TSRestType extends NodeBase { - type: 'TSRestType'; +export interface TSRestType extends BaseNode { + type: AST_NODE_TYPES.TSRestType; typeAnnotation: TypeNode; } -export interface TSStaticKeyword extends NodeBase { - type: 'TSStaticKeyword'; +export interface TSStaticKeyword extends BaseNode { + type: AST_NODE_TYPES.TSStaticKeyword; } -export interface TSStringKeyword extends NodeBase { - type: 'TSStringKeyword'; +export interface TSStringKeyword extends BaseNode { + type: AST_NODE_TYPES.TSStringKeyword; } -export interface TSSymbolKeyword extends NodeBase { - type: 'TSSymbolKeyword'; +export interface TSSymbolKeyword extends BaseNode { + type: AST_NODE_TYPES.TSSymbolKeyword; } -export interface TSThisType extends NodeBase { - type: 'TSThisType'; +export interface TSThisType extends BaseNode { + type: AST_NODE_TYPES.TSThisType; } -export interface TSTupleType extends NodeBase { - type: 'TSTupleType'; +export interface TSTupleType extends BaseNode { + type: AST_NODE_TYPES.TSTupleType; elementTypes: TypeNode[]; } -export interface TSTypeAliasDeclaration extends NodeBase { - type: 'TSTypeAliasDeclaration'; +export interface TSTypeAliasDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSTypeAliasDeclaration; id: Identifier; typeAnnotation: TypeNode; declare?: boolean; typeParameters?: TSTypeParameterDeclaration; } -export interface TSTypeAnnotation extends NodeBase { - type: 'TSTypeAnnotation'; +export interface TSTypeAnnotation extends BaseNode { + type: AST_NODE_TYPES.TSTypeAnnotation; typeAnnotation: TypeNode; } -export interface TSTypeAssertion extends NodeBase { - type: 'TSTypeAssertion'; +export interface TSTypeAssertion extends BaseNode { + type: AST_NODE_TYPES.TSTypeAssertion; typeAnnotation: TypeNode; expression: UnaryExpression; } -export interface TSTypeLiteral extends NodeBase { - type: 'TSTypeLiteral'; +export interface TSTypeLiteral extends BaseNode { + type: AST_NODE_TYPES.TSTypeLiteral; members: TypeElement[]; } -export interface TSTypeOperator extends NodeBase { - type: 'TSTypeOperator'; +export interface TSTypeOperator extends BaseNode { + type: AST_NODE_TYPES.TSTypeOperator; operator: 'keyof' | 'unique'; typeAnnotation?: TSTypeAnnotation; } -export interface TSTypeParameter extends NodeBase { - type: 'TSTypeParameter'; +export interface TSTypeParameter extends BaseNode { + type: AST_NODE_TYPES.TSTypeParameter; name: Identifier; constraint?: TypeNode; default?: TypeNode; } -export interface TSTypeParameterDeclaration extends NodeBase { - type: 'TSTypeParameterDeclaration'; +export interface TSTypeParameterDeclaration extends BaseNode { + type: AST_NODE_TYPES.TSTypeParameterDeclaration; params: TSTypeParameter[]; } -export interface TSTypeParameterInstantiation extends NodeBase { - type: 'TSTypeParameterInstantiation'; +export interface TSTypeParameterInstantiation extends BaseNode { + type: AST_NODE_TYPES.TSTypeParameterInstantiation; params: TypeNode[]; } -export interface TSTypePredicate extends NodeBase { - type: 'TSTypePredicate'; +export interface TSTypePredicate extends BaseNode { + type: AST_NODE_TYPES.TSTypePredicate; parameterName: Identifier | TSThisType; typeAnnotation: TypeNode; } -export interface TSTypeQuery extends NodeBase { - type: 'TSTypeQuery'; +export interface TSTypeQuery extends BaseNode { + type: AST_NODE_TYPES.TSTypeQuery; exprName: EntityName; } -export interface TSTypeReference extends NodeBase { - type: 'TSTypeReference'; +export interface TSTypeReference extends BaseNode { + type: AST_NODE_TYPES.TSTypeReference; typeName: EntityName; typeParameters?: TSTypeParameterInstantiation; } -export interface TSUndefinedKeyword extends NodeBase { - type: 'TSUndefinedKeyword'; +export interface TSUndefinedKeyword extends BaseNode { + type: AST_NODE_TYPES.TSUndefinedKeyword; } -export interface TSUnionType extends NodeBase { - type: 'TSUnionType'; +export interface TSUnionType extends BaseNode { + type: AST_NODE_TYPES.TSUnionType; types: TypeNode[]; } -export interface TSUnknownKeyword extends NodeBase { - type: 'TSUnknownKeyword'; +export interface TSUnknownKeyword extends BaseNode { + type: AST_NODE_TYPES.TSUnknownKeyword; } -export interface TSVoidKeyword extends NodeBase { - type: 'TSVoidKeyword'; +export interface TSVoidKeyword extends BaseNode { + type: AST_NODE_TYPES.TSVoidKeyword; } export interface UpdateExpression extends UnaryExpressionBase { - type: 'UpdateExpression'; + type: AST_NODE_TYPES.UpdateExpression; } export interface UnaryExpression extends UnaryExpressionBase { - type: 'UnaryExpression'; + type: AST_NODE_TYPES.UnaryExpression; } -export interface VariableDeclaration extends NodeBase { - type: 'VariableDeclaration'; +export interface VariableDeclaration extends BaseNode { + type: AST_NODE_TYPES.VariableDeclaration; declarations: VariableDeclarator[]; kind: 'let' | 'const' | 'var'; declare?: boolean; } -export interface VariableDeclarator extends NodeBase { - type: 'VariableDeclarator'; +export interface VariableDeclarator extends BaseNode { + type: AST_NODE_TYPES.VariableDeclarator; id: BindingName; init: Expression | null; definite?: boolean; } -export interface WhileStatement extends NodeBase { - type: 'WhileStatement'; +export interface WhileStatement extends BaseNode { + type: AST_NODE_TYPES.WhileStatement; test: Expression; body: Statement; } -export interface WithStatement extends NodeBase { - type: 'WithStatement'; +export interface WithStatement extends BaseNode { + type: AST_NODE_TYPES.WithStatement; object: Expression; body: Statement; } -export interface YieldExpression extends NodeBase { - type: 'YieldExpression'; +export interface YieldExpression extends BaseNode { + type: AST_NODE_TYPES.YieldExpression; delegate: boolean; argument?: Expression; } From ac1204b3881495912409a93474ed22f6f0203b1f Mon Sep 17 00:00:00 2001 From: Armano Date: Fri, 1 Feb 2019 22:58:36 +0100 Subject: [PATCH 09/18] chore: migrate types to typedefs --- packages/typescript-estree/src/ast-nodes.ts | 167 --- .../typescript-estree/src/ast-tree-nodes.ts | 1257 ----------------- .../typescript-estree/src/convert-comments.ts | 6 +- packages/typescript-estree/src/convert.ts | 81 +- packages/typescript-estree/src/node-utils.ts | 2 +- .../typescript-estree/src/parser-options.ts | 2 +- packages/typescript-estree/src/parser.ts | 2 +- packages/typescript-estree/src/typedefs.ts | 66 +- 8 files changed, 95 insertions(+), 1488 deletions(-) delete mode 100644 packages/typescript-estree/src/ast-nodes.ts delete mode 100644 packages/typescript-estree/src/ast-tree-nodes.ts diff --git a/packages/typescript-estree/src/ast-nodes.ts b/packages/typescript-estree/src/ast-nodes.ts deleted file mode 100644 index f4041055cf1c..000000000000 --- a/packages/typescript-estree/src/ast-nodes.ts +++ /dev/null @@ -1,167 +0,0 @@ -import * as es from './ast-tree-nodes'; - -export type ASTNode = - | es.ArrayExpression - | es.ArrayPattern - | es.ArrowFunctionExpression - | es.AssignmentExpression - | es.AssignmentPattern - | es.AwaitExpression - | es.BigIntLiteral - | es.BinaryExpression - | es.BlockStatement - | es.BreakStatement - | es.CallExpression - | es.CatchClause - | es.ClassBody - | es.ClassDeclaration - | es.ClassExpression - | es.ClassProperty - | es.ConditionalExpression - | es.ContinueStatement - | es.DebuggerStatement - | es.Decorator - | es.DoWhileStatement - | es.EmptyStatement - | es.ExportAllDeclaration - | es.ExportDefaultDeclaration - | es.ExportNamedDeclaration - | es.ExportSpecifier - | es.ExpressionStatement - | es.ForInStatement - | es.ForOfStatement - | es.ForStatement - | es.FunctionDeclaration - | es.FunctionExpression - | es.Identifier - | es.IfStatement - | es.Import - | es.ImportDeclaration - | es.ImportDefaultSpecifier - | es.ImportNamespaceSpecifier - | es.ImportSpecifier - | es.JSXAttribute - | es.JSXClosingElement - | es.JSXClosingFragment - | es.JSXElement - | es.JSXEmptyExpression - | es.JSXExpressionContainer - | es.JSXFragment - | es.JSXIdentifier - | es.JSXMemberExpression - // | es.JSXNamespacedName // https://github.com/Microsoft/TypeScript/issues/7411 - | es.JSXOpeningElement - | es.JSXOpeningFragment - | es.JSXSpreadAttribute - | es.JSXSpreadChild - | es.JSXText - | es.LabeledStatement - | es.Literal - | es.LogicalExpression - | es.MemberExpression - | es.MetaProperty - | es.MethodDefinition - | es.NewExpression - | es.ObjectExpression - | es.ObjectPattern - | es.Program - | es.Property - | es.RestElement - | es.ReturnStatement - | es.SequenceExpression - | es.SpreadElement - | es.Super - | es.SwitchCase - | es.SwitchStatement - | es.TaggedTemplateExpression - | es.TemplateElement - | es.TemplateLiteral - | es.ThisExpression - | es.ThrowStatement - | es.TryStatement - | es.UnaryExpression - | es.UpdateExpression - | es.VariableDeclaration - | es.VariableDeclarator - | es.WhileStatement - | es.WithStatement - | es.YieldExpression - | es.TSAbstractClassProperty - // | es.TSAbstractKeyword - | es.TSAbstractMethodDefinition - | es.TSAnyKeyword - | es.TSArrayType - | es.TSAsExpression - | es.TSAsyncKeyword - | es.TSBooleanKeyword - | es.TSBigIntKeyword - | es.TSConditionalType - | es.TSConstructorType - | es.TSCallSignatureDeclaration - | es.TSClassImplements - | es.TSConstructSignatureDeclaration - // | es.TSDeclareKeyword - | es.TSDeclareFunction - | es.TSEnumDeclaration - | es.TSEnumMember - | es.TSExportAssignment - // | es.TSExportKeyword - | es.TSExternalModuleReference - | es.TSImportType - | es.TSInferType - | es.TSLiteralType - | es.TSIndexedAccessType - | es.TSIndexSignature - | es.TSInterfaceBody - | es.TSInterfaceDeclaration - | es.TSInterfaceHeritage - | es.TSImportEqualsDeclaration - | es.TSFunctionType - | es.TSMethodSignature - | es.TSModuleBlock - | es.TSModuleDeclaration - | es.TSNamespaceExportDeclaration - | es.TSNonNullExpression - | es.TSNeverKeyword - | es.TSNullKeyword - | es.TSNumberKeyword - | es.TSMappedType - | es.TSObjectKeyword - | es.TSParameterProperty - | es.TSPrivateKeyword - | es.TSPropertySignature - | es.TSProtectedKeyword - | es.TSPublicKeyword - | es.TSQualifiedName - // | es.TSQuestionToken - // | es.TSReadonlyKeyword - | es.TSRestType - | es.TSStaticKeyword - | es.TSStringKeyword - | es.TSSymbolKeyword - | es.TSThisType - | es.TSTypeAnnotation - | es.TSTypeAliasDeclaration - | es.TSTypeAssertion - | es.TSTypeLiteral - | es.TSTypeOperator - | es.TSTypeParameter - | es.TSTypeParameterDeclaration - | es.TSTypeParameterInstantiation - | es.TSTypePredicate - | es.TSTypeReference - | es.TSTypeQuery - | es.TSIntersectionType - | es.TSTupleType - | es.TSOptionalType - | es.TSParenthesizedType - | es.TSUnionType - | es.TSUndefinedKeyword - | es.TSUnknownKeyword - | es.TSVoidKeyword - // abstract types - | es.FunctionDeclarationLike - | es.ClassPropertyLikeNode - | es.ClassLikeNode - | es.TSFunctionDeclarationLike - | es.TSExpressionWithTypeArgumentsLike; diff --git a/packages/typescript-estree/src/ast-tree-nodes.ts b/packages/typescript-estree/src/ast-tree-nodes.ts deleted file mode 100644 index 78ecc4e9d5ad..000000000000 --- a/packages/typescript-estree/src/ast-tree-nodes.ts +++ /dev/null @@ -1,1257 +0,0 @@ -/** - * @fileoverview Definition of AST structure. - * @author Armano - */ -/* eslint-disable @typescript-eslint/array-type */ - -import { AST_NODE_TYPES } from './ast-node-types'; - -export interface Position { - line: number; - column: number; -} - -export interface SourceLocation { - source?: string | null; - start: Position; - end: Position; -} - -/** - * TODO: loc and range should be optional, but its not supported yet by covert - */ -export interface BaseNode { - type: string; - loc?: SourceLocation | null; - range?: [number, number]; -} - -export interface Token extends BaseNode { - value: string; - regex?: { - pattern: string; - flags: string; - }; - object?: any; - property?: any; - name?: any; -} - -export interface Comment extends BaseNode { - type: 'Line' | 'Block'; - value: string; -} - -export interface ArrayExpression extends BaseNode { - type: AST_NODE_TYPES.ArrayExpression; - elements: Array; -} - -export interface ArrayPattern extends BaseNode { - type: AST_NODE_TYPES.ArrayPattern; - optional?: boolean; - typeAnnotation?: TSTypeAnnotation; - elements: Array< - | ArrayPattern - | AssignmentPattern - | Identifier - | MemberExpression - | ObjectPattern - | RestElement - | null - >; -} - -export interface ArrowFunctionExpression extends BaseNode { - type: AST_NODE_TYPES.ArrowFunctionExpression; - generator: boolean; - expression: boolean; - async: boolean; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array< - | ArrayPattern - | AssignmentPattern - | Identifier - | ObjectPattern - | RestElement - | TSParameterProperty - >; - id: null; - body: BlockStatement | Expressions | Identifier | JSXElement | Literals; -} - -export interface AssignmentExpression extends BaseNode { - type: AST_NODE_TYPES.AssignmentExpression; - operator: - | '%=' - | '&=' - | '**=' - | '*=' - | '+=' - | '-=' - | '/=' - | '<<=' - | '=' - | '>>=' - | '>>>=' - | '^=' - | '|='; - right: Expressions | Identifier | JSXElement | Literals; - left: ArrayPattern | Expressions | Identifier | Literal | ObjectPattern; -} - -export interface AssignmentPattern extends BaseNode { - type: AST_NODE_TYPES.AssignmentPattern; - right: Expressions | Identifier | Literals; - left: ArrayPattern | Identifier | ObjectPattern; -} - -export interface AwaitExpression extends BaseNode { - type: AST_NODE_TYPES.AwaitExpression; - argument: Expressions | Identifier | Literal; -} - -export interface BigIntLiteral extends BaseNode { - type: AST_NODE_TYPES.BigIntLiteral; - value: string; - raw: string; -} - -export interface BinaryExpression extends BaseNode { - type: AST_NODE_TYPES.BinaryExpression; - operator: - | '!=' - | '!==' - | '%' - | '&' - | '*' - | '**' - | '+' - | '-' - | '/' - | '<' - | '<<' - | '<=' - | '==' - | '===' - | '>' - | '>=' - | '>>' - | '>>>' - | '^' - | 'in' - | 'instanceof' - | '|'; - right: Expressions | Identifier | Literals; - left: Expressions | Identifier | Literals; -} - -export interface BlockStatement extends BaseNode { - type: AST_NODE_TYPES.BlockStatement; - body: Array; -} - -export interface BreakStatement extends BaseNode { - type: AST_NODE_TYPES.BreakStatement; - label: null | Identifier; -} - -export interface CallExpression extends BaseNode { - type: AST_NODE_TYPES.CallExpression; - typeParameters?: TSTypeParameterInstantiation; - callee: Expressions | Identifier | Import | Literals | Super; - arguments: Array; -} - -export interface CatchClause extends BaseNode { - type: AST_NODE_TYPES.CatchClause; - param: null | ArrayPattern | Identifier | ObjectPattern; - body: BlockStatement; -} - -export interface ClassBody extends BaseNode { - type: AST_NODE_TYPES.ClassBody; - body: Array< - | ClassProperty - | MethodDefinition - | TSAbstractClassProperty - | TSIndexSignature - >; -} - -export interface ClassLikeNode extends BaseNode { - type: AST_NODE_TYPES.ClassDeclaration | AST_NODE_TYPES.ClassExpression; - id: null | Identifier; - declare?: boolean; - abstract?: boolean; - body: ClassBody; - decorators?: Array; - superClass: null | Expressions | Identifier | Literal; - superTypeParameters?: TSTypeParameterInstantiation; - typeParameters?: TSTypeParameterDeclaration; - implements?: Array; -} - -export interface ClassDeclaration extends ClassLikeNode { - type: AST_NODE_TYPES.ClassDeclaration; -} - -export interface ClassExpression extends ClassLikeNode { - type: AST_NODE_TYPES.ClassExpression; -} - -export interface ClassPropertyLikeNode extends BaseNode { - type: AST_NODE_TYPES.ClassProperty | AST_NODE_TYPES.TSAbstractClassProperty; - static: boolean; - readonly?: boolean; - optional?: boolean; - definite?: boolean; - computed: boolean; - accessibility?: 'private' | 'protected' | 'public'; - value: null | Expressions | Identifier | Literal; - typeAnnotation?: TSTypeAnnotation; - key: Expressions | Identifier | Literals; - decorators?: Array; -} - -export interface ClassProperty extends ClassPropertyLikeNode { - type: AST_NODE_TYPES.ClassProperty; -} - -export interface TSAbstractClassProperty extends ClassPropertyLikeNode { - type: AST_NODE_TYPES.TSAbstractClassProperty; -} - -export interface ConditionalExpression extends BaseNode { - type: AST_NODE_TYPES.ConditionalExpression; - test: Expressions | Identifier | Literals; - consequent: Expressions | Identifier | JSXElement | Literals; - alternate: Expressions | Identifier | JSXElement | Literals; -} - -export interface ContinueStatement extends BaseNode { - type: AST_NODE_TYPES.ContinueStatement; - label: null | Identifier; -} - -export interface DebuggerStatement extends BaseNode { - type: AST_NODE_TYPES.DebuggerStatement; -} - -export interface Decorator extends BaseNode { - type: AST_NODE_TYPES.Decorator; - expression: Expressions | Identifier; -} - -export interface DoWhileStatement extends BaseNode { - type: AST_NODE_TYPES.DoWhileStatement; - test: Expressions | Identifier | Literal; - body: BlockStatement | VariableDeclaration; -} - -export interface EmptyStatement extends BaseNode { - type: AST_NODE_TYPES.EmptyStatement; -} - -export interface ExportAllDeclaration extends BaseNode { - type: AST_NODE_TYPES.ExportAllDeclaration; - source: Identifier | Literal; -} - -export interface ExportDefaultDeclaration extends BaseNode { - type: AST_NODE_TYPES.ExportDefaultDeclaration; - declaration: - | null - | Declarations - | Expressions - | Identifier - | JSXElement - | Literal; -} - -export interface ExportNamedDeclaration extends BaseNode { - type: AST_NODE_TYPES.ExportNamedDeclaration; - specifiers: Array; - source: null | Literal; - declaration: - | null - | Declarations - | Expressions - | Identifier - | JSXElement - | Literal; -} - -export interface ExportSpecifier extends BaseNode { - type: AST_NODE_TYPES.ExportSpecifier; - local: Identifier; - exported: Identifier; -} - -export interface ExpressionStatement extends BaseNode { - type: AST_NODE_TYPES.ExpressionStatement; - directive?: string; - expression: Expressions | Identifier | JSXElement | JSXFragment | Literals; -} - -export interface ForInStatement extends BaseNode { - type: AST_NODE_TYPES.ForInStatement; - right: Expressions | Identifier | Literal; - left: - | AssignmentPattern - | Expressions - | Identifier - | ObjectPattern - | VariableDeclaration; - body: Statements | VariableDeclaration; -} - -export interface ForOfStatement extends BaseNode { - type: AST_NODE_TYPES.ForOfStatement; - await: boolean; - right: Expressions | Identifier | Literal; - left: - | ArrayPattern - | Expressions - | Identifier - | ObjectPattern - | VariableDeclaration; - body: Statements; -} - -export interface ForStatement extends BaseNode { - type: AST_NODE_TYPES.ForStatement; - update: null | Expressions | Identifier; - test: null | Expressions | Identifier | Literal; - init: null | Expressions | Identifier | VariableDeclaration; - body: Statements | VariableDeclaration; -} - -export interface FunctionDeclarationLike extends BaseNode { - generator: boolean; - expression: boolean; - async: boolean; - declare?: boolean; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array< - | ArrayPattern - | AssignmentPattern - | Identifier - | ObjectPattern - | RestElement - | TSParameterProperty - >; - id: null | Identifier; - body?: BlockStatement; -} - -export interface FunctionDeclaration extends FunctionDeclarationLike { - type: AST_NODE_TYPES.FunctionDeclaration; - body: BlockStatement; -} - -export interface FunctionExpression extends BaseNode { - type: AST_NODE_TYPES.FunctionExpression; - generator: boolean; - expression: boolean; - async: boolean; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array< - | ArrayPattern - | AssignmentPattern - | Identifier - | ObjectPattern - | RestElement - | TSParameterProperty - >; - id: null | Identifier; - body: null | BlockStatement; -} - -export interface Identifier extends BaseNode { - type: AST_NODE_TYPES.Identifier; - optional?: boolean; - name: string; - typeAnnotation?: TSTypeAnnotation; - decorators?: Array; -} - -export interface IfStatement extends BaseNode { - type: AST_NODE_TYPES.IfStatement; - test: Expressions | Identifier | Literal; - consequent: Statements | VariableDeclaration; - alternate: null | Statements | VariableDeclaration; -} - -export interface Import extends BaseNode { - type: AST_NODE_TYPES.Import; -} - -export interface ImportDeclaration extends BaseNode { - type: AST_NODE_TYPES.ImportDeclaration; - specifiers: Array< - ImportDefaultSpecifier | ImportNamespaceSpecifier | ImportSpecifier - >; - source: Literal; -} - -export interface ImportDefaultSpecifier extends BaseNode { - type: AST_NODE_TYPES.ImportDefaultSpecifier; - local: Identifier; -} - -export interface ImportNamespaceSpecifier extends BaseNode { - type: AST_NODE_TYPES.ImportNamespaceSpecifier; - local: Identifier; -} - -export interface ImportSpecifier extends BaseNode { - type: AST_NODE_TYPES.ImportSpecifier; - local: Identifier; - imported: Identifier; -} - -export interface JSXAttribute extends BaseNode { - type: AST_NODE_TYPES.JSXAttribute; - value: null | JSXExpressionContainer | Literal; - name: JSXIdentifier; -} - -export interface JSXClosingElement extends BaseNode { - type: AST_NODE_TYPES.JSXClosingElement; - name: JSXIdentifier | JSXMemberExpression; -} - -export interface JSXClosingFragment extends BaseNode { - type: AST_NODE_TYPES.JSXClosingFragment; -} - -export interface JSXElement extends BaseNode { - type: AST_NODE_TYPES.JSXElement; - openingElement: JSXOpeningElement; - closingElement: null | JSXClosingElement; - children: Array< - JSXElement | JSXExpressionContainer | JSXFragment | JSXSpreadChild | JSXText - >; -} - -export interface JSXEmptyExpression extends BaseNode { - type: AST_NODE_TYPES.JSXEmptyExpression; -} - -export interface JSXExpressionContainer extends BaseNode { - type: AST_NODE_TYPES.JSXExpressionContainer; - expression: - | Expressions - | Identifier - | JSXElement - | JSXEmptyExpression - | Literal; -} - -export interface JSXFragment extends BaseNode { - type: AST_NODE_TYPES.JSXFragment; - openingFragment: JSXOpeningFragment; - closingFragment: JSXClosingFragment; - children: Array; -} - -export interface JSXIdentifier extends BaseNode { - type: AST_NODE_TYPES.JSXIdentifier; - name: string; -} - -export interface JSXMemberExpression extends BaseNode { - type: AST_NODE_TYPES.JSXMemberExpression; - property: JSXIdentifier; - object: JSXIdentifier | JSXMemberExpression | MemberExpression; -} - -export interface JSXOpeningElement extends BaseNode { - type: AST_NODE_TYPES.JSXOpeningElement; - selfClosing: boolean; - typeParameters?: TSTypeParameterInstantiation; - name: JSXIdentifier | JSXMemberExpression; - attributes: Array; -} - -export interface JSXOpeningFragment extends BaseNode { - type: AST_NODE_TYPES.JSXOpeningFragment; -} - -export interface JSXSpreadAttribute extends BaseNode { - type: AST_NODE_TYPES.JSXSpreadAttribute; - argument: Expressions | Identifier; -} - -export interface JSXSpreadChild extends BaseNode { - type: AST_NODE_TYPES.JSXSpreadChild; - expression: Expressions | JSXElement; -} - -export interface JSXText extends BaseNode { - type: AST_NODE_TYPES.JSXText; - value: string; - raw: string; -} - -export interface LabeledStatement extends BaseNode { - type: AST_NODE_TYPES.LabeledStatement; - label: Identifier; - body: Statements | VariableDeclaration; -} - -export interface Literal extends BaseNode { - type: AST_NODE_TYPES.Literal; - value: boolean | null | number | string | RegExp; - raw: string; - regex?: { - pattern: string; - flags: string; - }; -} - -export interface LogicalExpression extends BaseNode { - type: AST_NODE_TYPES.LogicalExpression; - operator: '&&' | '||'; - right: Expressions | Identifier | Literal; - left: Expressions | Identifier | Literal; -} - -export interface MemberExpression extends BaseNode { - type: AST_NODE_TYPES.MemberExpression; - computed?: boolean; - property: Expressions | Identifier | Literals; - object: Expressions | Identifier | Literals | Super; -} - -export interface MetaProperty extends BaseNode { - type: AST_NODE_TYPES.MetaProperty; - property: Identifier; - meta: Identifier; -} - -export interface MethodDefinition extends BaseNode { - type: - | AST_NODE_TYPES.MethodDefinition - | AST_NODE_TYPES.TSAbstractMethodDefinition; - static: boolean; - kind: 'constructor' | 'get' | 'method' | 'set'; - computed: boolean; - accessibility?: 'private' | 'protected' | 'public'; - value: FunctionExpression; - key: Expressions | Identifier | Literals; - decorators?: Array; -} - -export interface TSAbstractMethodDefinition extends MethodDefinition { - type: AST_NODE_TYPES.TSAbstractMethodDefinition; -} - -export interface NewExpression extends BaseNode { - type: AST_NODE_TYPES.NewExpression; - typeParameters?: TSTypeParameterInstantiation; - callee: Expressions | Identifier | Super | TemplateLiteral; - arguments: Array; -} - -export interface ObjectExpression extends BaseNode { - type: AST_NODE_TYPES.ObjectExpression; - properties: Array; -} - -export interface ObjectPattern extends BaseNode { - type: AST_NODE_TYPES.ObjectPattern; - optional?: boolean; - typeAnnotation?: TSTypeAnnotation; - properties: Array; -} - -export interface Program extends BaseNode { - type: AST_NODE_TYPES.Program; - sourceType: 'module' | 'script'; - body: Array; - tokens?: Token[]; - comments?: Comment[]; -} - -export interface Property extends BaseNode { - type: AST_NODE_TYPES.Property; - shorthand: boolean; - method: boolean; - kind: 'get' | 'init' | 'set'; - computed: boolean; - value: - | ArrayPattern - | AssignmentPattern - | Expressions - | Identifier - | Literals - | ObjectPattern; - typeParameters?: TSTypeParameterDeclaration; - key: Expressions | Identifier | Literals; -} - -export interface RestElement extends BaseNode { - type: AST_NODE_TYPES.RestElement; - optional?: boolean; - typeAnnotation?: TSTypeAnnotation; - decorators?: Array; - argument: ArrayPattern | AssignmentPattern | Identifier | ObjectPattern; - value?: - | ArrayPattern - | AssignmentPattern - | Expressions - | Identifier - | Literals - | ObjectPattern; -} - -export interface ReturnStatement extends BaseNode { - type: AST_NODE_TYPES.ReturnStatement; - argument: - | null - | Expressions - | Identifier - | JSXElement - | JSXFragment - | Literals; -} - -export interface SequenceExpression extends BaseNode { - type: AST_NODE_TYPES.SequenceExpression; - expressions: Array; -} - -export interface SpreadElement extends BaseNode { - type: AST_NODE_TYPES.SpreadElement; - argument: Expressions | Identifier; -} - -export interface Super extends BaseNode { - type: AST_NODE_TYPES.Super; -} - -export interface SwitchCase extends BaseNode { - type: AST_NODE_TYPES.SwitchCase; - test: null | Expressions | Identifier | Literals; - consequent: Array; -} - -export interface SwitchStatement extends BaseNode { - type: AST_NODE_TYPES.SwitchStatement; - discriminant: Expressions | Identifier | Literals; - cases: Array; -} - -export interface TaggedTemplateExpression extends BaseNode { - type: AST_NODE_TYPES.TaggedTemplateExpression; - typeParameters?: TSTypeParameterInstantiation; - tag: Identifier | MemberExpression | TemplateLiteral; - quasi: TemplateLiteral; -} - -export interface TemplateElement extends BaseNode { - type: AST_NODE_TYPES.TemplateElement; - tail: boolean; - value: { - raw: string; - cooked: string; - }; -} - -export interface TemplateLiteral extends BaseNode { - type: AST_NODE_TYPES.TemplateLiteral; - quasis: Array; - expressions: Array; -} - -export interface ThisExpression extends BaseNode { - type: AST_NODE_TYPES.ThisExpression; -} - -export interface ThrowStatement extends BaseNode { - type: AST_NODE_TYPES.ThrowStatement; - argument: null | Expressions | Identifier | Literal; -} - -export interface TryStatement extends BaseNode { - type: AST_NODE_TYPES.TryStatement; - handler: null | CatchClause; - finalizer: null | BlockStatement; - block: BlockStatement; -} - -export interface UnaryExpression extends BaseNode { - type: AST_NODE_TYPES.UnaryExpression; - prefix: boolean; - operator: '!' | '+' | '-' | 'delete' | 'typeof' | 'void' | '~'; - argument: Expressions | Identifier | Literals; -} - -export interface UpdateExpression extends BaseNode { - type: AST_NODE_TYPES.UpdateExpression; - prefix: boolean; - operator: '++' | '--'; - argument: Expressions | Identifier | Literal; -} - -export interface VariableDeclaration extends BaseNode { - type: AST_NODE_TYPES.VariableDeclaration; - kind: 'const' | 'let' | 'var'; - declare?: boolean; - declarations: Array; -} - -export interface VariableDeclarator extends BaseNode { - type: AST_NODE_TYPES.VariableDeclarator; - definite?: boolean; - init: null | Expressions | Identifier | JSXElement | Literals; - id: ArrayPattern | Identifier | ObjectPattern; -} - -export interface WhileStatement extends BaseNode { - type: AST_NODE_TYPES.WhileStatement; - test: Expressions | Identifier | Literals; - body: Statements | VariableDeclaration; -} - -export interface WithStatement extends BaseNode { - type: AST_NODE_TYPES.WithStatement; - object: Expressions | Identifier | Literal; - body: Statements | VariableDeclaration; -} - -export interface YieldExpression extends BaseNode { - type: AST_NODE_TYPES.YieldExpression; - delegate: boolean; - argument: null | Expressions | Identifier | Literals; -} - -export interface TSArrayType extends BaseNode { - type: AST_NODE_TYPES.TSArrayType; - elementType: TSTypeKeywords | TSTypeOperators; -} - -export interface TSAsExpression extends BaseNode { - type: AST_NODE_TYPES.TSAsExpression; - typeAnnotation: TSLiteralType | TSTypeKeywords | TSTypeOperators; - expression: Expressions | Identifier | JSXElement | Literals; -} - -export interface TSExpressionWithTypeArgumentsLike extends BaseNode { - type: AST_NODE_TYPES.TSInterfaceHeritage | AST_NODE_TYPES.TSClassImplements; - typeParameters?: TSTypeParameterInstantiation; - expression: Identifier | MemberExpression | Expressions; -} - -export interface TSClassImplements extends TSExpressionWithTypeArgumentsLike { - type: AST_NODE_TYPES.TSClassImplements; -} - -export interface TSInterfaceHeritage extends TSExpressionWithTypeArgumentsLike { - type: AST_NODE_TYPES.TSInterfaceHeritage; -} - -export interface TSConditionalType extends BaseNode { - type: AST_NODE_TYPES.TSConditionalType; - trueType: TSLiteralType | TSTypeKeywords | TSTypeOperators; - falseType: TSLiteralType | TSTypeKeywords | TSTypeOperators; - extendsType: TSLiteralType | TSTypeKeywords | TSTypeOperators; - checkType: TSTypeKeywords | TSTypeOperators; -} - -export interface TSFunctionDeclarationLike extends BaseNode { - type: - | AST_NODE_TYPES.TSConstructSignatureDeclaration - | AST_NODE_TYPES.TSConstructorType - | AST_NODE_TYPES.TSFunctionType - | AST_NODE_TYPES.TSCallSignatureDeclaration; - params: Array< - | Identifier - | ObjectPattern - | RestElement - | TSParameterProperty - | AssignmentPattern - | ArrayPattern - >; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; -} - -export interface TSCallSignatureDeclaration extends TSFunctionDeclarationLike { - type: AST_NODE_TYPES.TSCallSignatureDeclaration; -} - -export interface TSConstructSignatureDeclaration - extends TSFunctionDeclarationLike { - type: AST_NODE_TYPES.TSConstructSignatureDeclaration; -} - -export interface TSConstructorType extends TSFunctionDeclarationLike { - type: AST_NODE_TYPES.TSConstructorType; -} - -export interface TSFunctionType extends TSFunctionDeclarationLike { - type: AST_NODE_TYPES.TSFunctionType; -} - -export interface TSDeclareFunction extends FunctionDeclarationLike { - type: AST_NODE_TYPES.TSDeclareFunction; - body?: BlockStatement; -} - -export interface TSEnumDeclaration extends BaseNode { - type: AST_NODE_TYPES.TSEnumDeclaration; - declare?: boolean; - const?: boolean; - modifiers?: Array< - TSAsyncKeyword | TSPrivateKeyword | TSPublicKeyword | TSStaticKeyword - >; - members: Array; - id: Identifier; - decorators?: Array; -} - -export interface TSEnumMember extends BaseNode { - type: AST_NODE_TYPES.TSEnumMember; - initializer?: Expressions | Identifier | Literal; - id: Identifier | Literal; -} - -export interface TSExportAssignment extends BaseNode { - type: AST_NODE_TYPES.TSExportAssignment; - expression: Expressions | Identifier | Literal; -} - -export interface TSExternalModuleReference extends BaseNode { - type: AST_NODE_TYPES.TSExternalModuleReference; - expression: Identifier | Literal; -} - -export interface TSImportEqualsDeclaration extends BaseNode { - type: AST_NODE_TYPES.TSImportEqualsDeclaration; - isExport: boolean; - moduleReference: Identifier | TSExternalModuleReference | TSQualifiedName; - id: Identifier; -} - -export interface TSImportType extends BaseNode { - type: AST_NODE_TYPES.TSImportType; - isTypeOf: boolean; - typeParameters: null | TSTypeParameterInstantiation; - qualifier: null | Identifier; - parameter: TSLiteralType; -} - -export interface TSIndexSignature extends BaseNode { - type: AST_NODE_TYPES.TSIndexSignature; - static?: boolean; - readonly?: boolean; - export?: boolean; - accessibility?: 'private' | 'protected' | 'public'; - typeAnnotation?: TSTypeAnnotation; - parameters: Array< - AssignmentPattern | Identifier | RestElement | TSParameterProperty - >; -} - -export interface TSIndexedAccessType extends BaseNode { - type: AST_NODE_TYPES.TSIndexedAccessType; - objectType: TSTypeOperators | TSAnyKeyword; - indexType: TSLiteralType | TSTypeOperators | TSNeverKeyword; -} - -export interface TSInferType extends BaseNode { - type: AST_NODE_TYPES.TSInferType; - typeParameter: TSTypeParameter; -} - -export interface TSInterfaceBody extends BaseNode { - type: AST_NODE_TYPES.TSInterfaceBody; - body: Array; -} - -export interface TSInterfaceDeclaration extends BaseNode { - type: AST_NODE_TYPES.TSInterfaceDeclaration; - declare?: boolean; - abstract?: boolean; - typeParameters?: TSTypeParameterDeclaration; - implements?: Array; - id: Identifier; - extends?: Array; - decorators?: Array; - body: TSInterfaceBody; -} - -export interface TSIntersectionType extends BaseNode { - type: AST_NODE_TYPES.TSIntersectionType; - types: Array; -} - -export interface TSLiteralType extends BaseNode { - type: AST_NODE_TYPES.TSLiteralType; - literal: Literals | UnaryExpression; -} - -export interface TSMappedType extends BaseNode { - type: AST_NODE_TYPES.TSMappedType; - readonly?: boolean | '+' | '-'; - optional?: boolean | '+' | '-'; - typeParameter: TSTypeParameter; - typeAnnotation?: TSLiteralType | TSTypeKeywords | TSTypeOperators; -} - -export interface TSMethodSignature extends BaseNode { - type: AST_NODE_TYPES.TSMethodSignature; - optional?: boolean; - computed: boolean; - readonly?: boolean; - export?: boolean; - static?: boolean; - accessibility?: 'private' | 'protected' | 'public'; - typeParameters?: TSTypeParameterDeclaration; - returnType?: TSTypeAnnotation; - params: Array< - | ArrayPattern - | AssignmentPattern - | Identifier - | ObjectPattern - | RestElement - | TSParameterProperty - >; - key: Expressions | Identifier | Literal; -} - -export interface TSModuleBlock extends BaseNode { - type: AST_NODE_TYPES.TSModuleBlock; - body: Array; -} - -export interface TSModuleDeclaration extends BaseNode { - type: AST_NODE_TYPES.TSModuleDeclaration; - global?: boolean; - declare?: boolean; - modifiers?: Array< - | TSAsyncKeyword - | TSPrivateKeyword - | TSProtectedKeyword - | TSPublicKeyword - | TSStaticKeyword - >; - id: Identifier | Literal; - body?: TSModuleBlock | TSModuleDeclaration; -} - -export interface TSNamespaceExportDeclaration extends BaseNode { - type: AST_NODE_TYPES.TSNamespaceExportDeclaration; - id: Identifier; -} - -export interface TSNonNullExpression extends BaseNode { - type: AST_NODE_TYPES.TSNonNullExpression; - expression: Expressions | Identifier | Literal; -} - -export interface TSOptionalType extends BaseNode { - type: AST_NODE_TYPES.TSOptionalType; - typeAnnotation: TSStringKeyword; -} - -export interface TSParameterProperty extends BaseNode { - type: AST_NODE_TYPES.TSParameterProperty; - static?: boolean; - readonly?: boolean; - export?: boolean; - accessibility?: 'private' | 'protected' | 'public'; - parameter: - | ArrayPattern - | AssignmentPattern - | Identifier - | ObjectPattern - | RestElement; - decorators?: Array; -} - -export interface TSParenthesizedType extends BaseNode { - type: AST_NODE_TYPES.TSParenthesizedType; - typeAnnotation: TSLiteralType | TSTypeOperators; -} - -export interface TSPropertySignature extends BaseNode { - type: AST_NODE_TYPES.TSPropertySignature; - readonly?: boolean; - optional?: boolean; - static?: boolean; - export?: boolean; - computed: boolean; - accessibility?: 'private' | 'protected' | 'public'; - typeAnnotation?: TSTypeAnnotation; - key: Expressions | Identifier | Literal; - initializer?: Literal; -} - -export interface TSQualifiedName extends BaseNode { - type: AST_NODE_TYPES.TSQualifiedName; - right: Identifier; - left: Identifier | TSQualifiedName; -} - -export interface TSRestType extends BaseNode { - type: AST_NODE_TYPES.TSRestType; - typeAnnotation: TSTypeOperators; -} - -export interface TSThisType extends BaseNode { - type: AST_NODE_TYPES.TSThisType; -} - -export interface TSTupleType extends BaseNode { - type: AST_NODE_TYPES.TSTupleType; - elementTypes: Array; -} - -export interface TSTypeAliasDeclaration extends BaseNode { - type: AST_NODE_TYPES.TSTypeAliasDeclaration; - declare?: boolean; - typeParameters?: TSTypeParameterDeclaration; - typeAnnotation: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; - id: Identifier; -} - -export interface TSTypeAnnotation extends BaseNode { - type: AST_NODE_TYPES.TSTypeAnnotation; - typeAnnotation: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; -} - -export interface TSTypeAssertion extends BaseNode { - type: AST_NODE_TYPES.TSTypeAssertion; - typeAnnotation: TSTypeKeywords | TSTypeOperators; - expression: Expressions | Identifier | Literals; -} - -export interface TSTypeLiteral extends BaseNode { - type: AST_NODE_TYPES.TSTypeLiteral; - members: Array; -} - -export interface TSTypeOperator extends BaseNode { - type: AST_NODE_TYPES.TSTypeOperator; - operator: 'keyof' | 'unique'; - typeAnnotation: TSTypeKeywords | TSTypeOperators; -} - -export interface TSTypeParameter extends BaseNode { - type: AST_NODE_TYPES.TSTypeParameter; - name: Identifier; - default?: TSLiteralType | TSTypeKeywords | TSTypeOperators; - constraint?: TSLiteralType | TSThisType | TSTypeKeywords | TSTypeOperators; -} - -export interface TSTypeParameterDeclaration extends BaseNode { - type: AST_NODE_TYPES.TSTypeParameterDeclaration; - params: Array; -} - -export interface TSTypeParameterInstantiation extends BaseNode { - type: AST_NODE_TYPES.TSTypeParameterInstantiation; - params: Array; -} - -export interface TSTypePredicate extends BaseNode { - type: AST_NODE_TYPES.TSTypePredicate; - typeAnnotation: TSTypeAnnotation; - parameterName: Identifier | TSThisType; -} - -export interface TSTypeQuery extends BaseNode { - type: AST_NODE_TYPES.TSTypeQuery; - exprName: Identifier | TSQualifiedName; -} - -export interface TSTypeReference extends BaseNode { - type: AST_NODE_TYPES.TSTypeReference; - typeParameters?: TSTypeParameterInstantiation; - typeName: Identifier | TSQualifiedName; -} - -export interface TSUnionType extends BaseNode { - type: AST_NODE_TYPES.TSUnionType; - types: Array; -} - -export interface TSAnyKeyword extends BaseNode { - type: AST_NODE_TYPES.TSAnyKeyword; -} - -export interface TSAsyncKeyword extends BaseNode { - type: AST_NODE_TYPES.TSAsyncKeyword; -} - -export interface TSBigIntKeyword extends BaseNode { - type: AST_NODE_TYPES.TSBigIntKeyword; -} - -export interface TSBooleanKeyword extends BaseNode { - type: AST_NODE_TYPES.TSBooleanKeyword; -} - -export interface TSNeverKeyword extends BaseNode { - type: AST_NODE_TYPES.TSNeverKeyword; -} - -export interface TSNullKeyword extends BaseNode { - type: AST_NODE_TYPES.TSNullKeyword; -} - -export interface TSNumberKeyword extends BaseNode { - type: AST_NODE_TYPES.TSNumberKeyword; -} - -export interface TSObjectKeyword extends BaseNode { - type: AST_NODE_TYPES.TSObjectKeyword; -} - -export interface TSPrivateKeyword extends BaseNode { - type: AST_NODE_TYPES.TSPrivateKeyword; -} - -export interface TSProtectedKeyword extends BaseNode { - type: AST_NODE_TYPES.TSProtectedKeyword; -} - -export interface TSPublicKeyword extends BaseNode { - type: AST_NODE_TYPES.TSPublicKeyword; -} - -export interface TSStaticKeyword extends BaseNode { - type: AST_NODE_TYPES.TSStaticKeyword; -} - -export interface TSStringKeyword extends BaseNode { - type: AST_NODE_TYPES.TSStringKeyword; -} - -export interface TSSymbolKeyword extends BaseNode { - type: AST_NODE_TYPES.TSSymbolKeyword; -} - -export interface TSUndefinedKeyword extends BaseNode { - type: AST_NODE_TYPES.TSUndefinedKeyword; -} - -export interface TSUnknownKeyword extends BaseNode { - type: AST_NODE_TYPES.TSUnknownKeyword; -} - -export interface TSVoidKeyword extends BaseNode { - type: AST_NODE_TYPES.TSVoidKeyword; -} - -export type Declarations = - | ClassDeclaration - | ExportAllDeclaration - | ExportDefaultDeclaration - | ExportNamedDeclaration - | FunctionDeclaration - | ImportDeclaration - | VariableDeclaration - | TSDeclareFunction - | TSEnumDeclaration - | TSExportAssignment - | TSImportEqualsDeclaration - | TSInterfaceDeclaration - | TSModuleDeclaration - | TSTypeAliasDeclaration; - -export type Statements = - | ExpressionStatement - | BlockStatement - | EmptyStatement - | DebuggerStatement - | WithStatement - | ReturnStatement - | LabeledStatement - | BreakStatement - | ContinueStatement - | IfStatement - | SwitchStatement - | ThrowStatement - | TryStatement - | WhileStatement - | DoWhileStatement - | ForStatement - | ForInStatement - | ForOfStatement; - -export type Literals = TemplateLiteral | Literal | BigIntLiteral; - -export type Expressions = - | ThisExpression - | ArrayExpression - | ObjectExpression - | FunctionExpression - | ArrowFunctionExpression - | YieldExpression - | UnaryExpression - | UpdateExpression - | BinaryExpression - | AssignmentExpression - | LogicalExpression - | MemberExpression - | ConditionalExpression - | CallExpression - | NewExpression - | SequenceExpression - | TaggedTemplateExpression - | ClassExpression - | MetaProperty - | AwaitExpression - | TSAsExpression - | TSNonNullExpression - | TSTypeAssertion; - -export type TSSignatures = - | TSCallSignatureDeclaration - | TSConstructSignatureDeclaration - | TSIndexSignature - | TSMethodSignature - | TSPropertySignature; - -export type TSTypeKeywords = - | TSAnyKeyword - | TSBigIntKeyword - | TSBooleanKeyword - | TSNeverKeyword - | TSNullKeyword - | TSNumberKeyword - | TSObjectKeyword - | TSStringKeyword - | TSSymbolKeyword - | TSUndefinedKeyword - | TSUnknownKeyword - | TSVoidKeyword; - -export type TSTypeOperators = - | TSArrayType - | TSConditionalType - | TSConstructorType - | TSFunctionType - | TSImportType - | TSIndexedAccessType - | TSInferType - | TSIntersectionType - | TSMappedType - | TSParenthesizedType - | TSTupleType - | TSTypeLiteral - | TSTypeOperator - | TSTypePredicate - | TSTypeQuery - | TSTypeReference - | TSUnionType - | TSOptionalType - | TSRestType; diff --git a/packages/typescript-estree/src/convert-comments.ts b/packages/typescript-estree/src/convert-comments.ts index 037024fb98aa..cfce3b979200 100644 --- a/packages/typescript-estree/src/convert-comments.ts +++ b/packages/typescript-estree/src/convert-comments.ts @@ -7,7 +7,7 @@ import ts from 'typescript'; import { getLocFor, getNodeContainer } from './node-utils'; -import * as es from './ast-tree-nodes'; +import * as es from './typedefs'; /** * Converts a TypeScript comment to an Esprima comment. @@ -28,7 +28,7 @@ function convertTypeScriptCommentToEsprimaComment( startLoc: es.Position, endLoc: es.Position ): es.Comment { - const comment: es.Comment = { + const comment: es.OptionalRangeAndLoc = { type: block ? 'Block' : 'Line', value: text }; @@ -44,7 +44,7 @@ function convertTypeScriptCommentToEsprimaComment( }; } - return comment; + return comment as es.Comment; } /** diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 7f9e7eff6b26..8df01df5f223 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -6,7 +6,7 @@ * MIT License */ import ts from 'typescript'; -import * as es from './ast-tree-nodes'; +import * as es from './typedefs'; import { canContainDirective, convertToken, @@ -31,7 +31,6 @@ import { } from './node-utils'; import { AST_NODE_TYPES } from './ast-node-types'; import { TSNode } from './ts-nodes'; -import { ASTNode } from './ast-nodes'; const SyntaxKind = ts.SyntaxKind; @@ -160,11 +159,11 @@ export class Converter { return this.converter(child, parent, true, false); } - protected createNode( + protected createNode( node: ts.Node, - data: T + data: es.OptionalRangeAndLoc ): T { - const result: T = data; + const result = data; if (!result.range) { result.range = getRange(node, this.ast); } @@ -172,7 +171,7 @@ export class Converter { result.loc = getLocFor(result.range[0], result.range[1], this.ast); } - return result; + return result as T; } /** @@ -497,7 +496,7 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - protected convertNode(node: TSNode, parent: ts.Node): ASTNode | null { + protected convertNode(node: TSNode, parent: ts.Node): es.Node | null { switch (node.kind) { case SyntaxKind.SourceFile: { return this.createNode(node, { @@ -667,7 +666,7 @@ export class Converter { case SyntaxKind.FunctionDeclaration: { const isDeclare = hasModifier(SyntaxKind.DeclareKeyword, node); - const result = this.createNode(node, { + const result = this.createNode(node, { type: isDeclare || !node.body ? AST_NODE_TYPES.TSDeclareFunction @@ -678,7 +677,7 @@ export class Converter { async: hasModifier(SyntaxKind.AsyncKeyword, node), params: this.convertParameters(node.parameters), body: this.convertChild(node.body) || undefined - }); + }) as es.TSDeclareFunction | es.FunctionDeclaration; // Process returnType if (node.type) { @@ -838,7 +837,9 @@ export class Converter { case SyntaxKind.PropertyDeclaration: { const isAbstract = hasModifier(SyntaxKind.AbstractKeyword, node); - const result = this.createNode(node, { + const result = this.createNode< + es.TSAbstractClassProperty | es.ClassProperty + >(node, { type: isAbstract ? AST_NODE_TYPES.TSAbstractClassProperty : AST_NODE_TYPES.ClassProperty, @@ -897,7 +898,10 @@ export class Converter { ); } - let result: es.Property | es.MethodDefinition; + let result: + | es.Property + | es.TSAbstractMethodDefinition + | es.MethodDefinition; if (parent!.kind === SyntaxKind.ObjectLiteralExpression) { (method as any).params = node.parameters.map(el => @@ -931,14 +935,14 @@ export class Converter { ? AST_NODE_TYPES.TSAbstractMethodDefinition : AST_NODE_TYPES.MethodDefinition; - result = this.createNode(node, { + result = this.createNode(node, { type: methodDefinitionType, key: this.convertChild(node.name), value: method, computed: isComputedProperty(node.name), static: hasModifier(SyntaxKind.StaticKeyword, node), kind: 'method' - }); + }) as es.TSAbstractMethodDefinition | es.MethodDefinition; if (node.decorators) { result.decorators = node.decorators.map(el => @@ -1024,7 +1028,7 @@ export class Converter { }); const isStatic = hasModifier(SyntaxKind.StaticKeyword, node); - const result = this.createNode(node, { + const result = this.createNode(node, { type: hasModifier(SyntaxKind.AbstractKeyword, node) ? AST_NODE_TYPES.TSAbstractMethodDefinition : AST_NODE_TYPES.MethodDefinition, @@ -1033,7 +1037,7 @@ export class Converter { computed: false, static: isStatic, kind: isStatic ? 'method' : 'constructor' - }); + }) as es.TSAbstractMethodDefinition | es.MethodDefinition; const accessibility = getTSNodeAccessibility(node); if (accessibility) { @@ -1340,7 +1344,7 @@ export class Converter { clause => clause.token === SyntaxKind.ImplementsKeyword ); - const result = this.createNode(node, { + const result = this.createNode(node, { type: classNodeType, id: this.convertChild(node.name), body: this.createNode(node, { @@ -1352,7 +1356,7 @@ export class Converter { superClass && superClass.types[0] ? this.convertChild(superClass.types[0].expression) : null - }); + }) as es.ClassDeclaration | es.ClassExpression; if (superClass) { if (superClass.types.length > 1) { @@ -1627,11 +1631,14 @@ export class Converter { case SyntaxKind.PropertyAccessExpression: if (isJSXToken(parent!)) { - const jsxMemberExpression: es.MemberExpression = { - type: AST_NODE_TYPES.MemberExpression, - object: this.convertChild(node.expression), - property: this.convertChild(node.name) - }; + const jsxMemberExpression = this.createNode( + node, + { + type: AST_NODE_TYPES.MemberExpression, + object: this.convertChild(node.expression), + property: this.convertChild(node.name) + } + ); const isNestedMemberExpression = node.expression.kind === SyntaxKind.PropertyAccessExpression; if (node.expression.kind === SyntaxKind.ThisKeyword) { @@ -1643,10 +1650,7 @@ export class Converter { : AST_NODE_TYPES.JSXIdentifier; (jsxMemberExpression as any).property.type = AST_NODE_TYPES.JSXIdentifier; - return this.createNode( - node, - jsxMemberExpression - ); + return jsxMemberExpression; } else { return this.createNode(node, { type: AST_NODE_TYPES.MemberExpression, @@ -2227,10 +2231,14 @@ export class Converter { type = AST_NODE_TYPES.TSConstructorType; break; } - const result = this.createNode(node, { + const result = this.createNode(node, { type: type, params: this.convertParameters(node.parameters) - }); + }) as + | es.TSConstructSignatureDeclaration + | es.TSCallSignatureDeclaration + | es.TSFunctionType + | es.TSConstructorType; if (node.type) { result.returnType = this.convertTypeAnnotation(node.type, node); @@ -2246,16 +2254,13 @@ export class Converter { } case SyntaxKind.ExpressionWithTypeArguments: { - const result = this.createNode( - node, - { - type: - parent && parent.kind === SyntaxKind.InterfaceDeclaration - ? AST_NODE_TYPES.TSInterfaceHeritage - : AST_NODE_TYPES.TSClassImplements, - expression: this.convertChild(node.expression) - } - ); + const result = this.createNode(node, { + type: + parent && parent.kind === SyntaxKind.InterfaceDeclaration + ? AST_NODE_TYPES.TSInterfaceHeritage + : AST_NODE_TYPES.TSClassImplements, + expression: this.convertChild(node.expression) + }) as es.TSInterfaceHeritage | es.TSClassImplements; if (node.typeArguments && node.typeArguments.length) { result.typeParameters = this.convertTypeArgumentsToTypeParameters( diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index b8437820773b..14692155c6ba 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -6,7 +6,7 @@ */ import ts from 'typescript'; import unescape from 'lodash.unescape'; -import * as es from './ast-tree-nodes'; +import * as es from './typedefs'; import { AST_NODE_TYPES } from './ast-node-types'; const SyntaxKind = ts.SyntaxKind; diff --git a/packages/typescript-estree/src/parser-options.ts b/packages/typescript-estree/src/parser-options.ts index 8c2f4c1d3a16..a838db4af139 100644 --- a/packages/typescript-estree/src/parser-options.ts +++ b/packages/typescript-estree/src/parser-options.ts @@ -1,4 +1,4 @@ -import { Token, Comment } from './ast-tree-nodes'; +import { Token, Comment } from './typedefs'; export interface Extra { errorOnUnknownASTType: boolean; diff --git a/packages/typescript-estree/src/parser.ts b/packages/typescript-estree/src/parser.ts index 6df67bea0016..3c9680df06d4 100644 --- a/packages/typescript-estree/src/parser.ts +++ b/packages/typescript-estree/src/parser.ts @@ -14,7 +14,7 @@ import ts from 'typescript'; import convert from './ast-converter'; import { convertError } from './convert'; import { firstDefined } from './node-utils'; -import * as es from './ast-tree-nodes'; +import * as es from './typedefs'; import { Extra, ParserOptions } from './parser-options'; import { getFirstSemanticOrSyntacticError } from './semantic-errors'; diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 465d6b30ba0e..71e72504da55 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -21,7 +21,7 @@ export interface SourceLocation { end: Position; } -interface BaseNode { +export interface BaseNode { /** * The source location information of the node. */ @@ -38,12 +38,31 @@ interface BaseNode { parent?: Node; // every node *will* have a type, but let the nodes define their own exact string - // type: string; + type: string; // we don't ever set this from within ts-estree // source?: string | null; } +export interface Token extends BaseNode { + value: string; + regex?: { + pattern: string; + flags: string; + }; + object?: any; + property?: any; + name?: any; +} + +export type OptionalRangeAndLoc = Pick< + T, + Exclude +> & { + range?: [number, number]; + loc?: SourceLocation; +}; + export type Node = | ArrayExpression | ArrayPattern @@ -405,13 +424,13 @@ export type TSUnaryExpression = // **Ensure you sort the interfaces alphabetically** /////////////// -interface BinaryExpressionBase extends BaseNode { +export interface BinaryExpressionBase extends BaseNode { operator: string; left: Expression; right: Expression; } -interface ClassDeclarationBase extends BaseNode { +export interface ClassDeclarationBase extends BaseNode { typeParameters?: TSTypeParameterDeclaration; superTypeParameters?: TSTypeParameterInstantiation; id?: Identifier; @@ -423,7 +442,7 @@ interface ClassDeclarationBase extends BaseNode { decorators?: Decorator[]; } -interface ClassPropertyBase extends BaseNode { +export interface ClassPropertyBase extends BaseNode { key: PropertyName; value: Expression; computed: boolean; @@ -436,33 +455,34 @@ interface ClassPropertyBase extends BaseNode { typeAnnotation?: TSTypeAnnotation; } -interface FunctionDeclarationBase extends BaseNode { +export interface FunctionDeclarationBase extends BaseNode { id: Identifier | null; generator: boolean; expression: boolean; async: boolean; + declare?: boolean; params: Parameter[]; body?: BlockStatement | null; returnType?: TSTypeAnnotation; typeParameters?: TSTypeParameterDeclaration; } -interface FunctionSignatureBase extends BaseNode { +export interface FunctionSignatureBase extends BaseNode { params: Parameter[]; returnType?: TSTypeAnnotation; typeParameters?: TSTypeParameterDeclaration; } -interface LiteralBase extends BaseNode { - raw: boolean | number | RegExp | string | null; - value: string; +export interface LiteralBase extends BaseNode { + raw: string; + value: boolean | number | RegExp | string | null; regex?: { pattern: string; flags: string; }; } -interface MethodDefinitionBase extends BaseNode { +export interface MethodDefinitionBase extends BaseNode { key: PropertyName; value: FunctionExpression; computed: boolean; @@ -473,12 +493,12 @@ interface MethodDefinitionBase extends BaseNode { typeParameters?: TSTypeParameterDeclaration; } -interface TSHeritageBase extends BaseNode { +export interface TSHeritageBase extends BaseNode { expression: Expression; - typeParameters?: TSTypeParameterDeclaration; + typeParameters?: TSTypeParameterInstantiation; } -interface UnaryExpressionBase extends BaseNode { +export interface UnaryExpressionBase extends BaseNode { operator: string; prefix: boolean; argument: LeftHandSideExpression | Literal | UnaryExpression; @@ -509,8 +529,8 @@ export interface ArrowFunctionExpression extends BaseNode { body: Expression | BlockStatement; async: boolean; expression: boolean; - returnType: TSTypeAnnotation; - typeParameters: TSTypeParameterDeclaration; + returnType?: TSTypeAnnotation; + typeParameters?: TSTypeParameterDeclaration; } export interface AssignmentExpression extends BinaryExpressionBase { @@ -843,12 +863,15 @@ export interface Program extends BaseNode { type: AST_NODE_TYPES.Program; body: Statement[]; sourceType: 'module' | 'script'; + tokens?: Token[]; + comments?: Comment[]; } export interface Property extends BaseNode { type: AST_NODE_TYPES.Property; key: PropertyName; value: Expression | AssignmentPattern | BindingName; // TODO + typeParameters?: TSTypeParameterDeclaration; computed: boolean; method: boolean; shorthand: boolean; @@ -860,6 +883,7 @@ export interface RestElement extends BaseNode { argument: BindingName | Expression | PropertyName; typeAnnotation?: TSTypeAnnotation; optional?: boolean; + value?: AssignmentPattern; } export interface ReturnStatement extends BaseNode { @@ -895,7 +919,7 @@ export interface SwitchStatement extends BaseNode { export interface TaggedTemplateExpression extends BaseNode { type: AST_NODE_TYPES.TaggedTemplateExpression; - typeParameters: TSTypeParameterInstantiation; + typeParameters?: TSTypeParameterInstantiation; tag: LeftHandSideExpression; quasi: TemplateLiteral; } @@ -1134,7 +1158,7 @@ export interface TSMethodSignature extends BaseNode { key: PropertyName; params: Parameter[]; optional?: boolean; - returnType?: TypeNode; + returnType?: TSTypeAnnotation; readonly?: boolean; typeParameters?: TSTypeParameterDeclaration; accessibility?: Accessibility; @@ -1152,6 +1176,8 @@ export interface TSModuleDeclaration extends BaseNode { id: Identifier | Literal; body?: TSModuleBlock | Identifier; global?: boolean; + declare?: boolean; + modifiers?: Modifier[]; } export interface TSNamespaceExportDeclaration extends BaseNode { @@ -1209,7 +1235,7 @@ export interface TSPropertySignature extends BaseNode { readonly?: boolean; static?: boolean; export?: boolean; - accessability?: Accessibility; + accessibility?: Accessibility; } export interface TSPublicKeyword extends BaseNode { @@ -1310,7 +1336,7 @@ export interface TSTypeParameterInstantiation extends BaseNode { export interface TSTypePredicate extends BaseNode { type: AST_NODE_TYPES.TSTypePredicate; parameterName: Identifier | TSThisType; - typeAnnotation: TypeNode; + typeAnnotation: TSTypeAnnotation; } export interface TSTypeQuery extends BaseNode { From 9514ccecad875fab4ada6017a65649b6d28b4d87 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 2 Feb 2019 00:00:58 +0100 Subject: [PATCH 10/18] chore: rename Position to LineAndColumnData --- packages/typescript-estree/src/convert-comments.ts | 4 ++-- packages/typescript-estree/src/node-utils.ts | 2 +- packages/typescript-estree/src/typedefs.ts | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/typescript-estree/src/convert-comments.ts b/packages/typescript-estree/src/convert-comments.ts index cfce3b979200..59a2326122c8 100644 --- a/packages/typescript-estree/src/convert-comments.ts +++ b/packages/typescript-estree/src/convert-comments.ts @@ -25,8 +25,8 @@ function convertTypeScriptCommentToEsprimaComment( text: string, start: number, end: number, - startLoc: es.Position, - endLoc: es.Position + startLoc: es.LineAndColumnData, + endLoc: es.LineAndColumnData ): es.Comment { const comment: es.OptionalRangeAndLoc = { type: block ? 'Block' : 'Line', diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index 14692155c6ba..8114479dce84 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -224,7 +224,7 @@ export function getBinaryExpressionType( export function getLineAndCharacterFor( pos: number, ast: ts.SourceFile -): es.Position { +): es.LineAndColumnData { const loc = ast.getLineAndCharacterOfPosition(pos); return { line: loc.line + 1, diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 71e72504da55..7b9b6d237c29 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -1,6 +1,6 @@ import { AST_NODE_TYPES } from './ast-node-types'; -export interface Position { +export interface LineAndColumnData { /** * Line number (1-indexed) */ @@ -14,11 +14,11 @@ export interface SourceLocation { /** * The position of the first character of the parsed source region */ - start: Position; + start: LineAndColumnData; /** * The position of the first character after the parsed source region */ - end: Position; + end: LineAndColumnData; } export interface BaseNode { From 501634029484202c840d5681cf668d69759571fc Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 2 Feb 2019 00:09:18 +0100 Subject: [PATCH 11/18] chore: enforce stricter type checking --- packages/typescript-estree/src/convert.ts | 41 ++++++++++++++-------- packages/typescript-estree/src/typedefs.ts | 29 ++++++--------- 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 8df01df5f223..896b1118882c 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -666,7 +666,9 @@ export class Converter { case SyntaxKind.FunctionDeclaration: { const isDeclare = hasModifier(SyntaxKind.DeclareKeyword, node); - const result = this.createNode(node, { + const result = this.createNode< + es.TSDeclareFunction | es.FunctionDeclaration + >(node, { type: isDeclare || !node.body ? AST_NODE_TYPES.TSDeclareFunction @@ -677,7 +679,7 @@ export class Converter { async: hasModifier(SyntaxKind.AsyncKeyword, node), params: this.convertParameters(node.parameters), body: this.convertChild(node.body) || undefined - }) as es.TSDeclareFunction | es.FunctionDeclaration; + }); // Process returnType if (node.type) { @@ -935,14 +937,16 @@ export class Converter { ? AST_NODE_TYPES.TSAbstractMethodDefinition : AST_NODE_TYPES.MethodDefinition; - result = this.createNode(node, { + result = this.createNode< + es.TSAbstractMethodDefinition | es.MethodDefinition + >(node, { type: methodDefinitionType, key: this.convertChild(node.name), value: method, computed: isComputedProperty(node.name), static: hasModifier(SyntaxKind.StaticKeyword, node), kind: 'method' - }) as es.TSAbstractMethodDefinition | es.MethodDefinition; + }); if (node.decorators) { result.decorators = node.decorators.map(el => @@ -1028,7 +1032,9 @@ export class Converter { }); const isStatic = hasModifier(SyntaxKind.StaticKeyword, node); - const result = this.createNode(node, { + const result = this.createNode< + es.TSAbstractMethodDefinition | es.MethodDefinition + >(node, { type: hasModifier(SyntaxKind.AbstractKeyword, node) ? AST_NODE_TYPES.TSAbstractMethodDefinition : AST_NODE_TYPES.MethodDefinition, @@ -1037,7 +1043,7 @@ export class Converter { computed: false, static: isStatic, kind: isStatic ? 'method' : 'constructor' - }) as es.TSAbstractMethodDefinition | es.MethodDefinition; + }); const accessibility = getTSNodeAccessibility(node); if (accessibility) { @@ -1344,7 +1350,9 @@ export class Converter { clause => clause.token === SyntaxKind.ImplementsKeyword ); - const result = this.createNode(node, { + const result = this.createNode< + es.ClassDeclaration | es.ClassExpression + >(node, { type: classNodeType, id: this.convertChild(node.name), body: this.createNode(node, { @@ -1356,7 +1364,7 @@ export class Converter { superClass && superClass.types[0] ? this.convertChild(superClass.types[0].expression) : null - }) as es.ClassDeclaration | es.ClassExpression; + }); if (superClass) { if (superClass.types.length > 1) { @@ -2231,14 +2239,15 @@ export class Converter { type = AST_NODE_TYPES.TSConstructorType; break; } - const result = this.createNode(node, { - type: type, - params: this.convertParameters(node.parameters) - }) as + const result = this.createNode< | es.TSConstructSignatureDeclaration | es.TSCallSignatureDeclaration | es.TSFunctionType - | es.TSConstructorType; + | es.TSConstructorType + >(node, { + type: type, + params: this.convertParameters(node.parameters) + }); if (node.type) { result.returnType = this.convertTypeAnnotation(node.type, node); @@ -2254,13 +2263,15 @@ export class Converter { } case SyntaxKind.ExpressionWithTypeArguments: { - const result = this.createNode(node, { + const result = this.createNode< + es.TSInterfaceHeritage | es.TSClassImplements + >(node, { type: parent && parent.kind === SyntaxKind.InterfaceDeclaration ? AST_NODE_TYPES.TSInterfaceHeritage : AST_NODE_TYPES.TSClassImplements, expression: this.convertChild(node.expression) - }) as es.TSInterfaceHeritage | es.TSClassImplements; + }); if (node.typeArguments && node.typeArguments.length) { result.typeParameters = this.convertTypeArgumentsToTypeParameters( diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 7b9b6d237c29..6d3e37afe033 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -424,13 +424,13 @@ export type TSUnaryExpression = // **Ensure you sort the interfaces alphabetically** /////////////// -export interface BinaryExpressionBase extends BaseNode { +interface BinaryExpressionBase extends BaseNode { operator: string; left: Expression; right: Expression; } -export interface ClassDeclarationBase extends BaseNode { +interface ClassDeclarationBase extends BaseNode { typeParameters?: TSTypeParameterDeclaration; superTypeParameters?: TSTypeParameterInstantiation; id?: Identifier; @@ -442,7 +442,7 @@ export interface ClassDeclarationBase extends BaseNode { decorators?: Decorator[]; } -export interface ClassPropertyBase extends BaseNode { +interface ClassPropertyBase extends BaseNode { key: PropertyName; value: Expression; computed: boolean; @@ -455,7 +455,7 @@ export interface ClassPropertyBase extends BaseNode { typeAnnotation?: TSTypeAnnotation; } -export interface FunctionDeclarationBase extends BaseNode { +interface FunctionDeclarationBase extends BaseNode { id: Identifier | null; generator: boolean; expression: boolean; @@ -467,13 +467,13 @@ export interface FunctionDeclarationBase extends BaseNode { typeParameters?: TSTypeParameterDeclaration; } -export interface FunctionSignatureBase extends BaseNode { +interface FunctionSignatureBase extends BaseNode { params: Parameter[]; returnType?: TSTypeAnnotation; typeParameters?: TSTypeParameterDeclaration; } -export interface LiteralBase extends BaseNode { +interface LiteralBase extends BaseNode { raw: string; value: boolean | number | RegExp | string | null; regex?: { @@ -482,7 +482,7 @@ export interface LiteralBase extends BaseNode { }; } -export interface MethodDefinitionBase extends BaseNode { +interface MethodDefinitionBase extends BaseNode { key: PropertyName; value: FunctionExpression; computed: boolean; @@ -493,12 +493,12 @@ export interface MethodDefinitionBase extends BaseNode { typeParameters?: TSTypeParameterDeclaration; } -export interface TSHeritageBase extends BaseNode { +interface TSHeritageBase extends BaseNode { expression: Expression; typeParameters?: TSTypeParameterInstantiation; } -export interface UnaryExpressionBase extends BaseNode { +interface UnaryExpressionBase extends BaseNode { operator: string; prefix: boolean; argument: LeftHandSideExpression | Literal | UnaryExpression; @@ -1022,17 +1022,8 @@ export interface TSConstructSignatureDeclaration extends FunctionSignatureBase { type: AST_NODE_TYPES.TSConstructSignatureDeclaration; } -export interface TSDeclareFunction extends BaseNode { +export interface TSDeclareFunction extends FunctionDeclarationBase { type: AST_NODE_TYPES.TSDeclareFunction; - id: Identifier | null; - generator: boolean; - expression: boolean; - async: boolean; - params: Parameter[]; - body?: BlockStatement | null; - returnType?: TSTypeAnnotation; - declare: boolean; - typeParameters?: TSTypeParameterDeclaration; } export interface TSDeclareKeyword extends BaseNode { From 11d09131c350c13e52d22f92dae1de453db90bd3 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 2 Feb 2019 00:54:20 +0100 Subject: [PATCH 12/18] refactor(ts-estree): remove unnecessary assertions --- packages/typescript-estree/src/convert.ts | 71 ++++++++++------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 896b1118882c..d6e8faa8e75f 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -225,14 +225,14 @@ export class Converter { ts.isExpressionStatement(statement) && ts.isStringLiteral(statement.expression) ) { - const raw = child.expression.raw!; + const raw = child.expression.raw; child.directive = raw.slice(1, -1); - return child!; // child can be null but it's filtered below + return child; // child can be null but it's filtered below } else { allowDirectives = false; } } - return child!; // child can be null but it's filtered below + return child; // child can be null but it's filtered below }) // filter out unknown nodes for now .filter(statement => statement) @@ -289,7 +289,7 @@ export class Converter { return []; } return parameters.map(param => { - const convertedParam = this.convertChild(param)!; + const convertedParam = this.convertChild(param); if (!param.decorators || !param.decorators.length) { return convertedParam; } @@ -481,9 +481,9 @@ export class Converter { typeAnnotationParent: es.BaseNode, node: ts.TypeNode ): void { - typeAnnotationParent.range![1] = node.getEnd(); - typeAnnotationParent.loc!.end = getLineAndCharacterFor( - typeAnnotationParent.range![1], + typeAnnotationParent.range[1] = node.getEnd(); + typeAnnotationParent.loc.end = getLineAndCharacterFor( + typeAnnotationParent.range[1], this.ast ); } @@ -894,10 +894,7 @@ export class Converter { }); if (node.type) { - (method as any).returnType = this.convertTypeAnnotation( - node.type, - node - ); + method.returnType = this.convertTypeAnnotation(node.type, node); } let result: @@ -905,10 +902,8 @@ export class Converter { | es.TSAbstractMethodDefinition | es.MethodDefinition; - if (parent!.kind === SyntaxKind.ObjectLiteralExpression) { - (method as any).params = node.parameters.map(el => - this.convertChild(el) - ); + if (parent.kind === SyntaxKind.ObjectLiteralExpression) { + method.params = node.parameters.map(el => this.convertChild(el)); result = this.createNode(node, { type: AST_NODE_TYPES.Property, @@ -1100,7 +1095,7 @@ export class Converter { }); case SyntaxKind.BindingElement: { - if (parent!.kind === SyntaxKind.ArrayBindingPattern) { + if (parent.kind === SyntaxKind.ArrayBindingPattern) { const arrayItem = this.convertChild(node.name, parent); if (node.initializer) { @@ -1117,7 +1112,7 @@ export class Converter { } else { return arrayItem; } - } else if (parent!.kind === SyntaxKind.ObjectBindingPattern) { + } else if (parent.kind === SyntaxKind.ObjectBindingPattern) { let result: es.RestElement | es.Property; if (node.dotDotDotToken) { result = this.createNode(node, { @@ -1279,7 +1274,7 @@ export class Converter { argument: this.convertChild(node.name) }); } else if (node.initializer) { - parameter = this.convertChild(node.name)!; + parameter = this.convertChild(node.name); result = this.createNode(node, { type: AST_NODE_TYPES.AssignmentPattern, left: parameter, @@ -1288,15 +1283,11 @@ export class Converter { if (node.modifiers) { // AssignmentPattern should not contain modifiers in range - result.range![0] = parameter.range[0]; - result.loc = getLocFor( - result.range![0], - result.range![1], - this.ast - ); + result.range[0] = parameter.range[0]; + result.loc = getLocFor(result.range[0], result.range[1], this.ast); } } else { - parameter = result = this.convertChild(node.name, parent)!; + parameter = result = this.convertChild(node.name, parent); } if (node.type) { @@ -1435,18 +1426,18 @@ export class Converter { if (node.importClause) { if (node.importClause.name) { - result.specifiers!.push(this.convertChild(node.importClause)); + result.specifiers.push(this.convertChild(node.importClause)); } if (node.importClause.namedBindings) { switch (node.importClause.namedBindings.kind) { case SyntaxKind.NamespaceImport: - result.specifiers!.push( + result.specifiers.push( this.convertChild(node.importClause.namedBindings) ); break; case SyntaxKind.NamedImports: - result.specifiers = result.specifiers!.concat( + result.specifiers = result.specifiers.concat( node.importClause.namedBindings.elements.map(el => this.convertChild(el) ) @@ -1581,12 +1572,12 @@ export class Converter { expressions: [] }); - const left = this.convertChild(node.left)!, - right = this.convertChild(node.right)!; + const left = this.convertChild(node.left), + right = this.convertChild(node.right); if (left.type === AST_NODE_TYPES.SequenceExpression) { result.expressions = result.expressions.concat( - (left as any).expressions + left.expressions ); } else { result.expressions.push(left); @@ -1594,7 +1585,7 @@ export class Converter { if (right.type === AST_NODE_TYPES.SequenceExpression) { result.expressions = result.expressions.concat( - (right as any).expressions + right.expressions ); } else { result.expressions.push(right); @@ -1638,7 +1629,7 @@ export class Converter { } case SyntaxKind.PropertyAccessExpression: - if (isJSXToken(parent!)) { + if (isJSXToken(parent)) { const jsxMemberExpression = this.createNode( node, { @@ -1647,13 +1638,14 @@ export class Converter { property: this.convertChild(node.name) } ); + // TODO: refactor this const isNestedMemberExpression = node.expression.kind === SyntaxKind.PropertyAccessExpression; if (node.expression.kind === SyntaxKind.ThisKeyword) { - (jsxMemberExpression as any).object.name = 'this'; + (jsxMemberExpression.object as any).name = 'this'; } - (jsxMemberExpression as any).object.type = isNestedMemberExpression + (jsxMemberExpression.object as any).type = isNestedMemberExpression ? AST_NODE_TYPES.MemberExpression : AST_NODE_TYPES.JSXIdentifier; (jsxMemberExpression as any).property.type = @@ -1740,7 +1732,7 @@ export class Converter { raw: '', value: '' }); - result.raw = this.ast.text.slice(result.range![0], result.range![1]); + result.raw = this.ast.text.slice(result.range[0], result.range[1]); if ((parent as any).name && (parent as any).name === node) { result.value = node.text; } else { @@ -1763,7 +1755,7 @@ export class Converter { raw: '', value: '' }); - result.raw = this.ast.text.slice(result.range![0], result.range![1]); + result.raw = this.ast.text.slice(result.range[0], result.range[1]); result.value = result.raw.slice(0, -1); // remove suffix `n` return result; } @@ -2351,8 +2343,9 @@ export class Converter { /** * Specific fix for type-guard location data */ - result.typeAnnotation!.loc = result.typeAnnotation!.typeAnnotation!.loc; - result.typeAnnotation!.range = result.typeAnnotation!.typeAnnotation!.range; + result.typeAnnotation.loc = result.typeAnnotation.typeAnnotation.loc; + result.typeAnnotation.range = + result.typeAnnotation.typeAnnotation.range; return result; } From c8d3601bf13691d8dbe83ec57edc35100c1309b6 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 2 Feb 2019 01:03:52 +0100 Subject: [PATCH 13/18] chore: correct formatting after recent changes --- packages/typescript-estree/src/convert.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index d6e8faa8e75f..3a88c1f5a27f 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -1576,17 +1576,13 @@ export class Converter { right = this.convertChild(node.right); if (left.type === AST_NODE_TYPES.SequenceExpression) { - result.expressions = result.expressions.concat( - left.expressions - ); + result.expressions = result.expressions.concat(left.expressions); } else { result.expressions.push(left); } if (right.type === AST_NODE_TYPES.SequenceExpression) { - result.expressions = result.expressions.concat( - right.expressions - ); + result.expressions = result.expressions.concat(right.expressions); } else { result.expressions.push(right); } From 8cced4bdcef17918fce283b0d95ed44d03ef1437 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 2 Feb 2019 01:14:23 +0100 Subject: [PATCH 14/18] refactor: restore ~original conversion of binary expression --- packages/typescript-estree/src/convert.ts | 55 ++++++++++------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 3a88c1f5a27f..590d4b4b6b44 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -920,7 +920,7 @@ export class Converter { /** * Unlike in object literal methods, class method params can have decorators */ - (method as any).params = this.convertParameters(node.parameters); + method.params = this.convertParameters(node.parameters); /** * TypeScript class methods can be defined as "abstract" @@ -1589,38 +1589,29 @@ export class Converter { return result; } else { const type = getBinaryExpressionType(node.operatorToken); - switch (type) { - case AST_NODE_TYPES.AssignmentExpression: - if (this.allowPattern) { - return this.createNode(node, { - type: AST_NODE_TYPES.AssignmentPattern, - left: this.convertPattern(node.left, node), - right: this.convertChild(node.right) - }); - } else { - return this.createNode(node, { - type: AST_NODE_TYPES.AssignmentExpression, - operator: getTextForTokenKind(node.operatorToken.kind) as any, - left: this.convertPattern(node.left, node), - right: this.convertChild(node.right) - }); - } - case AST_NODE_TYPES.LogicalExpression: - return this.createNode(node, { - type: AST_NODE_TYPES.LogicalExpression, - operator: getTextForTokenKind(node.operatorToken.kind) as any, - left: this.convertChild(node.left, node), - right: this.convertChild(node.right) - }); - default: - case AST_NODE_TYPES.BinaryExpression: - return this.createNode(node, { - type: AST_NODE_TYPES.BinaryExpression, - operator: getTextForTokenKind(node.operatorToken.kind) as any, - left: this.convertChild(node.left, node), - right: this.convertChild(node.right) - }); + if ( + this.allowPattern && + type === AST_NODE_TYPES.AssignmentExpression + ) { + return this.createNode(node, { + type: AST_NODE_TYPES.AssignmentPattern, + left: this.convertPattern(node.left, node), + right: this.convertChild(node.right) + }); } + return this.createNode< + es.AssignmentExpression | es.LogicalExpression | es.BinaryExpression + >(node, { + type: type, + operator: getTextForTokenKind(node.operatorToken.kind)!, + left: this.converter( + node.left, + node, + this.inTypeMode, + type === AST_NODE_TYPES.AssignmentExpression + ), + right: this.convertChild(node.right) + }); } } From 9a411d3603e1f68df683338ec01ebf88bf7369ea Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 2 Feb 2019 03:34:29 +0100 Subject: [PATCH 15/18] refactor: add typing for convertTypeScriptJSXTagNameToESTreeName --- packages/typescript-estree/src/convert.ts | 30 ++++++---- packages/typescript-estree/src/node-utils.ts | 2 +- packages/typescript-estree/src/typedefs.ts | 62 ++++++++++++-------- 3 files changed, 56 insertions(+), 38 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 590d4b4b6b44..35117d7d4790 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -386,31 +386,39 @@ export class Converter { // Convert TSNode left and right objects into ESTreeNode object // and property objects - tagNameToken.object = this.convertChild( + const object = this.convertChild( (node as any).tagName.expression, node ); - tagNameToken.property = this.convertChild( + const property = this.convertChild( (node as any).tagName.name, node ); // Assign the appropriate types - tagNameToken.object.type = isNestedMemberExpression + object.type = isNestedMemberExpression ? AST_NODE_TYPES.JSXMemberExpression : AST_NODE_TYPES.JSXIdentifier; - tagNameToken.property.type = AST_NODE_TYPES.JSXIdentifier; + property.type = AST_NODE_TYPES.JSXIdentifier; if ((tagName as any).expression.kind === SyntaxKind.ThisKeyword) { - tagNameToken.object.name = 'this'; + object.name = 'this'; } + + return this.createNode(tagName, { + type: AST_NODE_TYPES.JSXMemberExpression, + range: tagNameToken.range, + loc: tagNameToken.loc, + object: object, + property: property + }); } else { - tagNameToken.type = AST_NODE_TYPES.JSXIdentifier; - tagNameToken.name = tagNameToken.value; + return this.createNode(tagName, { + type: AST_NODE_TYPES.JSXIdentifier, + range: tagNameToken.range, + loc: tagNameToken.loc, + name: tagNameToken.value + }); } - - delete tagNameToken.value; - - return tagNameToken as any; } /** diff --git a/packages/typescript-estree/src/node-utils.ts b/packages/typescript-estree/src/node-utils.ts index 8114479dce84..aa5a10418c76 100644 --- a/packages/typescript-estree/src/node-utils.ts +++ b/packages/typescript-estree/src/node-utils.ts @@ -501,7 +501,7 @@ export function fixExports( * @param token the ts.Token * @returns the token type */ -export function getTokenType(token: any): string { +export function getTokenType(token: any): es.TokenType { // Need two checks for keywords since some are also identifiers if (token.originalKeywordKind) { switch (token.originalKeywordKind) { diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 6d3e37afe033..6a37727b0161 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -38,21 +38,45 @@ export interface BaseNode { parent?: Node; // every node *will* have a type, but let the nodes define their own exact string - type: string; + // type: string; // we don't ever set this from within ts-estree // source?: string | null; } +/* + * Token and Comment are pseudo-nodes to represent pieces of source code + * + * NOTE: + * They are not included in the `Node` union below on purpose because they + * are not ever included as part of the standard AST tree. + */ + +export type TokenType = + | 'Boolean' + | 'Identifier' + | 'JSXIdentifier' + | 'JSXMemberExpression' + | 'JSXText' + | 'Keyword' + | 'Null' + | 'Numeric' + | 'Punctuator' + | 'RegularExpression' + | 'String' + | 'Template'; + export interface Token extends BaseNode { + type: TokenType; value: string; regex?: { pattern: string; flags: string; }; - object?: any; - property?: any; - name?: any; +} +export interface Comment extends BaseNode { + type: 'Line' | 'Block'; + value: string; } export type OptionalRangeAndLoc = Pick< @@ -63,6 +87,8 @@ export type OptionalRangeAndLoc = Pick< loc?: SourceLocation; }; +// Every single valid AST Node +// Please keep it sorted alphabetically. export type Node = | ArrayExpression | ArrayPattern @@ -152,12 +178,10 @@ export type Node = | TSCallSignatureDeclaration | TSClassImplements | TSConditionalType - // | TSConstKeyword | TSConstructorType | TSConstructSignatureDeclaration | TSDeclareFunction | TSDeclareKeyword - // | TSDefaultKeyword | TSEnumDeclaration | TSEnumMember | TSExportAssignment @@ -314,9 +338,7 @@ export type LiteralExpression = BigIntLiteral | Literal | TemplateLiteral; export type Modifier = | TSAbstractKeyword | TSAsyncKeyword - // | TSConstKeyword | TSDeclareKeyword - // | TSDefaultKeyword | TSExportKeyword | TSPublicKeyword | TSPrivateKeyword @@ -460,11 +482,11 @@ interface FunctionDeclarationBase extends BaseNode { generator: boolean; expression: boolean; async: boolean; - declare?: boolean; params: Parameter[]; body?: BlockStatement | null; returnType?: TSTypeAnnotation; typeParameters?: TSTypeParameterDeclaration; + declare?: boolean; } interface FunctionSignatureBase extends BaseNode { @@ -598,11 +620,6 @@ export interface ClassProperty extends ClassPropertyBase { type: AST_NODE_TYPES.ClassProperty; } -export interface Comment extends BaseNode { - type: 'Line' | 'Block'; - value: string; -} - export interface ConditionalExpression extends BaseNode { type: AST_NODE_TYPES.ConditionalExpression; test: Expression; @@ -778,7 +795,8 @@ export interface JSXIdentifier extends BaseNode { export interface JSXMemberExpression extends BaseNode { type: AST_NODE_TYPES.JSXMemberExpression; - name: string; + object: JSXTagNameExpression; + property: JSXTagNameExpression; } export interface JSXOpeningElement extends BaseNode { @@ -863,19 +881,19 @@ export interface Program extends BaseNode { type: AST_NODE_TYPES.Program; body: Statement[]; sourceType: 'module' | 'script'; - tokens?: Token[]; comments?: Comment[]; + tokens?: Token[]; } export interface Property extends BaseNode { type: AST_NODE_TYPES.Property; key: PropertyName; - value: Expression | AssignmentPattern | BindingName; // TODO - typeParameters?: TSTypeParameterDeclaration; + value: Expression | AssignmentPattern | BindingName; computed: boolean; method: boolean; shorthand: boolean; kind: 'init'; + typeParameters?: TSTypeParameterDeclaration; } export interface RestElement extends BaseNode { @@ -1010,10 +1028,6 @@ export interface TSConditionalType extends BaseNode { falseType: TypeNode; } -// export interface TSConstKeyword extends BaseNode { -// type: AST_NODE_TYPES.TSConstKeyword; -// } - export interface TSConstructorType extends FunctionSignatureBase { type: AST_NODE_TYPES.TSConstructorType; } @@ -1030,10 +1044,6 @@ export interface TSDeclareKeyword extends BaseNode { type: AST_NODE_TYPES.TSDeclareKeyword; } -// export interface TSDefaultKeyword extends BaseNode { -// type: AST_NODE_TYPES.TSDefaultKeyword; -// } - export interface TSEnumDeclaration extends BaseNode { type: AST_NODE_TYPES.TSEnumDeclaration; id: Identifier; From 92bc3902011d54cc9eda8553da5d88f7f4d2f6b6 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 2 Feb 2019 03:51:30 +0100 Subject: [PATCH 16/18] refactor: remove any cast in jsx tag name --- packages/typescript-estree/src/convert.ts | 19 +++++++------------ packages/typescript-estree/src/typedefs.ts | 2 +- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 35117d7d4790..a4a16769dede 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -370,30 +370,25 @@ export class Converter { /** * Converts a TypeScript JSX node.tagName into an ESTree node.name * @param tagName the tagName object from a JSX ts.Node - * @param node + * @param parent * @returns the converted ESTree name object */ protected convertTypeScriptJSXTagNameToESTreeName( tagName: ts.JsxTagNameExpression, - node: ts.Node + parent: ts.Node ): es.JSXMemberExpression | es.JSXIdentifier { + // TODO: remove convertToken call const tagNameToken = convertToken(tagName, this.ast); - if (tagNameToken.type === AST_NODE_TYPES.JSXMemberExpression) { + if (tagName.kind === SyntaxKind.PropertyAccessExpression) { const isNestedMemberExpression = - (node as any).tagName.expression.kind === + tagName.expression.kind === SyntaxKind.PropertyAccessExpression; // Convert TSNode left and right objects into ESTreeNode object // and property objects - const object = this.convertChild( - (node as any).tagName.expression, - node - ); - const property = this.convertChild( - (node as any).tagName.name, - node - ); + const object = this.convertChild(tagName.expression, parent); + const property = this.convertChild(tagName.name, parent); // Assign the appropriate types object.type = isNestedMemberExpression diff --git a/packages/typescript-estree/src/typedefs.ts b/packages/typescript-estree/src/typedefs.ts index 6a37727b0161..140ed6e09a49 100644 --- a/packages/typescript-estree/src/typedefs.ts +++ b/packages/typescript-estree/src/typedefs.ts @@ -796,7 +796,7 @@ export interface JSXIdentifier extends BaseNode { export interface JSXMemberExpression extends BaseNode { type: AST_NODE_TYPES.JSXMemberExpression; object: JSXTagNameExpression; - property: JSXTagNameExpression; + property: JSXIdentifier; } export interface JSXOpeningElement extends BaseNode { From 6c5d3fade29d7736dc08397cf0d2dc65124f8b76 Mon Sep 17 00:00:00 2001 From: Armano Date: Sat, 2 Feb 2019 03:52:01 +0100 Subject: [PATCH 17/18] chore: fix formatting --- packages/typescript-estree/src/convert.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index a4a16769dede..f452266aa0b8 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -382,8 +382,7 @@ export class Converter { if (tagName.kind === SyntaxKind.PropertyAccessExpression) { const isNestedMemberExpression = - tagName.expression.kind === - SyntaxKind.PropertyAccessExpression; + tagName.expression.kind === SyntaxKind.PropertyAccessExpression; // Convert TSNode left and right objects into ESTreeNode object // and property objects From d0b039a978170a294ea1c0ca56f6afbeb1b463a4 Mon Sep 17 00:00:00 2001 From: Armano Date: Sun, 3 Feb 2019 18:04:11 +0100 Subject: [PATCH 18/18] chore(ts-estree): update accessibility and TODOs --- packages/typescript-estree/src/convert.ts | 50 +++++++++++------------ 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index f452266aa0b8..8e2d6a876a15 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -54,13 +54,13 @@ export function convertError(error: any) { } export class Converter { - protected ast: ts.SourceFile; - protected options: ConverterOptions; - public esTreeNodeToTSNodeMap = new WeakMap(); - public tsNodeToESTreeNodeMap = new WeakMap(); + private readonly ast: ts.SourceFile; + private options: ConverterOptions; + private esTreeNodeToTSNodeMap = new WeakMap(); + private tsNodeToESTreeNodeMap = new WeakMap(); - protected allowPattern: boolean = false; - protected inTypeMode: boolean = false; + private allowPattern: boolean = false; + private inTypeMode: boolean = false; /** * Converts a TypeScript node into an ESTree node @@ -73,14 +73,14 @@ export class Converter { this.options = options; } - public getASTMaps() { + getASTMaps() { return { esTreeNodeToTSNodeMap: this.esTreeNodeToTSNodeMap, tsNodeToESTreeNodeMap: this.tsNodeToESTreeNodeMap }; } - public convertProgram(): es.Program { + convertProgram(): es.Program { return this.converter(this.ast) as es.Program; } @@ -92,7 +92,7 @@ export class Converter { * @param allowPattern flag to determine if patterns are allowed * @returns the converted ESTree node */ - protected converter( + private converter( node?: ts.Node, parent?: ts.Node, inTypeMode?: boolean, @@ -135,7 +135,7 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - protected convertPattern(child?: ts.Node, parent?: ts.Node): any | null { + private convertPattern(child?: ts.Node, parent?: ts.Node): any | null { return this.converter(child, parent, this.inTypeMode, true); } @@ -145,7 +145,7 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - protected convertChild(child?: ts.Node, parent?: ts.Node): any | null { + private convertChild(child?: ts.Node, parent?: ts.Node): any | null { return this.converter(child, parent, this.inTypeMode, false); } @@ -155,11 +155,11 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - protected convertType(child?: ts.Node, parent?: ts.Node): any | null { + private convertType(child?: ts.Node, parent?: ts.Node): any | null { return this.converter(child, parent, true, false); } - protected createNode( + private createNode( node: ts.Node, data: es.OptionalRangeAndLoc ): T { @@ -181,7 +181,7 @@ export class Converter { * @param parent parentNode * @returns The type annotation node. */ - protected convertTypeAnnotation( + private convertTypeAnnotation( child: ts.TypeNode, parent: ts.Node ): es.TSTypeAnnotation { @@ -208,7 +208,7 @@ export class Converter { * @param parent parentNode * @returns Array of body statements */ - protected convertBodyExpressions( + private convertBodyExpressions( nodes: ts.NodeArray, parent: ts.Node ): any[] { @@ -244,7 +244,7 @@ export class Converter { * @param typeArguments ts.Node typeArguments * @returns TypeParameterInstantiation node */ - protected convertTypeArgumentsToTypeParameters( + private convertTypeArgumentsToTypeParameters( typeArguments: ts.NodeArray ): es.TSTypeParameterInstantiation { const greaterThanToken = findNextToken(typeArguments, this.ast, this.ast)!; @@ -262,7 +262,7 @@ export class Converter { * @param typeParameters ts.Node typeParameters * @returns TypeParameterDeclaration node */ - protected convertTSTypeParametersToTypeParametersDeclaration( + private convertTSTypeParametersToTypeParametersDeclaration( typeParameters: ts.NodeArray ): es.TSTypeParameterDeclaration { const greaterThanToken = findNextToken(typeParameters, this.ast, this.ast)!; @@ -282,7 +282,7 @@ export class Converter { * @param parameters An array of ts.Node params to be converted * @returns an array of converted ESTreeNode params */ - protected convertParameters( + private convertParameters( parameters: ts.NodeArray ): (es.TSParameterProperty | es.RestElement | es.AssignmentPattern)[] { if (!parameters || !parameters.length) { @@ -304,7 +304,7 @@ export class Converter { * ESTree mostly as-is. The only difference is the addition of a type * property instead of a kind property. Recursively copies all children. */ - protected deeplyCopy(node: ts.Node): any { + private deeplyCopy(node: ts.Node): any { const customType = `TS${SyntaxKind[node.kind]}` as AST_NODE_TYPES; /** * If the "errorOnUnknownASTType" option is set to true, throw an error, @@ -373,7 +373,7 @@ export class Converter { * @param parent * @returns the converted ESTree name object */ - protected convertTypeScriptJSXTagNameToESTreeName( + private convertTypeScriptJSXTagNameToESTreeName( tagName: ts.JsxTagNameExpression, parent: ts.Node ): es.JSXMemberExpression | es.JSXIdentifier { @@ -420,10 +420,9 @@ export class Converter { * @param result * @param modifiers original ts.Nodes from the node.modifiers array * @returns the current result object will be mutated - * @deprecated - * TODO: remove this + * @deprecated This method adds not standardized `modifiers` property in nodes */ - protected applyModifiersToResult( + private applyModifiersToResult( result: es.TSEnumDeclaration | es.TSModuleDeclaration, modifiers?: ts.ModifiersArray ): void { @@ -479,7 +478,7 @@ export class Converter { * @param typeAnnotationParent The node that will have its location data mutated * @param node */ - protected fixTypeAnnotationParentLocation( + private fixTypeAnnotationParentLocation( typeAnnotationParent: es.BaseNode, node: ts.TypeNode ): void { @@ -498,7 +497,7 @@ export class Converter { * @param parent parentNode * @returns the converted ESTree node */ - protected convertNode(node: TSNode, parent: ts.Node): es.Node | null { + private convertNode(node: TSNode, parent: ts.Node): es.Node | null { switch (node.kind) { case SyntaxKind.SourceFile: { return this.createNode(node, { @@ -1999,7 +1998,6 @@ export class Converter { case SyntaxKind.UnknownKeyword: case SyntaxKind.VoidKeyword: case SyntaxKind.UndefinedKeyword: { - // TODO: return this.createNode(node, { type: AST_NODE_TYPES[`TS${SyntaxKind[node.kind]}` as AST_NODE_TYPES] });