2 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3 if (k2 === undefined) k2 = k;
4 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5 }) : (function(o, m, k, k2) {
6 if (k2 === undefined) k2 = k;
9 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10 Object.defineProperty(o, "default", { enumerable: true, value: v });
14 var __importStar = (this && this.__importStar) || function (mod) {
15 if (mod && mod.__esModule) return mod;
17 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18 __setModuleDefault(result, mod);
21 Object.defineProperty(exports, "__esModule", { value: true });
22 exports.Converter = exports.convertError = void 0;
23 // There's lots of funny stuff due to the typing of ts.Node
24 /* eslint-disable @typescript-eslint/no-explicit-any */
25 const ts = __importStar(require("typescript"));
26 const node_utils_1 = require("./node-utils");
27 const ts_estree_1 = require("./ts-estree");
28 const version_check_1 = require("./version-check");
29 const SyntaxKind = ts.SyntaxKind;
31 * Extends and formats a given error object
32 * @param error the error object
33 * @returns converted error object
35 function convertError(error) {
36 return node_utils_1.createError(error.file, error.start, error.message || error.messageText);
38 exports.convertError = convertError;
41 * Converts a TypeScript node into an ESTree node
42 * @param ast the full TypeScript AST
43 * @param options additional options for the conversion
44 * @returns the converted ESTreeNode
46 constructor(ast, options) {
47 this.esTreeNodeToTSNodeMap = new WeakMap();
48 this.tsNodeToESTreeNodeMap = new WeakMap();
49 this.allowPattern = false;
50 this.inTypeMode = false;
52 this.options = Object.assign({}, options);
56 esTreeNodeToTSNodeMap: this.esTreeNodeToTSNodeMap,
57 tsNodeToESTreeNodeMap: this.tsNodeToESTreeNodeMap,
61 return this.converter(this.ast);
64 * Converts a TypeScript node into an ESTree node.
65 * @param node the child ts.Node
66 * @param parent parentNode
67 * @param inTypeMode flag to determine if we are in typeMode
68 * @param allowPattern flag to determine if patterns are allowed
69 * @returns the converted ESTree node
71 converter(node, parent, inTypeMode, allowPattern) {
73 * Exit early for null and undefined
78 const typeMode = this.inTypeMode;
79 const pattern = this.allowPattern;
80 if (inTypeMode !== undefined) {
81 this.inTypeMode = inTypeMode;
83 if (allowPattern !== undefined) {
84 this.allowPattern = allowPattern;
86 const result = this.convertNode(node, (parent !== null && parent !== void 0 ? parent : node.parent));
87 this.registerTSNodeInNodeMap(node, result);
88 this.inTypeMode = typeMode;
89 this.allowPattern = pattern;
93 * Fixes the exports of the given ts.Node
94 * @param node the ts.Node
95 * @param result result
96 * @returns the ESTreeNode with fixed exports
98 fixExports(node, result) {
100 if (node.modifiers && node.modifiers[0].kind === SyntaxKind.ExportKeyword) {
102 * Make sure that original node is registered instead of export
104 this.registerTSNodeInNodeMap(node, result);
105 const exportKeyword = node.modifiers[0];
106 const nextModifier = node.modifiers[1];
107 const declarationIsDefault = nextModifier && nextModifier.kind === SyntaxKind.DefaultKeyword;
108 const varToken = declarationIsDefault
109 ? node_utils_1.findNextToken(nextModifier, this.ast, this.ast)
110 : node_utils_1.findNextToken(exportKeyword, this.ast, this.ast);
111 result.range[0] = varToken.getStart(this.ast);
112 result.loc = node_utils_1.getLocFor(result.range[0], result.range[1], this.ast);
113 if (declarationIsDefault) {
114 return this.createNode(node, {
115 type: ts_estree_1.AST_NODE_TYPES.ExportDefaultDeclaration,
117 range: [exportKeyword.getStart(this.ast), result.range[1]],
122 const isType = result.type === ts_estree_1.AST_NODE_TYPES.TSInterfaceDeclaration ||
123 result.type === ts_estree_1.AST_NODE_TYPES.TSTypeAliasDeclaration;
124 const isDeclare = result.declare === true;
125 return this.createNode(node, {
126 type: ts_estree_1.AST_NODE_TYPES.ExportNamedDeclaration,
130 exportKind: isType || isDeclare ? 'type' : 'value',
131 range: [exportKeyword.getStart(this.ast), result.range[1]],
138 * Register specific TypeScript node into map with first ESTree node provided
140 registerTSNodeInNodeMap(node, result) {
141 if (result && this.options.shouldPreserveNodeMaps) {
142 if (!this.tsNodeToESTreeNodeMap.has(node)) {
143 this.tsNodeToESTreeNodeMap.set(node, result);
148 * Converts a TypeScript node into an ESTree node.
149 * @param child the child ts.Node
150 * @param parent parentNode
151 * @returns the converted ESTree node
153 convertPattern(child, parent) {
154 return this.converter(child, parent, this.inTypeMode, true);
157 * Converts a TypeScript node into an ESTree node.
158 * @param child the child ts.Node
159 * @param parent parentNode
160 * @returns the converted ESTree node
162 convertChild(child, parent) {
163 return this.converter(child, parent, this.inTypeMode, false);
166 * Converts a TypeScript node into an ESTree node.
167 * @param child the child ts.Node
168 * @param parent parentNode
169 * @returns the converted ESTree node
171 convertType(child, parent) {
172 return this.converter(child, parent, true, false);
174 createNode(node, data) {
177 result.range = node_utils_1.getRange(
178 // this is completely valid, but TS hates it
182 result.loc = node_utils_1.getLocFor(result.range[0], result.range[1], this.ast);
184 if (result && this.options.shouldPreserveNodeMaps) {
185 this.esTreeNodeToTSNodeMap.set(result, node);
189 convertBindingNameWithTypeAnnotation(name, tsType, parent) {
190 const id = this.convertPattern(name);
192 id.typeAnnotation = this.convertTypeAnnotation(tsType, parent);
193 this.fixParentLocation(id, id.typeAnnotation.range);
198 * Converts a child into a type annotation. This creates an intermediary
199 * TypeAnnotation node to match what Flow does.
200 * @param child The TypeScript AST node to convert.
201 * @param parent parentNode
202 * @returns The type annotation node.
204 convertTypeAnnotation(child, parent) {
205 // in FunctionType and ConstructorType typeAnnotation has 2 characters `=>` and in other places is just colon
206 const offset = (parent === null || parent === void 0 ? void 0 : parent.kind) === SyntaxKind.FunctionType ||
207 (parent === null || parent === void 0 ? void 0 : parent.kind) === SyntaxKind.ConstructorType
210 const annotationStartCol = child.getFullStart() - offset;
211 const loc = node_utils_1.getLocFor(annotationStartCol, child.end, this.ast);
213 type: ts_estree_1.AST_NODE_TYPES.TSTypeAnnotation,
215 range: [annotationStartCol, child.end],
216 typeAnnotation: this.convertType(child),
220 * Coverts body Nodes and add a directive field to StringLiterals
221 * @param nodes of ts.Node
222 * @param parent parentNode
223 * @returns Array of body statements
225 convertBodyExpressions(nodes, parent) {
226 let allowDirectives = node_utils_1.canContainDirective(parent);
229 const child = this.convertChild(statement);
230 if (allowDirectives) {
231 if ((child === null || child === void 0 ? void 0 : child.expression) &&
232 ts.isExpressionStatement(statement) &&
233 ts.isStringLiteral(statement.expression)) {
234 const raw = child.expression.raw;
235 child.directive = raw.slice(1, -1);
236 return child; // child can be null, but it's filtered below
239 allowDirectives = false;
242 return child; // child can be null, but it's filtered below
244 // filter out unknown nodes for now
245 .filter(statement => statement));
248 * Converts a ts.Node's typeArguments to TSTypeParameterInstantiation node
249 * @param typeArguments ts.NodeArray typeArguments
250 * @param node parent used to create this node
251 * @returns TypeParameterInstantiation node
253 convertTypeArgumentsToTypeParameters(typeArguments, node) {
254 const greaterThanToken = node_utils_1.findNextToken(typeArguments, this.ast, this.ast);
255 return this.createNode(node, {
256 type: ts_estree_1.AST_NODE_TYPES.TSTypeParameterInstantiation,
257 range: [typeArguments.pos - 1, greaterThanToken.end],
258 params: typeArguments.map(typeArgument => this.convertType(typeArgument)),
262 * Converts a ts.Node's typeParameters to TSTypeParameterDeclaration node
263 * @param typeParameters ts.Node typeParameters
264 * @returns TypeParameterDeclaration node
266 convertTSTypeParametersToTypeParametersDeclaration(typeParameters) {
267 const greaterThanToken = node_utils_1.findNextToken(typeParameters, this.ast, this.ast);
269 type: ts_estree_1.AST_NODE_TYPES.TSTypeParameterDeclaration,
270 range: [typeParameters.pos - 1, greaterThanToken.end],
271 loc: node_utils_1.getLocFor(typeParameters.pos - 1, greaterThanToken.end, this.ast),
272 params: typeParameters.map(typeParameter => this.convertType(typeParameter)),
276 * Converts an array of ts.Node parameters into an array of ESTreeNode params
277 * @param parameters An array of ts.Node params to be converted
278 * @returns an array of converted ESTreeNode params
280 convertParameters(parameters) {
281 if (!parameters || !parameters.length) {
284 return parameters.map(param => {
286 const convertedParam = this.convertChild(param);
287 if ((_a = param.decorators) === null || _a === void 0 ? void 0 : _a.length) {
288 convertedParam.decorators = param.decorators.map(el => this.convertChild(el));
290 return convertedParam;
294 * For nodes that are copied directly from the TypeScript AST into
295 * ESTree mostly as-is. The only difference is the addition of a type
296 * property instead of a kind property. Recursively copies all children.
299 if (node.kind === ts.SyntaxKind.JSDocFunctionType) {
300 throw node_utils_1.createError(this.ast, node.pos, 'JSDoc types can only be used inside documentation comments.');
302 const customType = `TS${SyntaxKind[node.kind]}`;
304 * If the "errorOnUnknownASTType" option is set to true, throw an error,
305 * otherwise fallback to just including the unknown type as-is.
307 if (this.options.errorOnUnknownASTType && !ts_estree_1.AST_NODE_TYPES[customType]) {
308 throw new Error(`Unknown AST_NODE_TYPE: "${customType}"`);
310 const result = this.createNode(node, {
313 if ('type' in node) {
314 result.typeAnnotation =
315 node.type && 'kind' in node.type && ts.isTypeNode(node.type)
316 ? this.convertTypeAnnotation(node.type, node)
319 if ('typeArguments' in node) {
320 result.typeParameters =
321 node.typeArguments && 'pos' in node.typeArguments
322 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
325 if ('typeParameters' in node) {
326 result.typeParameters =
327 node.typeParameters && 'pos' in node.typeParameters
328 ? this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters)
331 if ('decorators' in node && node.decorators && node.decorators.length) {
332 result.decorators = node.decorators.map(el => this.convertChild(el));
335 .filter(([key]) => !/^(?:_children|kind|parent|pos|end|flags|modifierFlagsCache|jsDoc|type|typeArguments|typeParameters|decorators)$/.test(key))
336 .forEach(([key, value]) => {
337 if (Array.isArray(value)) {
338 result[key] = value.map(el => this.convertChild(el));
340 else if (value && typeof value === 'object' && value.kind) {
341 // need to check node[key].kind to ensure we don't try to convert a symbol
342 result[key] = this.convertChild(value);
351 * Converts a TypeScript JSX node.tagName into an ESTree node.name
352 * @param node the tagName object from a JSX ts.Node
354 * @returns the converted ESTree name object
356 convertJSXTagName(node, parent) {
359 case SyntaxKind.PropertyAccessExpression:
360 if (node.name.kind === SyntaxKind.PrivateIdentifier) {
361 // This is one of the few times where TS explicitly errors, and doesn't even gracefully handle the syntax.
362 // So we shouldn't ever get into this state to begin with.
363 throw new Error('Non-private identifier expected.');
365 result = this.createNode(node, {
366 type: ts_estree_1.AST_NODE_TYPES.JSXMemberExpression,
367 object: this.convertJSXTagName(node.expression, parent),
368 property: this.convertJSXTagName(node.name, parent),
371 case SyntaxKind.ThisKeyword:
372 result = this.createNode(node, {
373 type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
377 case SyntaxKind.Identifier:
379 result = this.createNode(node, {
380 type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
385 this.registerTSNodeInNodeMap(node, result);
389 * Applies the given TS modifiers to the given result object.
391 * @param modifiers original ts.Nodes from the node.modifiers array
392 * @returns the current result object will be mutated
393 * @deprecated This method adds not standardized `modifiers` property in nodes
395 applyModifiersToResult(result, modifiers) {
396 if (!modifiers || !modifiers.length) {
400 * Some modifiers are explicitly handled by applying them as
401 * boolean values on the result node. As well as adding them
402 * to the result, we remove them from the array, so that they
403 * are not handled twice.
405 const handledModifierIndices = {};
406 for (let i = 0; i < modifiers.length; i++) {
407 const modifier = modifiers[i];
408 switch (modifier.kind) {
410 * Ignore ExportKeyword and DefaultKeyword, they are handled
411 * via the fixExports utility function
413 case SyntaxKind.ExportKeyword:
414 case SyntaxKind.DefaultKeyword:
415 handledModifierIndices[i] = true;
417 case SyntaxKind.ConstKeyword:
419 handledModifierIndices[i] = true;
421 case SyntaxKind.DeclareKeyword:
422 result.declare = true;
423 handledModifierIndices[i] = true;
429 * If there are still valid modifiers available which have
430 * not been explicitly handled above, we just convert and
431 * add the modifiers array to the result node.
433 const remainingModifiers = modifiers.filter((_, i) => !handledModifierIndices[i]);
434 if (!remainingModifiers || !remainingModifiers.length) {
437 result.modifiers = remainingModifiers.map(el => this.convertChild(el));
440 * Uses the provided range location to adjust the location data of the given Node
441 * @param result The node that will have its location data mutated
442 * @param childRange The child node range used to expand location
444 fixParentLocation(result, childRange) {
445 if (childRange[0] < result.range[0]) {
446 result.range[0] = childRange[0];
447 result.loc.start = node_utils_1.getLineAndCharacterFor(result.range[0], this.ast);
449 if (childRange[1] > result.range[1]) {
450 result.range[1] = childRange[1];
451 result.loc.end = node_utils_1.getLineAndCharacterFor(result.range[1], this.ast);
455 * Converts a TypeScript node into an ESTree node.
456 * The core of the conversion logic:
457 * Identify and convert each relevant TypeScript SyntaxKind
458 * @param node the child ts.Node
459 * @param parent parentNode
460 * @returns the converted ESTree node
462 convertNode(node, parent) {
463 var _a, _b, _c, _d, _e, _f, _g, _h, _j;
465 case SyntaxKind.SourceFile: {
466 return this.createNode(node, {
467 type: ts_estree_1.AST_NODE_TYPES.Program,
468 body: this.convertBodyExpressions(node.statements, node),
469 sourceType: node.externalModuleIndicator ? 'module' : 'script',
470 range: [node.getStart(this.ast), node.endOfFileToken.end],
473 case SyntaxKind.Block: {
474 return this.createNode(node, {
475 type: ts_estree_1.AST_NODE_TYPES.BlockStatement,
476 body: this.convertBodyExpressions(node.statements, node),
479 case SyntaxKind.Identifier: {
480 return this.createNode(node, {
481 type: ts_estree_1.AST_NODE_TYPES.Identifier,
485 case SyntaxKind.WithStatement:
486 return this.createNode(node, {
487 type: ts_estree_1.AST_NODE_TYPES.WithStatement,
488 object: this.convertChild(node.expression),
489 body: this.convertChild(node.statement),
492 case SyntaxKind.ReturnStatement:
493 return this.createNode(node, {
494 type: ts_estree_1.AST_NODE_TYPES.ReturnStatement,
495 argument: this.convertChild(node.expression),
497 case SyntaxKind.LabeledStatement:
498 return this.createNode(node, {
499 type: ts_estree_1.AST_NODE_TYPES.LabeledStatement,
500 label: this.convertChild(node.label),
501 body: this.convertChild(node.statement),
503 case SyntaxKind.ContinueStatement:
504 return this.createNode(node, {
505 type: ts_estree_1.AST_NODE_TYPES.ContinueStatement,
506 label: this.convertChild(node.label),
508 case SyntaxKind.BreakStatement:
509 return this.createNode(node, {
510 type: ts_estree_1.AST_NODE_TYPES.BreakStatement,
511 label: this.convertChild(node.label),
514 case SyntaxKind.IfStatement:
515 return this.createNode(node, {
516 type: ts_estree_1.AST_NODE_TYPES.IfStatement,
517 test: this.convertChild(node.expression),
518 consequent: this.convertChild(node.thenStatement),
519 alternate: this.convertChild(node.elseStatement),
521 case SyntaxKind.SwitchStatement:
522 return this.createNode(node, {
523 type: ts_estree_1.AST_NODE_TYPES.SwitchStatement,
524 discriminant: this.convertChild(node.expression),
525 cases: node.caseBlock.clauses.map(el => this.convertChild(el)),
527 case SyntaxKind.CaseClause:
528 case SyntaxKind.DefaultClause:
529 return this.createNode(node, {
530 type: ts_estree_1.AST_NODE_TYPES.SwitchCase,
531 // expression is present in case only
532 test: node.kind === SyntaxKind.CaseClause
533 ? this.convertChild(node.expression)
535 consequent: node.statements.map(el => this.convertChild(el)),
538 case SyntaxKind.ThrowStatement:
539 return this.createNode(node, {
540 type: ts_estree_1.AST_NODE_TYPES.ThrowStatement,
541 argument: this.convertChild(node.expression),
543 case SyntaxKind.TryStatement:
544 return this.createNode(node, {
545 type: ts_estree_1.AST_NODE_TYPES.TryStatement,
546 block: this.convertChild(node.tryBlock),
547 handler: this.convertChild(node.catchClause),
548 finalizer: this.convertChild(node.finallyBlock),
550 case SyntaxKind.CatchClause:
551 return this.createNode(node, {
552 type: ts_estree_1.AST_NODE_TYPES.CatchClause,
553 param: node.variableDeclaration
554 ? this.convertBindingNameWithTypeAnnotation(node.variableDeclaration.name, node.variableDeclaration.type)
556 body: this.convertChild(node.block),
559 case SyntaxKind.WhileStatement:
560 return this.createNode(node, {
561 type: ts_estree_1.AST_NODE_TYPES.WhileStatement,
562 test: this.convertChild(node.expression),
563 body: this.convertChild(node.statement),
566 * Unlike other parsers, TypeScript calls a "DoWhileStatement"
569 case SyntaxKind.DoStatement:
570 return this.createNode(node, {
571 type: ts_estree_1.AST_NODE_TYPES.DoWhileStatement,
572 test: this.convertChild(node.expression),
573 body: this.convertChild(node.statement),
575 case SyntaxKind.ForStatement:
576 return this.createNode(node, {
577 type: ts_estree_1.AST_NODE_TYPES.ForStatement,
578 init: this.convertChild(node.initializer),
579 test: this.convertChild(node.condition),
580 update: this.convertChild(node.incrementor),
581 body: this.convertChild(node.statement),
583 case SyntaxKind.ForInStatement:
584 return this.createNode(node, {
585 type: ts_estree_1.AST_NODE_TYPES.ForInStatement,
586 left: this.convertPattern(node.initializer),
587 right: this.convertChild(node.expression),
588 body: this.convertChild(node.statement),
590 case SyntaxKind.ForOfStatement:
591 return this.createNode(node, {
592 type: ts_estree_1.AST_NODE_TYPES.ForOfStatement,
593 left: this.convertPattern(node.initializer),
594 right: this.convertChild(node.expression),
595 body: this.convertChild(node.statement),
596 await: Boolean(node.awaitModifier &&
597 node.awaitModifier.kind === SyntaxKind.AwaitKeyword),
600 case SyntaxKind.FunctionDeclaration: {
601 const isDeclare = node_utils_1.hasModifier(SyntaxKind.DeclareKeyword, node);
602 const result = this.createNode(node, {
603 type: isDeclare || !node.body
604 ? ts_estree_1.AST_NODE_TYPES.TSDeclareFunction
605 : ts_estree_1.AST_NODE_TYPES.FunctionDeclaration,
606 id: this.convertChild(node.name),
607 generator: !!node.asteriskToken,
609 async: node_utils_1.hasModifier(SyntaxKind.AsyncKeyword, node),
610 params: this.convertParameters(node.parameters),
611 body: this.convertChild(node.body) || undefined,
613 // Process returnType
615 result.returnType = this.convertTypeAnnotation(node.type, node);
618 result.declare = true;
620 // Process typeParameters
621 if (node.typeParameters) {
622 result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
625 * Semantically, decorators are not allowed on function declarations,
626 * but the TypeScript compiler will parse them and produce a valid AST,
627 * so we handle them here too.
629 if (node.decorators) {
630 result.decorators = node.decorators.map(el => this.convertChild(el));
633 return this.fixExports(node, result);
635 case SyntaxKind.VariableDeclaration: {
636 const result = this.createNode(node, {
637 type: ts_estree_1.AST_NODE_TYPES.VariableDeclarator,
638 id: this.convertBindingNameWithTypeAnnotation(node.name, node.type, node),
639 init: this.convertChild(node.initializer),
641 if (node.exclamationToken) {
642 result.definite = true;
646 case SyntaxKind.VariableStatement: {
647 const result = this.createNode(node, {
648 type: ts_estree_1.AST_NODE_TYPES.VariableDeclaration,
649 declarations: node.declarationList.declarations.map(el => this.convertChild(el)),
650 kind: node_utils_1.getDeclarationKind(node.declarationList),
653 * Semantically, decorators are not allowed on variable declarations,
654 * but the TypeScript compiler will parse them and produce a valid AST,
655 * so we handle them here too.
657 if (node.decorators) {
658 result.decorators = node.decorators.map(el => this.convertChild(el));
660 if (node_utils_1.hasModifier(SyntaxKind.DeclareKeyword, node)) {
661 result.declare = true;
664 return this.fixExports(node, result);
666 // mostly for for-of, for-in
667 case SyntaxKind.VariableDeclarationList:
668 return this.createNode(node, {
669 type: ts_estree_1.AST_NODE_TYPES.VariableDeclaration,
670 declarations: node.declarations.map(el => this.convertChild(el)),
671 kind: node_utils_1.getDeclarationKind(node),
674 case SyntaxKind.ExpressionStatement:
675 return this.createNode(node, {
676 type: ts_estree_1.AST_NODE_TYPES.ExpressionStatement,
677 expression: this.convertChild(node.expression),
679 case SyntaxKind.ThisKeyword:
680 return this.createNode(node, {
681 type: ts_estree_1.AST_NODE_TYPES.ThisExpression,
683 case SyntaxKind.ArrayLiteralExpression: {
684 // TypeScript uses ArrayLiteralExpression in destructuring assignment, too
685 if (this.allowPattern) {
686 return this.createNode(node, {
687 type: ts_estree_1.AST_NODE_TYPES.ArrayPattern,
688 elements: node.elements.map(el => this.convertPattern(el)),
692 return this.createNode(node, {
693 type: ts_estree_1.AST_NODE_TYPES.ArrayExpression,
694 elements: node.elements.map(el => this.convertChild(el)),
698 case SyntaxKind.ObjectLiteralExpression: {
699 // TypeScript uses ObjectLiteralExpression in destructuring assignment, too
700 if (this.allowPattern) {
701 return this.createNode(node, {
702 type: ts_estree_1.AST_NODE_TYPES.ObjectPattern,
703 properties: node.properties.map(el => this.convertPattern(el)),
707 return this.createNode(node, {
708 type: ts_estree_1.AST_NODE_TYPES.ObjectExpression,
709 properties: node.properties.map(el => this.convertChild(el)),
713 case SyntaxKind.PropertyAssignment:
714 return this.createNode(node, {
715 type: ts_estree_1.AST_NODE_TYPES.Property,
716 key: this.convertChild(node.name),
717 value: this.converter(node.initializer, node, this.inTypeMode, this.allowPattern),
718 computed: node_utils_1.isComputedProperty(node.name),
723 case SyntaxKind.ShorthandPropertyAssignment: {
724 if (node.objectAssignmentInitializer) {
725 return this.createNode(node, {
726 type: ts_estree_1.AST_NODE_TYPES.Property,
727 key: this.convertChild(node.name),
728 value: this.createNode(node, {
729 type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
730 left: this.convertPattern(node.name),
731 right: this.convertChild(node.objectAssignmentInitializer),
740 return this.createNode(node, {
741 type: ts_estree_1.AST_NODE_TYPES.Property,
742 key: this.convertChild(node.name),
743 value: this.convertChild(node.name),
751 case SyntaxKind.ComputedPropertyName:
752 return this.convertChild(node.expression);
753 case SyntaxKind.PropertyDeclaration: {
754 const isAbstract = node_utils_1.hasModifier(SyntaxKind.AbstractKeyword, node);
755 const result = this.createNode(node, {
757 ? ts_estree_1.AST_NODE_TYPES.TSAbstractClassProperty
758 : ts_estree_1.AST_NODE_TYPES.ClassProperty,
759 key: this.convertChild(node.name),
760 value: this.convertChild(node.initializer),
761 computed: node_utils_1.isComputedProperty(node.name),
762 static: node_utils_1.hasModifier(SyntaxKind.StaticKeyword, node),
763 readonly: node_utils_1.hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined,
764 declare: node_utils_1.hasModifier(SyntaxKind.DeclareKeyword, node),
767 result.typeAnnotation = this.convertTypeAnnotation(node.type, node);
769 if (node.decorators) {
770 result.decorators = node.decorators.map(el => this.convertChild(el));
772 const accessibility = node_utils_1.getTSNodeAccessibility(node);
774 result.accessibility = accessibility;
776 if ((node.name.kind === SyntaxKind.Identifier ||
777 node.name.kind === SyntaxKind.ComputedPropertyName) &&
778 node.questionToken) {
779 result.optional = true;
781 if (node.exclamationToken) {
782 result.definite = true;
784 if (result.key.type === ts_estree_1.AST_NODE_TYPES.Literal && node.questionToken) {
785 result.optional = true;
789 case SyntaxKind.GetAccessor:
790 case SyntaxKind.SetAccessor:
791 case SyntaxKind.MethodDeclaration: {
792 const method = this.createNode(node, {
794 ? ts_estree_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression
795 : ts_estree_1.AST_NODE_TYPES.FunctionExpression,
797 generator: !!node.asteriskToken,
799 async: node_utils_1.hasModifier(SyntaxKind.AsyncKeyword, node),
800 body: this.convertChild(node.body),
801 range: [node.parameters.pos - 1, node.end],
805 method.returnType = this.convertTypeAnnotation(node.type, node);
807 // Process typeParameters
808 if (node.typeParameters) {
809 method.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
810 this.fixParentLocation(method, method.typeParameters.range);
813 if (parent.kind === SyntaxKind.ObjectLiteralExpression) {
814 method.params = node.parameters.map(el => this.convertChild(el));
815 result = this.createNode(node, {
816 type: ts_estree_1.AST_NODE_TYPES.Property,
817 key: this.convertChild(node.name),
819 computed: node_utils_1.isComputedProperty(node.name),
820 method: node.kind === SyntaxKind.MethodDeclaration,
828 * Unlike in object literal methods, class method params can have decorators
830 method.params = this.convertParameters(node.parameters);
832 * TypeScript class methods can be defined as "abstract"
834 const methodDefinitionType = node_utils_1.hasModifier(SyntaxKind.AbstractKeyword, node)
835 ? ts_estree_1.AST_NODE_TYPES.TSAbstractMethodDefinition
836 : ts_estree_1.AST_NODE_TYPES.MethodDefinition;
837 result = this.createNode(node, {
838 type: methodDefinitionType,
839 key: this.convertChild(node.name),
841 computed: node_utils_1.isComputedProperty(node.name),
842 static: node_utils_1.hasModifier(SyntaxKind.StaticKeyword, node),
845 if (node.decorators) {
846 result.decorators = node.decorators.map(el => this.convertChild(el));
848 const accessibility = node_utils_1.getTSNodeAccessibility(node);
850 result.accessibility = accessibility;
853 if (node.questionToken) {
854 result.optional = true;
856 if (node.kind === SyntaxKind.GetAccessor) {
859 else if (node.kind === SyntaxKind.SetAccessor) {
862 else if (!result.static &&
863 node.name.kind === SyntaxKind.StringLiteral &&
864 node.name.text === 'constructor' &&
865 result.type !== ts_estree_1.AST_NODE_TYPES.Property) {
866 result.kind = 'constructor';
870 // TypeScript uses this even for static methods named "constructor"
871 case SyntaxKind.Constructor: {
872 const lastModifier = node_utils_1.getLastModifier(node);
873 const constructorToken = (lastModifier && node_utils_1.findNextToken(lastModifier, node, this.ast)) ||
874 node.getFirstToken();
875 const constructor = this.createNode(node, {
877 ? ts_estree_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression
878 : ts_estree_1.AST_NODE_TYPES.FunctionExpression,
880 params: this.convertParameters(node.parameters),
884 body: this.convertChild(node.body),
885 range: [node.parameters.pos - 1, node.end],
887 // Process typeParameters
888 if (node.typeParameters) {
889 constructor.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
890 this.fixParentLocation(constructor, constructor.typeParameters.range);
892 // Process returnType
894 constructor.returnType = this.convertTypeAnnotation(node.type, node);
896 const constructorKey = this.createNode(node, {
897 type: ts_estree_1.AST_NODE_TYPES.Identifier,
899 range: [constructorToken.getStart(this.ast), constructorToken.end],
901 const isStatic = node_utils_1.hasModifier(SyntaxKind.StaticKeyword, node);
902 const result = this.createNode(node, {
903 type: node_utils_1.hasModifier(SyntaxKind.AbstractKeyword, node)
904 ? ts_estree_1.AST_NODE_TYPES.TSAbstractMethodDefinition
905 : ts_estree_1.AST_NODE_TYPES.MethodDefinition,
910 kind: isStatic ? 'method' : 'constructor',
912 const accessibility = node_utils_1.getTSNodeAccessibility(node);
914 result.accessibility = accessibility;
918 case SyntaxKind.FunctionExpression: {
919 const result = this.createNode(node, {
920 type: ts_estree_1.AST_NODE_TYPES.FunctionExpression,
921 id: this.convertChild(node.name),
922 generator: !!node.asteriskToken,
923 params: this.convertParameters(node.parameters),
924 body: this.convertChild(node.body),
925 async: node_utils_1.hasModifier(SyntaxKind.AsyncKeyword, node),
928 // Process returnType
930 result.returnType = this.convertTypeAnnotation(node.type, node);
932 // Process typeParameters
933 if (node.typeParameters) {
934 result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
938 case SyntaxKind.SuperKeyword:
939 return this.createNode(node, {
940 type: ts_estree_1.AST_NODE_TYPES.Super,
942 case SyntaxKind.ArrayBindingPattern:
943 return this.createNode(node, {
944 type: ts_estree_1.AST_NODE_TYPES.ArrayPattern,
945 elements: node.elements.map(el => this.convertPattern(el)),
947 // occurs with missing array elements like [,]
948 case SyntaxKind.OmittedExpression:
950 case SyntaxKind.ObjectBindingPattern:
951 return this.createNode(node, {
952 type: ts_estree_1.AST_NODE_TYPES.ObjectPattern,
953 properties: node.elements.map(el => this.convertPattern(el)),
955 case SyntaxKind.BindingElement: {
956 if (parent.kind === SyntaxKind.ArrayBindingPattern) {
957 const arrayItem = this.convertChild(node.name, parent);
958 if (node.initializer) {
959 return this.createNode(node, {
960 type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
962 right: this.convertChild(node.initializer),
965 else if (node.dotDotDotToken) {
966 return this.createNode(node, {
967 type: ts_estree_1.AST_NODE_TYPES.RestElement,
977 if (node.dotDotDotToken) {
978 result = this.createNode(node, {
979 type: ts_estree_1.AST_NODE_TYPES.RestElement,
980 argument: this.convertChild((_a = node.propertyName) !== null && _a !== void 0 ? _a : node.name),
984 result = this.createNode(node, {
985 type: ts_estree_1.AST_NODE_TYPES.Property,
986 key: this.convertChild((_b = node.propertyName) !== null && _b !== void 0 ? _b : node.name),
987 value: this.convertChild(node.name),
988 computed: Boolean(node.propertyName &&
989 node.propertyName.kind === SyntaxKind.ComputedPropertyName),
991 shorthand: !node.propertyName,
995 if (node.initializer) {
996 result.value = this.createNode(node, {
997 type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
998 left: this.convertChild(node.name),
999 right: this.convertChild(node.initializer),
1000 range: [node.name.getStart(this.ast), node.initializer.end],
1006 case SyntaxKind.ArrowFunction: {
1007 const result = this.createNode(node, {
1008 type: ts_estree_1.AST_NODE_TYPES.ArrowFunctionExpression,
1011 params: this.convertParameters(node.parameters),
1012 body: this.convertChild(node.body),
1013 async: node_utils_1.hasModifier(SyntaxKind.AsyncKeyword, node),
1014 expression: node.body.kind !== SyntaxKind.Block,
1016 // Process returnType
1018 result.returnType = this.convertTypeAnnotation(node.type, node);
1020 // Process typeParameters
1021 if (node.typeParameters) {
1022 result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1026 case SyntaxKind.YieldExpression:
1027 return this.createNode(node, {
1028 type: ts_estree_1.AST_NODE_TYPES.YieldExpression,
1029 delegate: !!node.asteriskToken,
1030 argument: this.convertChild(node.expression),
1032 case SyntaxKind.AwaitExpression:
1033 return this.createNode(node, {
1034 type: ts_estree_1.AST_NODE_TYPES.AwaitExpression,
1035 argument: this.convertChild(node.expression),
1037 // Template Literals
1038 case SyntaxKind.NoSubstitutionTemplateLiteral:
1039 return this.createNode(node, {
1040 type: ts_estree_1.AST_NODE_TYPES.TemplateLiteral,
1042 this.createNode(node, {
1043 type: ts_estree_1.AST_NODE_TYPES.TemplateElement,
1045 raw: this.ast.text.slice(node.getStart(this.ast) + 1, node.end - 1),
1053 case SyntaxKind.TemplateExpression: {
1054 const result = this.createNode(node, {
1055 type: ts_estree_1.AST_NODE_TYPES.TemplateLiteral,
1056 quasis: [this.convertChild(node.head)],
1059 node.templateSpans.forEach(templateSpan => {
1060 result.expressions.push(this.convertChild(templateSpan.expression));
1061 result.quasis.push(this.convertChild(templateSpan.literal));
1065 case SyntaxKind.TaggedTemplateExpression:
1066 return this.createNode(node, {
1067 type: ts_estree_1.AST_NODE_TYPES.TaggedTemplateExpression,
1068 typeParameters: node.typeArguments
1069 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
1071 tag: this.convertChild(node.tag),
1072 quasi: this.convertChild(node.template),
1074 case SyntaxKind.TemplateHead:
1075 case SyntaxKind.TemplateMiddle:
1076 case SyntaxKind.TemplateTail: {
1077 const tail = node.kind === SyntaxKind.TemplateTail;
1078 return this.createNode(node, {
1079 type: ts_estree_1.AST_NODE_TYPES.TemplateElement,
1081 raw: this.ast.text.slice(node.getStart(this.ast) + 1, node.end - (tail ? 1 : 2)),
1088 case SyntaxKind.SpreadAssignment:
1089 case SyntaxKind.SpreadElement: {
1090 if (this.allowPattern) {
1091 return this.createNode(node, {
1092 type: ts_estree_1.AST_NODE_TYPES.RestElement,
1093 argument: this.convertPattern(node.expression),
1097 return this.createNode(node, {
1098 type: ts_estree_1.AST_NODE_TYPES.SpreadElement,
1099 argument: this.convertChild(node.expression),
1103 case SyntaxKind.Parameter: {
1106 if (node.dotDotDotToken) {
1107 parameter = result = this.createNode(node, {
1108 type: ts_estree_1.AST_NODE_TYPES.RestElement,
1109 argument: this.convertChild(node.name),
1112 else if (node.initializer) {
1113 parameter = this.convertChild(node.name);
1114 result = this.createNode(node, {
1115 type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
1117 right: this.convertChild(node.initializer),
1119 if (node.modifiers) {
1120 // AssignmentPattern should not contain modifiers in range
1121 result.range[0] = parameter.range[0];
1122 result.loc = node_utils_1.getLocFor(result.range[0], result.range[1], this.ast);
1126 parameter = result = this.convertChild(node.name, parent);
1129 parameter.typeAnnotation = this.convertTypeAnnotation(node.type, node);
1130 this.fixParentLocation(parameter, parameter.typeAnnotation.range);
1132 if (node.questionToken) {
1133 if (node.questionToken.end > parameter.range[1]) {
1134 parameter.range[1] = node.questionToken.end;
1135 parameter.loc.end = node_utils_1.getLineAndCharacterFor(parameter.range[1], this.ast);
1137 parameter.optional = true;
1139 if (node.modifiers) {
1140 return this.createNode(node, {
1141 type: ts_estree_1.AST_NODE_TYPES.TSParameterProperty,
1142 accessibility: (_c = node_utils_1.getTSNodeAccessibility(node)) !== null && _c !== void 0 ? _c : undefined,
1143 readonly: node_utils_1.hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined,
1144 static: node_utils_1.hasModifier(SyntaxKind.StaticKeyword, node) || undefined,
1145 export: node_utils_1.hasModifier(SyntaxKind.ExportKeyword, node) || undefined,
1152 case SyntaxKind.ClassDeclaration:
1153 case SyntaxKind.ClassExpression: {
1154 const heritageClauses = (_d = node.heritageClauses) !== null && _d !== void 0 ? _d : [];
1155 const classNodeType = node.kind === SyntaxKind.ClassDeclaration
1156 ? ts_estree_1.AST_NODE_TYPES.ClassDeclaration
1157 : ts_estree_1.AST_NODE_TYPES.ClassExpression;
1158 const superClass = heritageClauses.find(clause => clause.token === SyntaxKind.ExtendsKeyword);
1159 const implementsClause = heritageClauses.find(clause => clause.token === SyntaxKind.ImplementsKeyword);
1160 const result = this.createNode(node, {
1161 type: classNodeType,
1162 id: this.convertChild(node.name),
1163 body: this.createNode(node, {
1164 type: ts_estree_1.AST_NODE_TYPES.ClassBody,
1166 range: [node.members.pos - 1, node.end],
1168 superClass: (superClass === null || superClass === void 0 ? void 0 : superClass.types[0]) ? this.convertChild(superClass.types[0].expression)
1172 if (superClass.types.length > 1) {
1173 throw node_utils_1.createError(this.ast, superClass.types[1].pos, 'Classes can only extend a single class.');
1175 if ((_e = superClass.types[0]) === null || _e === void 0 ? void 0 : _e.typeArguments) {
1176 result.superTypeParameters = this.convertTypeArgumentsToTypeParameters(superClass.types[0].typeArguments, superClass.types[0]);
1179 if (node.typeParameters) {
1180 result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1182 if (implementsClause) {
1183 result.implements = implementsClause.types.map(el => this.convertChild(el));
1186 * TypeScript class declarations can be defined as "abstract"
1188 if (node_utils_1.hasModifier(SyntaxKind.AbstractKeyword, node)) {
1189 result.abstract = true;
1191 if (node_utils_1.hasModifier(SyntaxKind.DeclareKeyword, node)) {
1192 result.declare = true;
1194 if (node.decorators) {
1195 result.decorators = node.decorators.map(el => this.convertChild(el));
1197 const filteredMembers = node.members.filter(node_utils_1.isESTreeClassMember);
1198 if (filteredMembers.length) {
1199 result.body.body = filteredMembers.map(el => this.convertChild(el));
1201 // check for exports
1202 return this.fixExports(node, result);
1205 case SyntaxKind.ModuleBlock:
1206 return this.createNode(node, {
1207 type: ts_estree_1.AST_NODE_TYPES.TSModuleBlock,
1208 body: this.convertBodyExpressions(node.statements, node),
1210 case SyntaxKind.ImportDeclaration: {
1211 const result = this.createNode(node, {
1212 type: ts_estree_1.AST_NODE_TYPES.ImportDeclaration,
1213 source: this.convertChild(node.moduleSpecifier),
1215 importKind: 'value',
1217 if (node.importClause) {
1218 if (node.importClause.isTypeOnly) {
1219 result.importKind = 'type';
1221 if (node.importClause.name) {
1222 result.specifiers.push(this.convertChild(node.importClause));
1224 if (node.importClause.namedBindings) {
1225 switch (node.importClause.namedBindings.kind) {
1226 case SyntaxKind.NamespaceImport:
1227 result.specifiers.push(this.convertChild(node.importClause.namedBindings));
1229 case SyntaxKind.NamedImports:
1230 result.specifiers = result.specifiers.concat(node.importClause.namedBindings.elements.map(el => this.convertChild(el)));
1237 case SyntaxKind.NamespaceImport:
1238 return this.createNode(node, {
1239 type: ts_estree_1.AST_NODE_TYPES.ImportNamespaceSpecifier,
1240 local: this.convertChild(node.name),
1242 case SyntaxKind.ImportSpecifier:
1243 return this.createNode(node, {
1244 type: ts_estree_1.AST_NODE_TYPES.ImportSpecifier,
1245 local: this.convertChild(node.name),
1246 imported: this.convertChild((_f = node.propertyName) !== null && _f !== void 0 ? _f : node.name),
1248 case SyntaxKind.ImportClause: {
1249 const local = this.convertChild(node.name);
1250 return this.createNode(node, {
1251 type: ts_estree_1.AST_NODE_TYPES.ImportDefaultSpecifier,
1256 case SyntaxKind.ExportDeclaration:
1257 if (((_g = node.exportClause) === null || _g === void 0 ? void 0 : _g.kind) === SyntaxKind.NamedExports) {
1258 return this.createNode(node, {
1259 type: ts_estree_1.AST_NODE_TYPES.ExportNamedDeclaration,
1260 source: this.convertChild(node.moduleSpecifier),
1261 specifiers: node.exportClause.elements.map(el => this.convertChild(el)),
1262 exportKind: node.isTypeOnly ? 'type' : 'value',
1267 return this.createNode(node, {
1268 type: ts_estree_1.AST_NODE_TYPES.ExportAllDeclaration,
1269 source: this.convertChild(node.moduleSpecifier),
1270 exportKind: node.isTypeOnly ? 'type' : 'value',
1272 // note - for compat with 3.7.x, where node.exportClause is always undefined and
1273 // SyntaxKind.NamespaceExport does not exist yet (i.e. is undefined), this
1274 // cannot be shortened to an optional chain, or else you end up with
1275 // undefined === undefined, and the true path will hard error at runtime
1276 node.exportClause &&
1277 node.exportClause.kind === SyntaxKind.NamespaceExport
1278 ? this.convertChild(node.exportClause.name)
1282 case SyntaxKind.ExportSpecifier:
1283 return this.createNode(node, {
1284 type: ts_estree_1.AST_NODE_TYPES.ExportSpecifier,
1285 local: this.convertChild((_h = node.propertyName) !== null && _h !== void 0 ? _h : node.name),
1286 exported: this.convertChild(node.name),
1288 case SyntaxKind.ExportAssignment:
1289 if (node.isExportEquals) {
1290 return this.createNode(node, {
1291 type: ts_estree_1.AST_NODE_TYPES.TSExportAssignment,
1292 expression: this.convertChild(node.expression),
1296 return this.createNode(node, {
1297 type: ts_estree_1.AST_NODE_TYPES.ExportDefaultDeclaration,
1298 declaration: this.convertChild(node.expression),
1299 exportKind: 'value',
1303 case SyntaxKind.PrefixUnaryExpression:
1304 case SyntaxKind.PostfixUnaryExpression: {
1305 const operator = node_utils_1.getTextForTokenKind(node.operator);
1307 * ESTree uses UpdateExpression for ++/--
1309 if (operator === '++' || operator === '--') {
1310 return this.createNode(node, {
1311 type: ts_estree_1.AST_NODE_TYPES.UpdateExpression,
1313 prefix: node.kind === SyntaxKind.PrefixUnaryExpression,
1314 argument: this.convertChild(node.operand),
1318 return this.createNode(node, {
1319 type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1321 prefix: node.kind === SyntaxKind.PrefixUnaryExpression,
1322 argument: this.convertChild(node.operand),
1326 case SyntaxKind.DeleteExpression:
1327 return this.createNode(node, {
1328 type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1331 argument: this.convertChild(node.expression),
1333 case SyntaxKind.VoidExpression:
1334 return this.createNode(node, {
1335 type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1338 argument: this.convertChild(node.expression),
1340 case SyntaxKind.TypeOfExpression:
1341 return this.createNode(node, {
1342 type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1345 argument: this.convertChild(node.expression),
1347 case SyntaxKind.TypeOperator:
1348 return this.createNode(node, {
1349 type: ts_estree_1.AST_NODE_TYPES.TSTypeOperator,
1350 operator: node_utils_1.getTextForTokenKind(node.operator),
1351 typeAnnotation: this.convertChild(node.type),
1353 // Binary Operations
1354 case SyntaxKind.BinaryExpression: {
1355 // TypeScript uses BinaryExpression for sequences as well
1356 if (node_utils_1.isComma(node.operatorToken)) {
1357 const result = this.createNode(node, {
1358 type: ts_estree_1.AST_NODE_TYPES.SequenceExpression,
1361 const left = this.convertChild(node.left);
1362 if (left.type === ts_estree_1.AST_NODE_TYPES.SequenceExpression &&
1363 node.left.kind !== SyntaxKind.ParenthesizedExpression) {
1364 result.expressions = result.expressions.concat(left.expressions);
1367 result.expressions.push(left);
1369 result.expressions.push(this.convertChild(node.right));
1373 const type = node_utils_1.getBinaryExpressionType(node.operatorToken);
1374 if (this.allowPattern &&
1375 type === ts_estree_1.AST_NODE_TYPES.AssignmentExpression) {
1376 return this.createNode(node, {
1377 type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
1378 left: this.convertPattern(node.left, node),
1379 right: this.convertChild(node.right),
1382 return this.createNode(node, {
1384 operator: node_utils_1.getTextForTokenKind(node.operatorToken.kind),
1385 left: this.converter(node.left, node, this.inTypeMode, type === ts_estree_1.AST_NODE_TYPES.AssignmentExpression),
1386 right: this.convertChild(node.right),
1390 case SyntaxKind.PropertyAccessExpression: {
1391 const object = this.convertChild(node.expression);
1392 const property = this.convertChild(node.name);
1393 const computed = false;
1394 const isLocallyOptional = node.questionDotToken !== undefined;
1395 // the optional expression should propagate up the member expression tree
1396 const isChildOptional = node_utils_1.isChildOptionalChain(node, object);
1397 if (isLocallyOptional || isChildOptional) {
1398 return this.createNode(node, {
1399 type: ts_estree_1.AST_NODE_TYPES.OptionalMemberExpression,
1403 optional: isLocallyOptional,
1407 return this.createNode(node, {
1408 type: ts_estree_1.AST_NODE_TYPES.MemberExpression,
1416 case SyntaxKind.ElementAccessExpression: {
1417 const object = this.convertChild(node.expression);
1418 const property = this.convertChild(node.argumentExpression);
1419 const computed = true;
1420 const isLocallyOptional = node.questionDotToken !== undefined;
1421 // the optional expression should propagate up the member expression tree
1422 const isChildOptional = node_utils_1.isChildOptionalChain(node, object);
1423 if (isLocallyOptional || isChildOptional) {
1424 return this.createNode(node, {
1425 type: ts_estree_1.AST_NODE_TYPES.OptionalMemberExpression,
1429 optional: isLocallyOptional,
1433 return this.createNode(node, {
1434 type: ts_estree_1.AST_NODE_TYPES.MemberExpression,
1442 case SyntaxKind.CallExpression: {
1443 if (node.expression.kind === SyntaxKind.ImportKeyword) {
1444 if (node.arguments.length !== 1) {
1445 throw node_utils_1.createError(this.ast, node.arguments.pos, 'Dynamic import must have one specifier as an argument.');
1447 return this.createNode(node, {
1448 type: ts_estree_1.AST_NODE_TYPES.ImportExpression,
1449 source: this.convertChild(node.arguments[0]),
1452 const callee = this.convertChild(node.expression);
1453 const args = node.arguments.map(el => this.convertChild(el));
1455 const isLocallyOptional = node.questionDotToken !== undefined;
1456 // the optional expression should propagate up the member expression tree
1457 const isChildOptional = node_utils_1.isChildOptionalChain(node, callee);
1458 if (isLocallyOptional || isChildOptional) {
1459 result = this.createNode(node, {
1460 type: ts_estree_1.AST_NODE_TYPES.OptionalCallExpression,
1463 optional: isLocallyOptional,
1467 result = this.createNode(node, {
1468 type: ts_estree_1.AST_NODE_TYPES.CallExpression,
1474 if (node.typeArguments) {
1475 result.typeParameters = this.convertTypeArgumentsToTypeParameters(node.typeArguments, node);
1479 case SyntaxKind.NewExpression: {
1480 // NOTE - NewExpression cannot have an optional chain in it
1481 const result = this.createNode(node, {
1482 type: ts_estree_1.AST_NODE_TYPES.NewExpression,
1483 callee: this.convertChild(node.expression),
1484 arguments: node.arguments
1485 ? node.arguments.map(el => this.convertChild(el))
1488 if (node.typeArguments) {
1489 result.typeParameters = this.convertTypeArgumentsToTypeParameters(node.typeArguments, node);
1493 case SyntaxKind.ConditionalExpression:
1494 return this.createNode(node, {
1495 type: ts_estree_1.AST_NODE_TYPES.ConditionalExpression,
1496 test: this.convertChild(node.condition),
1497 consequent: this.convertChild(node.whenTrue),
1498 alternate: this.convertChild(node.whenFalse),
1500 case SyntaxKind.MetaProperty: {
1501 return this.createNode(node, {
1502 type: ts_estree_1.AST_NODE_TYPES.MetaProperty,
1503 meta: this.createNode(
1504 // TODO: do we really want to convert it to Token?
1505 node.getFirstToken(), {
1506 type: ts_estree_1.AST_NODE_TYPES.Identifier,
1507 name: node_utils_1.getTextForTokenKind(node.keywordToken),
1509 property: this.convertChild(node.name),
1512 case SyntaxKind.Decorator: {
1513 return this.createNode(node, {
1514 type: ts_estree_1.AST_NODE_TYPES.Decorator,
1515 expression: this.convertChild(node.expression),
1519 case SyntaxKind.StringLiteral: {
1520 const result = this.createNode(node, {
1521 type: ts_estree_1.AST_NODE_TYPES.Literal,
1525 result.raw = this.ast.text.slice(result.range[0], result.range[1]);
1526 if ('name' in parent && parent.name === node) {
1527 result.value = node.text;
1530 result.value = node_utils_1.unescapeStringLiteralText(node.text);
1534 case SyntaxKind.NumericLiteral: {
1535 return this.createNode(node, {
1536 type: ts_estree_1.AST_NODE_TYPES.Literal,
1537 value: Number(node.text),
1538 raw: node.getText(),
1541 case SyntaxKind.BigIntLiteral: {
1542 const range = node_utils_1.getRange(node, this.ast);
1543 const rawValue = this.ast.text.slice(range[0], range[1]);
1544 const bigint = rawValue
1545 // remove suffix `n`
1547 // `BigInt` doesn't accept numeric separator
1548 // and `bigint` property should not include numeric separator
1550 const value = typeof BigInt !== 'undefined' ? BigInt(bigint) : null;
1551 return this.createNode(node, {
1552 type: ts_estree_1.AST_NODE_TYPES.Literal,
1555 bigint: value === null ? bigint : String(value),
1559 case SyntaxKind.RegularExpressionLiteral: {
1560 const pattern = node.text.slice(1, node.text.lastIndexOf('/'));
1561 const flags = node.text.slice(node.text.lastIndexOf('/') + 1);
1564 regex = new RegExp(pattern, flags);
1569 return this.createNode(node, {
1570 type: ts_estree_1.AST_NODE_TYPES.Literal,
1579 case SyntaxKind.TrueKeyword:
1580 return this.createNode(node, {
1581 type: ts_estree_1.AST_NODE_TYPES.Literal,
1585 case SyntaxKind.FalseKeyword:
1586 return this.createNode(node, {
1587 type: ts_estree_1.AST_NODE_TYPES.Literal,
1591 case SyntaxKind.NullKeyword: {
1592 if (!version_check_1.typescriptVersionIsAtLeast['4.0'] && this.inTypeMode) {
1593 // 4.0 started nesting null types inside a LiteralType node, but we still need to support pre-4.0
1594 return this.createNode(node, {
1595 type: ts_estree_1.AST_NODE_TYPES.TSNullKeyword,
1598 return this.createNode(node, {
1599 type: ts_estree_1.AST_NODE_TYPES.Literal,
1604 case SyntaxKind.EmptyStatement:
1605 return this.createNode(node, {
1606 type: ts_estree_1.AST_NODE_TYPES.EmptyStatement,
1608 case SyntaxKind.DebuggerStatement:
1609 return this.createNode(node, {
1610 type: ts_estree_1.AST_NODE_TYPES.DebuggerStatement,
1613 case SyntaxKind.JsxElement:
1614 return this.createNode(node, {
1615 type: ts_estree_1.AST_NODE_TYPES.JSXElement,
1616 openingElement: this.convertChild(node.openingElement),
1617 closingElement: this.convertChild(node.closingElement),
1618 children: node.children.map(el => this.convertChild(el)),
1620 case SyntaxKind.JsxFragment:
1621 return this.createNode(node, {
1622 type: ts_estree_1.AST_NODE_TYPES.JSXFragment,
1623 openingFragment: this.convertChild(node.openingFragment),
1624 closingFragment: this.convertChild(node.closingFragment),
1625 children: node.children.map(el => this.convertChild(el)),
1627 case SyntaxKind.JsxSelfClosingElement: {
1628 return this.createNode(node, {
1629 type: ts_estree_1.AST_NODE_TYPES.JSXElement,
1631 * Convert SyntaxKind.JsxSelfClosingElement to SyntaxKind.JsxOpeningElement,
1632 * TypeScript does not seem to have the idea of openingElement when tag is self-closing
1634 openingElement: this.createNode(node, {
1635 type: ts_estree_1.AST_NODE_TYPES.JSXOpeningElement,
1636 typeParameters: node.typeArguments
1637 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
1640 name: this.convertJSXTagName(node.tagName, node),
1641 attributes: node.attributes.properties.map(el => this.convertChild(el)),
1642 range: node_utils_1.getRange(node, this.ast),
1644 closingElement: null,
1648 case SyntaxKind.JsxOpeningElement:
1649 return this.createNode(node, {
1650 type: ts_estree_1.AST_NODE_TYPES.JSXOpeningElement,
1651 typeParameters: node.typeArguments
1652 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
1655 name: this.convertJSXTagName(node.tagName, node),
1656 attributes: node.attributes.properties.map(el => this.convertChild(el)),
1658 case SyntaxKind.JsxClosingElement:
1659 return this.createNode(node, {
1660 type: ts_estree_1.AST_NODE_TYPES.JSXClosingElement,
1661 name: this.convertJSXTagName(node.tagName, node),
1663 case SyntaxKind.JsxOpeningFragment:
1664 return this.createNode(node, {
1665 type: ts_estree_1.AST_NODE_TYPES.JSXOpeningFragment,
1667 case SyntaxKind.JsxClosingFragment:
1668 return this.createNode(node, {
1669 type: ts_estree_1.AST_NODE_TYPES.JSXClosingFragment,
1671 case SyntaxKind.JsxExpression: {
1672 const expression = node.expression
1673 ? this.convertChild(node.expression)
1674 : this.createNode(node, {
1675 type: ts_estree_1.AST_NODE_TYPES.JSXEmptyExpression,
1676 range: [node.getStart(this.ast) + 1, node.getEnd() - 1],
1678 if (node.dotDotDotToken) {
1679 return this.createNode(node, {
1680 type: ts_estree_1.AST_NODE_TYPES.JSXSpreadChild,
1685 return this.createNode(node, {
1686 type: ts_estree_1.AST_NODE_TYPES.JSXExpressionContainer,
1691 case SyntaxKind.JsxAttribute: {
1692 const attributeName = this.convertChild(node.name);
1693 attributeName.type = ts_estree_1.AST_NODE_TYPES.JSXIdentifier;
1694 return this.createNode(node, {
1695 type: ts_estree_1.AST_NODE_TYPES.JSXAttribute,
1696 name: attributeName,
1697 value: this.convertChild(node.initializer),
1701 * The JSX AST changed the node type for string literals
1702 * inside a JSX Element from `Literal` to `JSXText`. We
1703 * provide a flag to support both types until `Literal`
1704 * node type is deprecated in ESLint v5.
1706 case SyntaxKind.JsxText: {
1707 const start = node.getFullStart();
1708 const end = node.getEnd();
1709 if (this.options.useJSXTextNode) {
1710 return this.createNode(node, {
1711 type: ts_estree_1.AST_NODE_TYPES.JSXText,
1712 value: this.ast.text.slice(start, end),
1713 raw: this.ast.text.slice(start, end),
1714 range: [start, end],
1718 return this.createNode(node, {
1719 type: ts_estree_1.AST_NODE_TYPES.Literal,
1720 value: this.ast.text.slice(start, end),
1721 raw: this.ast.text.slice(start, end),
1722 range: [start, end],
1726 case SyntaxKind.JsxSpreadAttribute:
1727 return this.createNode(node, {
1728 type: ts_estree_1.AST_NODE_TYPES.JSXSpreadAttribute,
1729 argument: this.convertChild(node.expression),
1731 case SyntaxKind.QualifiedName: {
1732 return this.createNode(node, {
1733 type: ts_estree_1.AST_NODE_TYPES.TSQualifiedName,
1734 left: this.convertChild(node.left),
1735 right: this.convertChild(node.right),
1738 // TypeScript specific
1739 case SyntaxKind.TypeReference: {
1740 return this.createNode(node, {
1741 type: ts_estree_1.AST_NODE_TYPES.TSTypeReference,
1742 typeName: this.convertType(node.typeName),
1743 typeParameters: node.typeArguments
1744 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
1748 case SyntaxKind.TypeParameter: {
1749 return this.createNode(node, {
1750 type: ts_estree_1.AST_NODE_TYPES.TSTypeParameter,
1751 name: this.convertType(node.name),
1752 constraint: node.constraint
1753 ? this.convertType(node.constraint)
1755 default: node.default ? this.convertType(node.default) : undefined,
1758 case SyntaxKind.ThisType:
1759 return this.createNode(node, {
1760 type: ts_estree_1.AST_NODE_TYPES.TSThisType,
1762 case SyntaxKind.AnyKeyword:
1763 case SyntaxKind.BigIntKeyword:
1764 case SyntaxKind.BooleanKeyword:
1765 case SyntaxKind.NeverKeyword:
1766 case SyntaxKind.NumberKeyword:
1767 case SyntaxKind.ObjectKeyword:
1768 case SyntaxKind.StringKeyword:
1769 case SyntaxKind.SymbolKeyword:
1770 case SyntaxKind.UnknownKeyword:
1771 case SyntaxKind.VoidKeyword:
1772 case SyntaxKind.UndefinedKeyword: {
1773 return this.createNode(node, {
1774 type: ts_estree_1.AST_NODE_TYPES[`TS${SyntaxKind[node.kind]}`],
1777 case SyntaxKind.NonNullExpression: {
1778 return this.createNode(node, {
1779 type: ts_estree_1.AST_NODE_TYPES.TSNonNullExpression,
1780 expression: this.convertChild(node.expression),
1783 case SyntaxKind.TypeLiteral: {
1784 return this.createNode(node, {
1785 type: ts_estree_1.AST_NODE_TYPES.TSTypeLiteral,
1786 members: node.members.map(el => this.convertChild(el)),
1789 case SyntaxKind.ArrayType: {
1790 return this.createNode(node, {
1791 type: ts_estree_1.AST_NODE_TYPES.TSArrayType,
1792 elementType: this.convertType(node.elementType),
1795 case SyntaxKind.IndexedAccessType: {
1796 return this.createNode(node, {
1797 type: ts_estree_1.AST_NODE_TYPES.TSIndexedAccessType,
1798 objectType: this.convertType(node.objectType),
1799 indexType: this.convertType(node.indexType),
1802 case SyntaxKind.ConditionalType: {
1803 return this.createNode(node, {
1804 type: ts_estree_1.AST_NODE_TYPES.TSConditionalType,
1805 checkType: this.convertType(node.checkType),
1806 extendsType: this.convertType(node.extendsType),
1807 trueType: this.convertType(node.trueType),
1808 falseType: this.convertType(node.falseType),
1811 case SyntaxKind.TypeQuery: {
1812 return this.createNode(node, {
1813 type: ts_estree_1.AST_NODE_TYPES.TSTypeQuery,
1814 exprName: this.convertType(node.exprName),
1817 case SyntaxKind.MappedType: {
1818 const result = this.createNode(node, {
1819 type: ts_estree_1.AST_NODE_TYPES.TSMappedType,
1820 typeParameter: this.convertType(node.typeParameter),
1822 if (node.readonlyToken) {
1823 if (node.readonlyToken.kind === SyntaxKind.ReadonlyKeyword) {
1824 result.readonly = true;
1827 result.readonly = node_utils_1.getTextForTokenKind(node.readonlyToken.kind);
1830 if (node.questionToken) {
1831 if (node.questionToken.kind === SyntaxKind.QuestionToken) {
1832 result.optional = true;
1835 result.optional = node_utils_1.getTextForTokenKind(node.questionToken.kind);
1839 result.typeAnnotation = this.convertType(node.type);
1843 case SyntaxKind.ParenthesizedExpression:
1844 return this.convertChild(node.expression, parent);
1845 case SyntaxKind.TypeAliasDeclaration: {
1846 const result = this.createNode(node, {
1847 type: ts_estree_1.AST_NODE_TYPES.TSTypeAliasDeclaration,
1848 id: this.convertChild(node.name),
1849 typeAnnotation: this.convertType(node.type),
1851 if (node_utils_1.hasModifier(SyntaxKind.DeclareKeyword, node)) {
1852 result.declare = true;
1854 // Process typeParameters
1855 if (node.typeParameters) {
1856 result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1858 // check for exports
1859 return this.fixExports(node, result);
1861 case SyntaxKind.MethodSignature: {
1862 const result = this.createNode(node, {
1863 type: ts_estree_1.AST_NODE_TYPES.TSMethodSignature,
1864 computed: node_utils_1.isComputedProperty(node.name),
1865 key: this.convertChild(node.name),
1866 params: this.convertParameters(node.parameters),
1868 if (node_utils_1.isOptional(node)) {
1869 result.optional = true;
1872 result.returnType = this.convertTypeAnnotation(node.type, node);
1874 if (node_utils_1.hasModifier(SyntaxKind.ReadonlyKeyword, node)) {
1875 result.readonly = true;
1877 if (node.typeParameters) {
1878 result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1880 const accessibility = node_utils_1.getTSNodeAccessibility(node);
1881 if (accessibility) {
1882 result.accessibility = accessibility;
1884 if (node_utils_1.hasModifier(SyntaxKind.ExportKeyword, node)) {
1885 result.export = true;
1887 if (node_utils_1.hasModifier(SyntaxKind.StaticKeyword, node)) {
1888 result.static = true;
1892 case SyntaxKind.PropertySignature: {
1893 const result = this.createNode(node, {
1894 type: ts_estree_1.AST_NODE_TYPES.TSPropertySignature,
1895 optional: node_utils_1.isOptional(node) || undefined,
1896 computed: node_utils_1.isComputedProperty(node.name),
1897 key: this.convertChild(node.name),
1898 typeAnnotation: node.type
1899 ? this.convertTypeAnnotation(node.type, node)
1901 initializer: this.convertChild(node.initializer) || undefined,
1902 readonly: node_utils_1.hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined,
1903 static: node_utils_1.hasModifier(SyntaxKind.StaticKeyword, node) || undefined,
1904 export: node_utils_1.hasModifier(SyntaxKind.ExportKeyword, node) || undefined,
1906 const accessibility = node_utils_1.getTSNodeAccessibility(node);
1907 if (accessibility) {
1908 result.accessibility = accessibility;
1912 case SyntaxKind.IndexSignature: {
1913 const result = this.createNode(node, {
1914 type: ts_estree_1.AST_NODE_TYPES.TSIndexSignature,
1915 parameters: node.parameters.map(el => this.convertChild(el)),
1918 result.typeAnnotation = this.convertTypeAnnotation(node.type, node);
1920 if (node_utils_1.hasModifier(SyntaxKind.ReadonlyKeyword, node)) {
1921 result.readonly = true;
1923 const accessibility = node_utils_1.getTSNodeAccessibility(node);
1924 if (accessibility) {
1925 result.accessibility = accessibility;
1927 if (node_utils_1.hasModifier(SyntaxKind.ExportKeyword, node)) {
1928 result.export = true;
1930 if (node_utils_1.hasModifier(SyntaxKind.StaticKeyword, node)) {
1931 result.static = true;
1935 case SyntaxKind.ConstructorType:
1936 case SyntaxKind.FunctionType:
1937 case SyntaxKind.ConstructSignature:
1938 case SyntaxKind.CallSignature: {
1940 switch (node.kind) {
1941 case SyntaxKind.ConstructSignature:
1942 type = ts_estree_1.AST_NODE_TYPES.TSConstructSignatureDeclaration;
1944 case SyntaxKind.CallSignature:
1945 type = ts_estree_1.AST_NODE_TYPES.TSCallSignatureDeclaration;
1947 case SyntaxKind.FunctionType:
1948 type = ts_estree_1.AST_NODE_TYPES.TSFunctionType;
1950 case SyntaxKind.ConstructorType:
1952 type = ts_estree_1.AST_NODE_TYPES.TSConstructorType;
1955 const result = this.createNode(node, {
1957 params: this.convertParameters(node.parameters),
1960 result.returnType = this.convertTypeAnnotation(node.type, node);
1962 if (node.typeParameters) {
1963 result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1967 case SyntaxKind.ExpressionWithTypeArguments: {
1968 const result = this.createNode(node, {
1969 type: parent && parent.kind === SyntaxKind.InterfaceDeclaration
1970 ? ts_estree_1.AST_NODE_TYPES.TSInterfaceHeritage
1971 : ts_estree_1.AST_NODE_TYPES.TSClassImplements,
1972 expression: this.convertChild(node.expression),
1974 if (node.typeArguments) {
1975 result.typeParameters = this.convertTypeArgumentsToTypeParameters(node.typeArguments, node);
1979 case SyntaxKind.InterfaceDeclaration: {
1980 const interfaceHeritageClauses = (_j = node.heritageClauses) !== null && _j !== void 0 ? _j : [];
1981 const result = this.createNode(node, {
1982 type: ts_estree_1.AST_NODE_TYPES.TSInterfaceDeclaration,
1983 body: this.createNode(node, {
1984 type: ts_estree_1.AST_NODE_TYPES.TSInterfaceBody,
1985 body: node.members.map(member => this.convertChild(member)),
1986 range: [node.members.pos - 1, node.end],
1988 id: this.convertChild(node.name),
1990 if (node.typeParameters) {
1991 result.typeParameters = this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1993 if (interfaceHeritageClauses.length > 0) {
1994 const interfaceExtends = [];
1995 const interfaceImplements = [];
1996 for (const heritageClause of interfaceHeritageClauses) {
1997 if (heritageClause.token === SyntaxKind.ExtendsKeyword) {
1998 for (const n of heritageClause.types) {
1999 interfaceExtends.push(this.convertChild(n, node));
2003 for (const n of heritageClause.types) {
2004 interfaceImplements.push(this.convertChild(n, node));
2008 if (interfaceExtends.length) {
2009 result.extends = interfaceExtends;
2011 if (interfaceImplements.length) {
2012 result.implements = interfaceImplements;
2016 * Semantically, decorators are not allowed on interface declarations,
2017 * but the TypeScript compiler will parse them and produce a valid AST,
2018 * so we handle them here too.
2020 if (node.decorators) {
2021 result.decorators = node.decorators.map(el => this.convertChild(el));
2023 if (node_utils_1.hasModifier(SyntaxKind.AbstractKeyword, node)) {
2024 result.abstract = true;
2026 if (node_utils_1.hasModifier(SyntaxKind.DeclareKeyword, node)) {
2027 result.declare = true;
2029 // check for exports
2030 return this.fixExports(node, result);
2032 case SyntaxKind.TypePredicate: {
2033 const result = this.createNode(node, {
2034 type: ts_estree_1.AST_NODE_TYPES.TSTypePredicate,
2035 asserts: node.assertsModifier !== undefined,
2036 parameterName: this.convertChild(node.parameterName),
2037 typeAnnotation: null,
2040 * Specific fix for type-guard location data
2043 result.typeAnnotation = this.convertTypeAnnotation(node.type, node);
2044 result.typeAnnotation.loc = result.typeAnnotation.typeAnnotation.loc;
2045 result.typeAnnotation.range =
2046 result.typeAnnotation.typeAnnotation.range;
2050 case SyntaxKind.ImportType:
2051 return this.createNode(node, {
2052 type: ts_estree_1.AST_NODE_TYPES.TSImportType,
2053 isTypeOf: !!node.isTypeOf,
2054 parameter: this.convertChild(node.argument),
2055 qualifier: this.convertChild(node.qualifier),
2056 typeParameters: node.typeArguments
2057 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
2060 case SyntaxKind.EnumDeclaration: {
2061 const result = this.createNode(node, {
2062 type: ts_estree_1.AST_NODE_TYPES.TSEnumDeclaration,
2063 id: this.convertChild(node.name),
2064 members: node.members.map(el => this.convertChild(el)),
2066 // apply modifiers first...
2067 this.applyModifiersToResult(result, node.modifiers);
2069 * Semantically, decorators are not allowed on enum declarations,
2070 * but the TypeScript compiler will parse them and produce a valid AST,
2071 * so we handle them here too.
2073 if (node.decorators) {
2074 result.decorators = node.decorators.map(el => this.convertChild(el));
2076 // ...then check for exports
2077 return this.fixExports(node, result);
2079 case SyntaxKind.EnumMember: {
2080 const result = this.createNode(node, {
2081 type: ts_estree_1.AST_NODE_TYPES.TSEnumMember,
2082 id: this.convertChild(node.name),
2084 if (node.initializer) {
2085 result.initializer = this.convertChild(node.initializer);
2087 if (node.name.kind === ts.SyntaxKind.ComputedPropertyName) {
2088 result.computed = true;
2092 case SyntaxKind.ModuleDeclaration: {
2093 const result = this.createNode(node, {
2094 type: ts_estree_1.AST_NODE_TYPES.TSModuleDeclaration,
2095 id: this.convertChild(node.name),
2098 result.body = this.convertChild(node.body);
2100 // apply modifiers first...
2101 this.applyModifiersToResult(result, node.modifiers);
2102 if (node.flags & ts.NodeFlags.GlobalAugmentation) {
2103 result.global = true;
2105 // ...then check for exports
2106 return this.fixExports(node, result);
2108 // TypeScript specific types
2109 case SyntaxKind.ParenthesizedType: {
2110 return this.createNode(node, {
2111 type: ts_estree_1.AST_NODE_TYPES.TSParenthesizedType,
2112 typeAnnotation: this.convertType(node.type),
2115 case SyntaxKind.UnionType: {
2116 return this.createNode(node, {
2117 type: ts_estree_1.AST_NODE_TYPES.TSUnionType,
2118 types: node.types.map(el => this.convertType(el)),
2121 case SyntaxKind.IntersectionType: {
2122 return this.createNode(node, {
2123 type: ts_estree_1.AST_NODE_TYPES.TSIntersectionType,
2124 types: node.types.map(el => this.convertType(el)),
2127 case SyntaxKind.AsExpression: {
2128 return this.createNode(node, {
2129 type: ts_estree_1.AST_NODE_TYPES.TSAsExpression,
2130 expression: this.convertChild(node.expression),
2131 typeAnnotation: this.convertType(node.type),
2134 case SyntaxKind.InferType: {
2135 return this.createNode(node, {
2136 type: ts_estree_1.AST_NODE_TYPES.TSInferType,
2137 typeParameter: this.convertType(node.typeParameter),
2140 case SyntaxKind.LiteralType: {
2141 if (version_check_1.typescriptVersionIsAtLeast['4.0'] &&
2142 node.literal.kind === SyntaxKind.NullKeyword) {
2143 // 4.0 started nesting null types inside a LiteralType node
2144 // but our AST is designed around the old way of null being a keyword
2145 return this.createNode(node.literal, {
2146 type: ts_estree_1.AST_NODE_TYPES.TSNullKeyword,
2150 return this.createNode(node, {
2151 type: ts_estree_1.AST_NODE_TYPES.TSLiteralType,
2152 literal: this.convertType(node.literal),
2156 case SyntaxKind.TypeAssertionExpression: {
2157 return this.createNode(node, {
2158 type: ts_estree_1.AST_NODE_TYPES.TSTypeAssertion,
2159 typeAnnotation: this.convertType(node.type),
2160 expression: this.convertChild(node.expression),
2163 case SyntaxKind.ImportEqualsDeclaration: {
2164 return this.createNode(node, {
2165 type: ts_estree_1.AST_NODE_TYPES.TSImportEqualsDeclaration,
2166 id: this.convertChild(node.name),
2167 moduleReference: this.convertChild(node.moduleReference),
2168 isExport: node_utils_1.hasModifier(SyntaxKind.ExportKeyword, node),
2171 case SyntaxKind.ExternalModuleReference: {
2172 return this.createNode(node, {
2173 type: ts_estree_1.AST_NODE_TYPES.TSExternalModuleReference,
2174 expression: this.convertChild(node.expression),
2177 case SyntaxKind.NamespaceExportDeclaration: {
2178 return this.createNode(node, {
2179 type: ts_estree_1.AST_NODE_TYPES.TSNamespaceExportDeclaration,
2180 id: this.convertChild(node.name),
2183 case SyntaxKind.AbstractKeyword: {
2184 return this.createNode(node, {
2185 type: ts_estree_1.AST_NODE_TYPES.TSAbstractKeyword,
2189 case SyntaxKind.TupleType: {
2190 // In TS 4.0, the `elementTypes` property was changed to `elements`.
2191 // To support both at compile time, we cast to access the newer version
2192 // if the former does not exist.
2193 const elementTypes = 'elementTypes' in node
2194 ? node.elementTypes.map((el) => this.convertType(el))
2195 : node.elements.map((el) => this.convertType(el));
2196 return this.createNode(node, {
2197 type: ts_estree_1.AST_NODE_TYPES.TSTupleType,
2201 case SyntaxKind.NamedTupleMember: {
2202 const member = this.createNode(node, {
2203 type: ts_estree_1.AST_NODE_TYPES.TSNamedTupleMember,
2204 elementType: this.convertType(node.type, node),
2205 label: this.convertChild(node.name, node),
2206 optional: node.questionToken != null,
2208 if (node.dotDotDotToken) {
2209 // adjust the start to account for the "..."
2210 member.range[0] = member.label.range[0];
2211 member.loc.start = member.label.loc.start;
2212 return this.createNode(node, {
2213 type: ts_estree_1.AST_NODE_TYPES.TSRestType,
2214 typeAnnotation: member,
2219 case SyntaxKind.OptionalType: {
2220 return this.createNode(node, {
2221 type: ts_estree_1.AST_NODE_TYPES.TSOptionalType,
2222 typeAnnotation: this.convertType(node.type),
2225 case SyntaxKind.RestType: {
2226 return this.createNode(node, {
2227 type: ts_estree_1.AST_NODE_TYPES.TSRestType,
2228 typeAnnotation: this.convertType(node.type),
2232 return this.deeplyCopy(node);
2236 exports.Converter = Converter;
2237 //# sourceMappingURL=convert.js.map