UNPKG

110 kBJavaScriptView Raw
1"use strict";
2var __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;
7 o[k2] = m[k];
8}));
9var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10 Object.defineProperty(o, "default", { enumerable: true, value: v });
11}) : function(o, v) {
12 o["default"] = v;
13});
14var __importStar = (this && this.__importStar) || function (mod) {
15 if (mod && mod.__esModule) return mod;
16 var result = {};
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);
19 return result;
20};
21Object.defineProperty(exports, "__esModule", { value: true });
22exports.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, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access */
25const ts = __importStar(require("typescript"));
26const node_utils_1 = require("./node-utils");
27const ts_estree_1 = require("./ts-estree");
28const version_check_1 = require("./version-check");
29const SyntaxKind = ts.SyntaxKind;
30/**
31 * Extends and formats a given error object
32 * @param error the error object
33 * @returns converted error object
34 */
35function convertError(error) {
36 return (0, node_utils_1.createError)(error.file, error.start, ('message' in error && error.message) || error.messageText);
37}
38exports.convertError = convertError;
39class Converter {
40 /**
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
45 */
46 constructor(ast, options) {
47 this.esTreeNodeToTSNodeMap = new WeakMap();
48 this.tsNodeToESTreeNodeMap = new WeakMap();
49 this.allowPattern = false;
50 this.inTypeMode = false;
51 this.ast = ast;
52 this.options = Object.assign({}, options);
53 }
54 getASTMaps() {
55 return {
56 esTreeNodeToTSNodeMap: this.esTreeNodeToTSNodeMap,
57 tsNodeToESTreeNodeMap: this.tsNodeToESTreeNodeMap,
58 };
59 }
60 convertProgram() {
61 return this.converter(this.ast);
62 }
63 /**
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
70 */
71 converter(node, parent, inTypeMode, allowPattern) {
72 /**
73 * Exit early for null and undefined
74 */
75 if (!node) {
76 return null;
77 }
78 const typeMode = this.inTypeMode;
79 const pattern = this.allowPattern;
80 if (inTypeMode !== undefined) {
81 this.inTypeMode = inTypeMode;
82 }
83 if (allowPattern !== undefined) {
84 this.allowPattern = allowPattern;
85 }
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;
90 return result;
91 }
92 /**
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
97 */
98 fixExports(node, result) {
99 // check for exports
100 if (node.modifiers && node.modifiers[0].kind === SyntaxKind.ExportKeyword) {
101 /**
102 * Make sure that original node is registered instead of export
103 */
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 ? (0, node_utils_1.findNextToken)(nextModifier, this.ast, this.ast)
110 : (0, node_utils_1.findNextToken)(exportKeyword, this.ast, this.ast);
111 result.range[0] = varToken.getStart(this.ast);
112 result.loc = (0, 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,
116 declaration: result,
117 range: [exportKeyword.getStart(this.ast), result.range[1]],
118 exportKind: 'value',
119 });
120 }
121 else {
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,
127 declaration: result,
128 specifiers: [],
129 source: null,
130 exportKind: isType || isDeclare ? 'type' : 'value',
131 range: [exportKeyword.getStart(this.ast), result.range[1]],
132 assertions: [],
133 });
134 }
135 }
136 return result;
137 }
138 /**
139 * Register specific TypeScript node into map with first ESTree node provided
140 */
141 registerTSNodeInNodeMap(node, result) {
142 if (result && this.options.shouldPreserveNodeMaps) {
143 if (!this.tsNodeToESTreeNodeMap.has(node)) {
144 this.tsNodeToESTreeNodeMap.set(node, result);
145 }
146 }
147 }
148 /**
149 * Converts a TypeScript node into an ESTree node.
150 * @param child the child ts.Node
151 * @param parent parentNode
152 * @returns the converted ESTree node
153 */
154 convertPattern(child, parent) {
155 return this.converter(child, parent, this.inTypeMode, true);
156 }
157 /**
158 * Converts a TypeScript node into an ESTree node.
159 * @param child the child ts.Node
160 * @param parent parentNode
161 * @returns the converted ESTree node
162 */
163 convertChild(child, parent) {
164 return this.converter(child, parent, this.inTypeMode, false);
165 }
166 /**
167 * Converts a TypeScript node into an ESTree node.
168 * @param child the child ts.Node
169 * @param parent parentNode
170 * @returns the converted ESTree node
171 */
172 convertType(child, parent) {
173 return this.converter(child, parent, true, false);
174 }
175 createNode(node, data) {
176 const result = data;
177 if (!result.range) {
178 result.range = (0, node_utils_1.getRange)(
179 // this is completely valid, but TS hates it
180 node, this.ast);
181 }
182 if (!result.loc) {
183 result.loc = (0, node_utils_1.getLocFor)(result.range[0], result.range[1], this.ast);
184 }
185 if (result && this.options.shouldPreserveNodeMaps) {
186 this.esTreeNodeToTSNodeMap.set(result, node);
187 }
188 return result;
189 }
190 convertBindingNameWithTypeAnnotation(name, tsType, parent) {
191 const id = this.convertPattern(name);
192 if (tsType) {
193 id.typeAnnotation = this.convertTypeAnnotation(tsType, parent);
194 this.fixParentLocation(id, id.typeAnnotation.range);
195 }
196 return id;
197 }
198 /**
199 * Converts a child into a type annotation. This creates an intermediary
200 * TypeAnnotation node to match what Flow does.
201 * @param child The TypeScript AST node to convert.
202 * @param parent parentNode
203 * @returns The type annotation node.
204 */
205 convertTypeAnnotation(child, parent) {
206 // in FunctionType and ConstructorType typeAnnotation has 2 characters `=>` and in other places is just colon
207 const offset = (parent === null || parent === void 0 ? void 0 : parent.kind) === SyntaxKind.FunctionType ||
208 (parent === null || parent === void 0 ? void 0 : parent.kind) === SyntaxKind.ConstructorType
209 ? 2
210 : 1;
211 const annotationStartCol = child.getFullStart() - offset;
212 const loc = (0, node_utils_1.getLocFor)(annotationStartCol, child.end, this.ast);
213 return {
214 type: ts_estree_1.AST_NODE_TYPES.TSTypeAnnotation,
215 loc,
216 range: [annotationStartCol, child.end],
217 typeAnnotation: this.convertType(child),
218 };
219 }
220 /**
221 * Coverts body Nodes and add a directive field to StringLiterals
222 * @param nodes of ts.Node
223 * @param parent parentNode
224 * @returns Array of body statements
225 */
226 convertBodyExpressions(nodes, parent) {
227 let allowDirectives = (0, node_utils_1.canContainDirective)(parent);
228 return (nodes
229 .map(statement => {
230 const child = this.convertChild(statement);
231 if (allowDirectives) {
232 if ((child === null || child === void 0 ? void 0 : child.expression) &&
233 ts.isExpressionStatement(statement) &&
234 ts.isStringLiteral(statement.expression)) {
235 const raw = child.expression.raw;
236 child.directive = raw.slice(1, -1);
237 return child; // child can be null, but it's filtered below
238 }
239 else {
240 allowDirectives = false;
241 }
242 }
243 return child; // child can be null, but it's filtered below
244 })
245 // filter out unknown nodes for now
246 .filter(statement => statement));
247 }
248 /**
249 * Converts a ts.Node's typeArguments to TSTypeParameterInstantiation node
250 * @param typeArguments ts.NodeArray typeArguments
251 * @param node parent used to create this node
252 * @returns TypeParameterInstantiation node
253 */
254 convertTypeArgumentsToTypeParameters(typeArguments, node) {
255 const greaterThanToken = (0, node_utils_1.findNextToken)(typeArguments, this.ast, this.ast);
256 return this.createNode(node, {
257 type: ts_estree_1.AST_NODE_TYPES.TSTypeParameterInstantiation,
258 range: [typeArguments.pos - 1, greaterThanToken.end],
259 params: typeArguments.map(typeArgument => this.convertType(typeArgument)),
260 });
261 }
262 /**
263 * Converts a ts.Node's typeParameters to TSTypeParameterDeclaration node
264 * @param typeParameters ts.Node typeParameters
265 * @returns TypeParameterDeclaration node
266 */
267 convertTSTypeParametersToTypeParametersDeclaration(typeParameters) {
268 const greaterThanToken = (0, node_utils_1.findNextToken)(typeParameters, this.ast, this.ast);
269 return {
270 type: ts_estree_1.AST_NODE_TYPES.TSTypeParameterDeclaration,
271 range: [typeParameters.pos - 1, greaterThanToken.end],
272 loc: (0, node_utils_1.getLocFor)(typeParameters.pos - 1, greaterThanToken.end, this.ast),
273 params: typeParameters.map(typeParameter => this.convertType(typeParameter)),
274 };
275 }
276 /**
277 * Converts an array of ts.Node parameters into an array of ESTreeNode params
278 * @param parameters An array of ts.Node params to be converted
279 * @returns an array of converted ESTreeNode params
280 */
281 convertParameters(parameters) {
282 if (!parameters || !parameters.length) {
283 return [];
284 }
285 return parameters.map(param => {
286 var _a;
287 const convertedParam = this.convertChild(param);
288 if ((_a = param.decorators) === null || _a === void 0 ? void 0 : _a.length) {
289 convertedParam.decorators = param.decorators.map(el => this.convertChild(el));
290 }
291 return convertedParam;
292 });
293 }
294 convertChainExpression(node, tsNode) {
295 const { child, isOptional } = (() => {
296 if (node.type === ts_estree_1.AST_NODE_TYPES.MemberExpression) {
297 return { child: node.object, isOptional: node.optional };
298 }
299 if (node.type === ts_estree_1.AST_NODE_TYPES.CallExpression) {
300 return { child: node.callee, isOptional: node.optional };
301 }
302 return { child: node.expression, isOptional: false };
303 })();
304 const isChildUnwrappable = (0, node_utils_1.isChildUnwrappableOptionalChain)(tsNode, child);
305 if (!isChildUnwrappable && !isOptional) {
306 return node;
307 }
308 if (isChildUnwrappable && (0, node_utils_1.isChainExpression)(child)) {
309 // unwrap the chain expression child
310 const newChild = child.expression;
311 if (node.type === ts_estree_1.AST_NODE_TYPES.MemberExpression) {
312 node.object = newChild;
313 }
314 else if (node.type === ts_estree_1.AST_NODE_TYPES.CallExpression) {
315 node.callee = newChild;
316 }
317 else {
318 node.expression = newChild;
319 }
320 }
321 return this.createNode(tsNode, {
322 type: ts_estree_1.AST_NODE_TYPES.ChainExpression,
323 expression: node,
324 });
325 }
326 /**
327 * For nodes that are copied directly from the TypeScript AST into
328 * ESTree mostly as-is. The only difference is the addition of a type
329 * property instead of a kind property. Recursively copies all children.
330 */
331 deeplyCopy(node) {
332 if (node.kind === ts.SyntaxKind.JSDocFunctionType) {
333 throw (0, node_utils_1.createError)(this.ast, node.pos, 'JSDoc types can only be used inside documentation comments.');
334 }
335 const customType = `TS${SyntaxKind[node.kind]}`;
336 /**
337 * If the "errorOnUnknownASTType" option is set to true, throw an error,
338 * otherwise fallback to just including the unknown type as-is.
339 */
340 if (this.options.errorOnUnknownASTType && !ts_estree_1.AST_NODE_TYPES[customType]) {
341 throw new Error(`Unknown AST_NODE_TYPE: "${customType}"`);
342 }
343 const result = this.createNode(node, {
344 type: customType,
345 });
346 if ('type' in node) {
347 result.typeAnnotation =
348 node.type && 'kind' in node.type && ts.isTypeNode(node.type)
349 ? this.convertTypeAnnotation(node.type, node)
350 : null;
351 }
352 if ('typeArguments' in node) {
353 result.typeParameters =
354 node.typeArguments && 'pos' in node.typeArguments
355 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
356 : null;
357 }
358 if ('typeParameters' in node) {
359 result.typeParameters =
360 node.typeParameters && 'pos' in node.typeParameters
361 ? this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters)
362 : null;
363 }
364 if ('decorators' in node && node.decorators && node.decorators.length) {
365 result.decorators = node.decorators.map(el => this.convertChild(el));
366 }
367 Object.entries(node)
368 .filter(([key]) => !/^(?:_children|kind|parent|pos|end|flags|modifierFlagsCache|jsDoc|type|typeArguments|typeParameters|decorators|transformFlags)$/.test(key))
369 .forEach(([key, value]) => {
370 if (Array.isArray(value)) {
371 result[key] = value.map(el => this.convertChild(el));
372 }
373 else if (value && typeof value === 'object' && value.kind) {
374 // need to check node[key].kind to ensure we don't try to convert a symbol
375 result[key] = this.convertChild(value);
376 }
377 else {
378 result[key] = value;
379 }
380 });
381 return result;
382 }
383 convertJSXIdentifier(node) {
384 const result = this.createNode(node, {
385 type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
386 name: node.getText(),
387 });
388 this.registerTSNodeInNodeMap(node, result);
389 return result;
390 }
391 convertJSXNamespaceOrIdentifier(node) {
392 const text = node.getText();
393 const colonIndex = text.indexOf(':');
394 // this is intentional we can ignore conversion if `:` is in first character
395 if (colonIndex > 0) {
396 const range = (0, node_utils_1.getRange)(node, this.ast);
397 const result = this.createNode(node, {
398 type: ts_estree_1.AST_NODE_TYPES.JSXNamespacedName,
399 namespace: this.createNode(node, {
400 type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
401 name: text.slice(0, colonIndex),
402 range: [range[0], range[0] + colonIndex],
403 }),
404 name: this.createNode(node, {
405 type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
406 name: text.slice(colonIndex + 1),
407 range: [range[0] + colonIndex + 1, range[1]],
408 }),
409 range,
410 });
411 this.registerTSNodeInNodeMap(node, result);
412 return result;
413 }
414 return this.convertJSXIdentifier(node);
415 }
416 /**
417 * Converts a TypeScript JSX node.tagName into an ESTree node.name
418 * @param node the tagName object from a JSX ts.Node
419 * @param parent
420 * @returns the converted ESTree name object
421 */
422 convertJSXTagName(node, parent) {
423 let result;
424 switch (node.kind) {
425 case SyntaxKind.PropertyAccessExpression:
426 if (node.name.kind === SyntaxKind.PrivateIdentifier) {
427 // This is one of the few times where TS explicitly errors, and doesn't even gracefully handle the syntax.
428 // So we shouldn't ever get into this state to begin with.
429 throw new Error('Non-private identifier expected.');
430 }
431 result = this.createNode(node, {
432 type: ts_estree_1.AST_NODE_TYPES.JSXMemberExpression,
433 object: this.convertJSXTagName(node.expression, parent),
434 property: this.convertJSXIdentifier(node.name),
435 });
436 break;
437 case SyntaxKind.ThisKeyword:
438 case SyntaxKind.Identifier:
439 default:
440 return this.convertJSXNamespaceOrIdentifier(node);
441 }
442 this.registerTSNodeInNodeMap(node, result);
443 return result;
444 }
445 convertMethodSignature(node) {
446 const result = this.createNode(node, {
447 type: ts_estree_1.AST_NODE_TYPES.TSMethodSignature,
448 computed: (0, node_utils_1.isComputedProperty)(node.name),
449 key: this.convertChild(node.name),
450 params: this.convertParameters(node.parameters),
451 kind: (() => {
452 switch (node.kind) {
453 case SyntaxKind.GetAccessor:
454 return 'get';
455 case SyntaxKind.SetAccessor:
456 return 'set';
457 case SyntaxKind.MethodSignature:
458 return 'method';
459 }
460 })(),
461 });
462 if ((0, node_utils_1.isOptional)(node)) {
463 result.optional = true;
464 }
465 if (node.type) {
466 result.returnType = this.convertTypeAnnotation(node.type, node);
467 }
468 if ((0, node_utils_1.hasModifier)(SyntaxKind.ReadonlyKeyword, node)) {
469 result.readonly = true;
470 }
471 if (node.typeParameters) {
472 result.typeParameters =
473 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
474 }
475 const accessibility = (0, node_utils_1.getTSNodeAccessibility)(node);
476 if (accessibility) {
477 result.accessibility = accessibility;
478 }
479 if ((0, node_utils_1.hasModifier)(SyntaxKind.ExportKeyword, node)) {
480 result.export = true;
481 }
482 if ((0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node)) {
483 result.static = true;
484 }
485 return result;
486 }
487 convertAssertClasue(node) {
488 return node === undefined
489 ? []
490 : node.elements.map(element => this.convertChild(element));
491 }
492 /**
493 * Applies the given TS modifiers to the given result object.
494 * @param result
495 * @param modifiers original ts.Nodes from the node.modifiers array
496 * @returns the current result object will be mutated
497 * @deprecated This method adds not standardized `modifiers` property in nodes
498 */
499 applyModifiersToResult(result, modifiers) {
500 if (!modifiers || !modifiers.length) {
501 return;
502 }
503 const remainingModifiers = [];
504 /**
505 * Some modifiers are explicitly handled by applying them as
506 * boolean values on the result node. As well as adding them
507 * to the result, we remove them from the array, so that they
508 * are not handled twice.
509 */
510 for (let i = 0; i < modifiers.length; i++) {
511 const modifier = modifiers[i];
512 switch (modifier.kind) {
513 /**
514 * Ignore ExportKeyword and DefaultKeyword, they are handled
515 * via the fixExports utility function
516 */
517 case SyntaxKind.ExportKeyword:
518 case SyntaxKind.DefaultKeyword:
519 break;
520 case SyntaxKind.ConstKeyword:
521 result.const = true;
522 break;
523 case SyntaxKind.DeclareKeyword:
524 result.declare = true;
525 break;
526 default:
527 remainingModifiers.push(this.convertChild(modifier));
528 break;
529 }
530 }
531 /**
532 * If there are still valid modifiers available which have
533 * not been explicitly handled above, we just convert and
534 * add the modifiers array to the result node.
535 */
536 if (remainingModifiers.length) {
537 result.modifiers = remainingModifiers;
538 }
539 }
540 /**
541 * Uses the provided range location to adjust the location data of the given Node
542 * @param result The node that will have its location data mutated
543 * @param childRange The child node range used to expand location
544 */
545 fixParentLocation(result, childRange) {
546 if (childRange[0] < result.range[0]) {
547 result.range[0] = childRange[0];
548 result.loc.start = (0, node_utils_1.getLineAndCharacterFor)(result.range[0], this.ast);
549 }
550 if (childRange[1] > result.range[1]) {
551 result.range[1] = childRange[1];
552 result.loc.end = (0, node_utils_1.getLineAndCharacterFor)(result.range[1], this.ast);
553 }
554 }
555 assertModuleSpecifier(node) {
556 if (node.moduleSpecifier &&
557 node.moduleSpecifier.kind !== SyntaxKind.StringLiteral) {
558 throw (0, node_utils_1.createError)(this.ast, node.moduleSpecifier.pos, 'Module specifier must be a string literal.');
559 }
560 }
561 /**
562 * Converts a TypeScript node into an ESTree node.
563 * The core of the conversion logic:
564 * Identify and convert each relevant TypeScript SyntaxKind
565 * @param node the child ts.Node
566 * @param parent parentNode
567 * @returns the converted ESTree node
568 */
569 convertNode(node, parent) {
570 var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
571 switch (node.kind) {
572 case SyntaxKind.SourceFile: {
573 return this.createNode(node, {
574 type: ts_estree_1.AST_NODE_TYPES.Program,
575 body: this.convertBodyExpressions(node.statements, node),
576 sourceType: node.externalModuleIndicator ? 'module' : 'script',
577 range: [node.getStart(this.ast), node.endOfFileToken.end],
578 });
579 }
580 case SyntaxKind.Block: {
581 return this.createNode(node, {
582 type: ts_estree_1.AST_NODE_TYPES.BlockStatement,
583 body: this.convertBodyExpressions(node.statements, node),
584 });
585 }
586 case SyntaxKind.Identifier: {
587 return this.createNode(node, {
588 type: ts_estree_1.AST_NODE_TYPES.Identifier,
589 name: node.text,
590 });
591 }
592 case SyntaxKind.PrivateIdentifier: {
593 return this.createNode(node, {
594 type: ts_estree_1.AST_NODE_TYPES.PrivateIdentifier,
595 // typescript includes the `#` in the text
596 name: node.text.slice(1),
597 });
598 }
599 case SyntaxKind.WithStatement:
600 return this.createNode(node, {
601 type: ts_estree_1.AST_NODE_TYPES.WithStatement,
602 object: this.convertChild(node.expression),
603 body: this.convertChild(node.statement),
604 });
605 // Control Flow
606 case SyntaxKind.ReturnStatement:
607 return this.createNode(node, {
608 type: ts_estree_1.AST_NODE_TYPES.ReturnStatement,
609 argument: this.convertChild(node.expression),
610 });
611 case SyntaxKind.LabeledStatement:
612 return this.createNode(node, {
613 type: ts_estree_1.AST_NODE_TYPES.LabeledStatement,
614 label: this.convertChild(node.label),
615 body: this.convertChild(node.statement),
616 });
617 case SyntaxKind.ContinueStatement:
618 return this.createNode(node, {
619 type: ts_estree_1.AST_NODE_TYPES.ContinueStatement,
620 label: this.convertChild(node.label),
621 });
622 case SyntaxKind.BreakStatement:
623 return this.createNode(node, {
624 type: ts_estree_1.AST_NODE_TYPES.BreakStatement,
625 label: this.convertChild(node.label),
626 });
627 // Choice
628 case SyntaxKind.IfStatement:
629 return this.createNode(node, {
630 type: ts_estree_1.AST_NODE_TYPES.IfStatement,
631 test: this.convertChild(node.expression),
632 consequent: this.convertChild(node.thenStatement),
633 alternate: this.convertChild(node.elseStatement),
634 });
635 case SyntaxKind.SwitchStatement:
636 return this.createNode(node, {
637 type: ts_estree_1.AST_NODE_TYPES.SwitchStatement,
638 discriminant: this.convertChild(node.expression),
639 cases: node.caseBlock.clauses.map(el => this.convertChild(el)),
640 });
641 case SyntaxKind.CaseClause:
642 case SyntaxKind.DefaultClause:
643 return this.createNode(node, {
644 type: ts_estree_1.AST_NODE_TYPES.SwitchCase,
645 // expression is present in case only
646 test: node.kind === SyntaxKind.CaseClause
647 ? this.convertChild(node.expression)
648 : null,
649 consequent: node.statements.map(el => this.convertChild(el)),
650 });
651 // Exceptions
652 case SyntaxKind.ThrowStatement:
653 return this.createNode(node, {
654 type: ts_estree_1.AST_NODE_TYPES.ThrowStatement,
655 argument: this.convertChild(node.expression),
656 });
657 case SyntaxKind.TryStatement:
658 return this.createNode(node, {
659 type: ts_estree_1.AST_NODE_TYPES.TryStatement,
660 block: this.convertChild(node.tryBlock),
661 handler: this.convertChild(node.catchClause),
662 finalizer: this.convertChild(node.finallyBlock),
663 });
664 case SyntaxKind.CatchClause:
665 return this.createNode(node, {
666 type: ts_estree_1.AST_NODE_TYPES.CatchClause,
667 param: node.variableDeclaration
668 ? this.convertBindingNameWithTypeAnnotation(node.variableDeclaration.name, node.variableDeclaration.type)
669 : null,
670 body: this.convertChild(node.block),
671 });
672 // Loops
673 case SyntaxKind.WhileStatement:
674 return this.createNode(node, {
675 type: ts_estree_1.AST_NODE_TYPES.WhileStatement,
676 test: this.convertChild(node.expression),
677 body: this.convertChild(node.statement),
678 });
679 /**
680 * Unlike other parsers, TypeScript calls a "DoWhileStatement"
681 * a "DoStatement"
682 */
683 case SyntaxKind.DoStatement:
684 return this.createNode(node, {
685 type: ts_estree_1.AST_NODE_TYPES.DoWhileStatement,
686 test: this.convertChild(node.expression),
687 body: this.convertChild(node.statement),
688 });
689 case SyntaxKind.ForStatement:
690 return this.createNode(node, {
691 type: ts_estree_1.AST_NODE_TYPES.ForStatement,
692 init: this.convertChild(node.initializer),
693 test: this.convertChild(node.condition),
694 update: this.convertChild(node.incrementor),
695 body: this.convertChild(node.statement),
696 });
697 case SyntaxKind.ForInStatement:
698 return this.createNode(node, {
699 type: ts_estree_1.AST_NODE_TYPES.ForInStatement,
700 left: this.convertPattern(node.initializer),
701 right: this.convertChild(node.expression),
702 body: this.convertChild(node.statement),
703 });
704 case SyntaxKind.ForOfStatement:
705 return this.createNode(node, {
706 type: ts_estree_1.AST_NODE_TYPES.ForOfStatement,
707 left: this.convertPattern(node.initializer),
708 right: this.convertChild(node.expression),
709 body: this.convertChild(node.statement),
710 await: Boolean(node.awaitModifier &&
711 node.awaitModifier.kind === SyntaxKind.AwaitKeyword),
712 });
713 // Declarations
714 case SyntaxKind.FunctionDeclaration: {
715 const isDeclare = (0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node);
716 const result = this.createNode(node, {
717 type: isDeclare || !node.body
718 ? ts_estree_1.AST_NODE_TYPES.TSDeclareFunction
719 : ts_estree_1.AST_NODE_TYPES.FunctionDeclaration,
720 id: this.convertChild(node.name),
721 generator: !!node.asteriskToken,
722 expression: false,
723 async: (0, node_utils_1.hasModifier)(SyntaxKind.AsyncKeyword, node),
724 params: this.convertParameters(node.parameters),
725 body: this.convertChild(node.body) || undefined,
726 });
727 // Process returnType
728 if (node.type) {
729 result.returnType = this.convertTypeAnnotation(node.type, node);
730 }
731 if (isDeclare) {
732 result.declare = true;
733 }
734 // Process typeParameters
735 if (node.typeParameters) {
736 result.typeParameters =
737 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
738 }
739 // check for exports
740 return this.fixExports(node, result);
741 }
742 case SyntaxKind.VariableDeclaration: {
743 const result = this.createNode(node, {
744 type: ts_estree_1.AST_NODE_TYPES.VariableDeclarator,
745 id: this.convertBindingNameWithTypeAnnotation(node.name, node.type, node),
746 init: this.convertChild(node.initializer),
747 });
748 if (node.exclamationToken) {
749 result.definite = true;
750 }
751 return result;
752 }
753 case SyntaxKind.VariableStatement: {
754 const result = this.createNode(node, {
755 type: ts_estree_1.AST_NODE_TYPES.VariableDeclaration,
756 declarations: node.declarationList.declarations.map(el => this.convertChild(el)),
757 kind: (0, node_utils_1.getDeclarationKind)(node.declarationList),
758 });
759 /**
760 * Semantically, decorators are not allowed on variable declarations,
761 * but the TypeScript compiler will parse them and produce a valid AST,
762 * so we handle them here too.
763 */
764 if (node.decorators) {
765 result.decorators = node.decorators.map(el => this.convertChild(el));
766 }
767 if ((0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node)) {
768 result.declare = true;
769 }
770 // check for exports
771 return this.fixExports(node, result);
772 }
773 // mostly for for-of, for-in
774 case SyntaxKind.VariableDeclarationList:
775 return this.createNode(node, {
776 type: ts_estree_1.AST_NODE_TYPES.VariableDeclaration,
777 declarations: node.declarations.map(el => this.convertChild(el)),
778 kind: (0, node_utils_1.getDeclarationKind)(node),
779 });
780 // Expressions
781 case SyntaxKind.ExpressionStatement:
782 return this.createNode(node, {
783 type: ts_estree_1.AST_NODE_TYPES.ExpressionStatement,
784 expression: this.convertChild(node.expression),
785 });
786 case SyntaxKind.ThisKeyword:
787 return this.createNode(node, {
788 type: ts_estree_1.AST_NODE_TYPES.ThisExpression,
789 });
790 case SyntaxKind.ArrayLiteralExpression: {
791 // TypeScript uses ArrayLiteralExpression in destructuring assignment, too
792 if (this.allowPattern) {
793 return this.createNode(node, {
794 type: ts_estree_1.AST_NODE_TYPES.ArrayPattern,
795 elements: node.elements.map(el => this.convertPattern(el)),
796 });
797 }
798 else {
799 return this.createNode(node, {
800 type: ts_estree_1.AST_NODE_TYPES.ArrayExpression,
801 elements: node.elements.map(el => this.convertChild(el)),
802 });
803 }
804 }
805 case SyntaxKind.ObjectLiteralExpression: {
806 // TypeScript uses ObjectLiteralExpression in destructuring assignment, too
807 if (this.allowPattern) {
808 return this.createNode(node, {
809 type: ts_estree_1.AST_NODE_TYPES.ObjectPattern,
810 properties: node.properties.map(el => this.convertPattern(el)),
811 });
812 }
813 else {
814 return this.createNode(node, {
815 type: ts_estree_1.AST_NODE_TYPES.ObjectExpression,
816 properties: node.properties.map(el => this.convertChild(el)),
817 });
818 }
819 }
820 case SyntaxKind.PropertyAssignment:
821 return this.createNode(node, {
822 type: ts_estree_1.AST_NODE_TYPES.Property,
823 key: this.convertChild(node.name),
824 value: this.converter(node.initializer, node, this.inTypeMode, this.allowPattern),
825 computed: (0, node_utils_1.isComputedProperty)(node.name),
826 method: false,
827 shorthand: false,
828 kind: 'init',
829 });
830 case SyntaxKind.ShorthandPropertyAssignment: {
831 if (node.objectAssignmentInitializer) {
832 return this.createNode(node, {
833 type: ts_estree_1.AST_NODE_TYPES.Property,
834 key: this.convertChild(node.name),
835 value: this.createNode(node, {
836 type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
837 left: this.convertPattern(node.name),
838 right: this.convertChild(node.objectAssignmentInitializer),
839 }),
840 computed: false,
841 method: false,
842 shorthand: true,
843 kind: 'init',
844 });
845 }
846 else {
847 return this.createNode(node, {
848 type: ts_estree_1.AST_NODE_TYPES.Property,
849 key: this.convertChild(node.name),
850 value: this.convertChild(node.name),
851 computed: false,
852 method: false,
853 shorthand: true,
854 kind: 'init',
855 });
856 }
857 }
858 case SyntaxKind.ComputedPropertyName:
859 return this.convertChild(node.expression);
860 case SyntaxKind.PropertyDeclaration: {
861 const isAbstract = (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node);
862 const result = this.createNode(node, {
863 type: isAbstract
864 ? ts_estree_1.AST_NODE_TYPES.TSAbstractPropertyDefinition
865 : ts_estree_1.AST_NODE_TYPES.PropertyDefinition,
866 key: this.convertChild(node.name),
867 value: isAbstract ? null : this.convertChild(node.initializer),
868 computed: (0, node_utils_1.isComputedProperty)(node.name),
869 static: (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node),
870 readonly: (0, node_utils_1.hasModifier)(SyntaxKind.ReadonlyKeyword, node) || undefined,
871 declare: (0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node),
872 override: (0, node_utils_1.hasModifier)(SyntaxKind.OverrideKeyword, node),
873 });
874 if (node.type) {
875 result.typeAnnotation = this.convertTypeAnnotation(node.type, node);
876 }
877 if (node.decorators) {
878 result.decorators = node.decorators.map(el => this.convertChild(el));
879 }
880 const accessibility = (0, node_utils_1.getTSNodeAccessibility)(node);
881 if (accessibility) {
882 result.accessibility = accessibility;
883 }
884 if ((node.name.kind === SyntaxKind.Identifier ||
885 node.name.kind === SyntaxKind.ComputedPropertyName ||
886 node.name.kind === SyntaxKind.PrivateIdentifier) &&
887 node.questionToken) {
888 result.optional = true;
889 }
890 if (node.exclamationToken) {
891 result.definite = true;
892 }
893 if (result.key.type === ts_estree_1.AST_NODE_TYPES.Literal && node.questionToken) {
894 result.optional = true;
895 }
896 return result;
897 }
898 case SyntaxKind.GetAccessor:
899 case SyntaxKind.SetAccessor: {
900 if (node.parent.kind === SyntaxKind.InterfaceDeclaration ||
901 node.parent.kind === SyntaxKind.TypeLiteral) {
902 return this.convertMethodSignature(node);
903 }
904 }
905 // otherwise, it is a non-type accessor - intentional fallthrough
906 case SyntaxKind.MethodDeclaration: {
907 const method = this.createNode(node, {
908 type: !node.body
909 ? ts_estree_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression
910 : ts_estree_1.AST_NODE_TYPES.FunctionExpression,
911 id: null,
912 generator: !!node.asteriskToken,
913 expression: false,
914 async: (0, node_utils_1.hasModifier)(SyntaxKind.AsyncKeyword, node),
915 body: this.convertChild(node.body),
916 range: [node.parameters.pos - 1, node.end],
917 params: [],
918 });
919 if (node.type) {
920 method.returnType = this.convertTypeAnnotation(node.type, node);
921 }
922 // Process typeParameters
923 if (node.typeParameters) {
924 method.typeParameters =
925 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
926 this.fixParentLocation(method, method.typeParameters.range);
927 }
928 let result;
929 if (parent.kind === SyntaxKind.ObjectLiteralExpression) {
930 method.params = node.parameters.map(el => this.convertChild(el));
931 result = this.createNode(node, {
932 type: ts_estree_1.AST_NODE_TYPES.Property,
933 key: this.convertChild(node.name),
934 value: method,
935 computed: (0, node_utils_1.isComputedProperty)(node.name),
936 method: node.kind === SyntaxKind.MethodDeclaration,
937 shorthand: false,
938 kind: 'init',
939 });
940 }
941 else {
942 // class
943 /**
944 * Unlike in object literal methods, class method params can have decorators
945 */
946 method.params = this.convertParameters(node.parameters);
947 /**
948 * TypeScript class methods can be defined as "abstract"
949 */
950 const methodDefinitionType = (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node)
951 ? ts_estree_1.AST_NODE_TYPES.TSAbstractMethodDefinition
952 : ts_estree_1.AST_NODE_TYPES.MethodDefinition;
953 result = this.createNode(node, {
954 type: methodDefinitionType,
955 key: this.convertChild(node.name),
956 value: method,
957 computed: (0, node_utils_1.isComputedProperty)(node.name),
958 static: (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node),
959 kind: 'method',
960 override: (0, node_utils_1.hasModifier)(SyntaxKind.OverrideKeyword, node),
961 });
962 if (node.decorators) {
963 result.decorators = node.decorators.map(el => this.convertChild(el));
964 }
965 const accessibility = (0, node_utils_1.getTSNodeAccessibility)(node);
966 if (accessibility) {
967 result.accessibility = accessibility;
968 }
969 }
970 if (node.questionToken) {
971 result.optional = true;
972 }
973 if (node.kind === SyntaxKind.GetAccessor) {
974 result.kind = 'get';
975 }
976 else if (node.kind === SyntaxKind.SetAccessor) {
977 result.kind = 'set';
978 }
979 else if (!result.static &&
980 node.name.kind === SyntaxKind.StringLiteral &&
981 node.name.text === 'constructor' &&
982 result.type !== ts_estree_1.AST_NODE_TYPES.Property) {
983 result.kind = 'constructor';
984 }
985 return result;
986 }
987 // TypeScript uses this even for static methods named "constructor"
988 case SyntaxKind.Constructor: {
989 const lastModifier = (0, node_utils_1.getLastModifier)(node);
990 const constructorToken = (lastModifier && (0, node_utils_1.findNextToken)(lastModifier, node, this.ast)) ||
991 node.getFirstToken();
992 const constructor = this.createNode(node, {
993 type: !node.body
994 ? ts_estree_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression
995 : ts_estree_1.AST_NODE_TYPES.FunctionExpression,
996 id: null,
997 params: this.convertParameters(node.parameters),
998 generator: false,
999 expression: false,
1000 async: false,
1001 body: this.convertChild(node.body),
1002 range: [node.parameters.pos - 1, node.end],
1003 });
1004 // Process typeParameters
1005 if (node.typeParameters) {
1006 constructor.typeParameters =
1007 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1008 this.fixParentLocation(constructor, constructor.typeParameters.range);
1009 }
1010 // Process returnType
1011 if (node.type) {
1012 constructor.returnType = this.convertTypeAnnotation(node.type, node);
1013 }
1014 const constructorKey = this.createNode(node, {
1015 type: ts_estree_1.AST_NODE_TYPES.Identifier,
1016 name: 'constructor',
1017 range: [constructorToken.getStart(this.ast), constructorToken.end],
1018 });
1019 const isStatic = (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node);
1020 const result = this.createNode(node, {
1021 type: (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node)
1022 ? ts_estree_1.AST_NODE_TYPES.TSAbstractMethodDefinition
1023 : ts_estree_1.AST_NODE_TYPES.MethodDefinition,
1024 key: constructorKey,
1025 value: constructor,
1026 computed: false,
1027 static: isStatic,
1028 kind: isStatic ? 'method' : 'constructor',
1029 override: false,
1030 });
1031 const accessibility = (0, node_utils_1.getTSNodeAccessibility)(node);
1032 if (accessibility) {
1033 result.accessibility = accessibility;
1034 }
1035 return result;
1036 }
1037 case SyntaxKind.FunctionExpression: {
1038 const result = this.createNode(node, {
1039 type: ts_estree_1.AST_NODE_TYPES.FunctionExpression,
1040 id: this.convertChild(node.name),
1041 generator: !!node.asteriskToken,
1042 params: this.convertParameters(node.parameters),
1043 body: this.convertChild(node.body),
1044 async: (0, node_utils_1.hasModifier)(SyntaxKind.AsyncKeyword, node),
1045 expression: false,
1046 });
1047 // Process returnType
1048 if (node.type) {
1049 result.returnType = this.convertTypeAnnotation(node.type, node);
1050 }
1051 // Process typeParameters
1052 if (node.typeParameters) {
1053 result.typeParameters =
1054 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1055 }
1056 return result;
1057 }
1058 case SyntaxKind.SuperKeyword:
1059 return this.createNode(node, {
1060 type: ts_estree_1.AST_NODE_TYPES.Super,
1061 });
1062 case SyntaxKind.ArrayBindingPattern:
1063 return this.createNode(node, {
1064 type: ts_estree_1.AST_NODE_TYPES.ArrayPattern,
1065 elements: node.elements.map(el => this.convertPattern(el)),
1066 });
1067 // occurs with missing array elements like [,]
1068 case SyntaxKind.OmittedExpression:
1069 return null;
1070 case SyntaxKind.ObjectBindingPattern:
1071 return this.createNode(node, {
1072 type: ts_estree_1.AST_NODE_TYPES.ObjectPattern,
1073 properties: node.elements.map(el => this.convertPattern(el)),
1074 });
1075 case SyntaxKind.BindingElement: {
1076 if (parent.kind === SyntaxKind.ArrayBindingPattern) {
1077 const arrayItem = this.convertChild(node.name, parent);
1078 if (node.initializer) {
1079 return this.createNode(node, {
1080 type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
1081 left: arrayItem,
1082 right: this.convertChild(node.initializer),
1083 });
1084 }
1085 else if (node.dotDotDotToken) {
1086 return this.createNode(node, {
1087 type: ts_estree_1.AST_NODE_TYPES.RestElement,
1088 argument: arrayItem,
1089 });
1090 }
1091 else {
1092 return arrayItem;
1093 }
1094 }
1095 else {
1096 let result;
1097 if (node.dotDotDotToken) {
1098 result = this.createNode(node, {
1099 type: ts_estree_1.AST_NODE_TYPES.RestElement,
1100 argument: this.convertChild((_a = node.propertyName) !== null && _a !== void 0 ? _a : node.name),
1101 });
1102 }
1103 else {
1104 result = this.createNode(node, {
1105 type: ts_estree_1.AST_NODE_TYPES.Property,
1106 key: this.convertChild((_b = node.propertyName) !== null && _b !== void 0 ? _b : node.name),
1107 value: this.convertChild(node.name),
1108 computed: Boolean(node.propertyName &&
1109 node.propertyName.kind === SyntaxKind.ComputedPropertyName),
1110 method: false,
1111 shorthand: !node.propertyName,
1112 kind: 'init',
1113 });
1114 }
1115 if (node.initializer) {
1116 result.value = this.createNode(node, {
1117 type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
1118 left: this.convertChild(node.name),
1119 right: this.convertChild(node.initializer),
1120 range: [node.name.getStart(this.ast), node.initializer.end],
1121 });
1122 }
1123 return result;
1124 }
1125 }
1126 case SyntaxKind.ArrowFunction: {
1127 const result = this.createNode(node, {
1128 type: ts_estree_1.AST_NODE_TYPES.ArrowFunctionExpression,
1129 generator: false,
1130 id: null,
1131 params: this.convertParameters(node.parameters),
1132 body: this.convertChild(node.body),
1133 async: (0, node_utils_1.hasModifier)(SyntaxKind.AsyncKeyword, node),
1134 expression: node.body.kind !== SyntaxKind.Block,
1135 });
1136 // Process returnType
1137 if (node.type) {
1138 result.returnType = this.convertTypeAnnotation(node.type, node);
1139 }
1140 // Process typeParameters
1141 if (node.typeParameters) {
1142 result.typeParameters =
1143 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1144 }
1145 return result;
1146 }
1147 case SyntaxKind.YieldExpression:
1148 return this.createNode(node, {
1149 type: ts_estree_1.AST_NODE_TYPES.YieldExpression,
1150 delegate: !!node.asteriskToken,
1151 argument: this.convertChild(node.expression),
1152 });
1153 case SyntaxKind.AwaitExpression:
1154 return this.createNode(node, {
1155 type: ts_estree_1.AST_NODE_TYPES.AwaitExpression,
1156 argument: this.convertChild(node.expression),
1157 });
1158 // Template Literals
1159 case SyntaxKind.NoSubstitutionTemplateLiteral:
1160 return this.createNode(node, {
1161 type: ts_estree_1.AST_NODE_TYPES.TemplateLiteral,
1162 quasis: [
1163 this.createNode(node, {
1164 type: ts_estree_1.AST_NODE_TYPES.TemplateElement,
1165 value: {
1166 raw: this.ast.text.slice(node.getStart(this.ast) + 1, node.end - 1),
1167 cooked: node.text,
1168 },
1169 tail: true,
1170 }),
1171 ],
1172 expressions: [],
1173 });
1174 case SyntaxKind.TemplateExpression: {
1175 const result = this.createNode(node, {
1176 type: ts_estree_1.AST_NODE_TYPES.TemplateLiteral,
1177 quasis: [this.convertChild(node.head)],
1178 expressions: [],
1179 });
1180 node.templateSpans.forEach(templateSpan => {
1181 result.expressions.push(this.convertChild(templateSpan.expression));
1182 result.quasis.push(this.convertChild(templateSpan.literal));
1183 });
1184 return result;
1185 }
1186 case SyntaxKind.TaggedTemplateExpression:
1187 return this.createNode(node, {
1188 type: ts_estree_1.AST_NODE_TYPES.TaggedTemplateExpression,
1189 typeParameters: node.typeArguments
1190 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
1191 : undefined,
1192 tag: this.convertChild(node.tag),
1193 quasi: this.convertChild(node.template),
1194 });
1195 case SyntaxKind.TemplateHead:
1196 case SyntaxKind.TemplateMiddle:
1197 case SyntaxKind.TemplateTail: {
1198 const tail = node.kind === SyntaxKind.TemplateTail;
1199 return this.createNode(node, {
1200 type: ts_estree_1.AST_NODE_TYPES.TemplateElement,
1201 value: {
1202 raw: this.ast.text.slice(node.getStart(this.ast) + 1, node.end - (tail ? 1 : 2)),
1203 cooked: node.text,
1204 },
1205 tail,
1206 });
1207 }
1208 // Patterns
1209 case SyntaxKind.SpreadAssignment:
1210 case SyntaxKind.SpreadElement: {
1211 if (this.allowPattern) {
1212 return this.createNode(node, {
1213 type: ts_estree_1.AST_NODE_TYPES.RestElement,
1214 argument: this.convertPattern(node.expression),
1215 });
1216 }
1217 else {
1218 return this.createNode(node, {
1219 type: ts_estree_1.AST_NODE_TYPES.SpreadElement,
1220 argument: this.convertChild(node.expression),
1221 });
1222 }
1223 }
1224 case SyntaxKind.Parameter: {
1225 let parameter;
1226 let result;
1227 if (node.dotDotDotToken) {
1228 parameter = result = this.createNode(node, {
1229 type: ts_estree_1.AST_NODE_TYPES.RestElement,
1230 argument: this.convertChild(node.name),
1231 });
1232 }
1233 else if (node.initializer) {
1234 parameter = this.convertChild(node.name);
1235 result = this.createNode(node, {
1236 type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
1237 left: parameter,
1238 right: this.convertChild(node.initializer),
1239 });
1240 if (node.modifiers) {
1241 // AssignmentPattern should not contain modifiers in range
1242 result.range[0] = parameter.range[0];
1243 result.loc = (0, node_utils_1.getLocFor)(result.range[0], result.range[1], this.ast);
1244 }
1245 }
1246 else {
1247 parameter = result = this.convertChild(node.name, parent);
1248 }
1249 if (node.type) {
1250 parameter.typeAnnotation = this.convertTypeAnnotation(node.type, node);
1251 this.fixParentLocation(parameter, parameter.typeAnnotation.range);
1252 }
1253 if (node.questionToken) {
1254 if (node.questionToken.end > parameter.range[1]) {
1255 parameter.range[1] = node.questionToken.end;
1256 parameter.loc.end = (0, node_utils_1.getLineAndCharacterFor)(parameter.range[1], this.ast);
1257 }
1258 parameter.optional = true;
1259 }
1260 if (node.modifiers) {
1261 return this.createNode(node, {
1262 type: ts_estree_1.AST_NODE_TYPES.TSParameterProperty,
1263 accessibility: (_c = (0, node_utils_1.getTSNodeAccessibility)(node)) !== null && _c !== void 0 ? _c : undefined,
1264 readonly: (0, node_utils_1.hasModifier)(SyntaxKind.ReadonlyKeyword, node) || undefined,
1265 static: (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node) || undefined,
1266 export: (0, node_utils_1.hasModifier)(SyntaxKind.ExportKeyword, node) || undefined,
1267 override: (0, node_utils_1.hasModifier)(SyntaxKind.OverrideKeyword, node) || undefined,
1268 parameter: result,
1269 });
1270 }
1271 return result;
1272 }
1273 // Classes
1274 case SyntaxKind.ClassDeclaration:
1275 case SyntaxKind.ClassExpression: {
1276 const heritageClauses = (_d = node.heritageClauses) !== null && _d !== void 0 ? _d : [];
1277 const classNodeType = node.kind === SyntaxKind.ClassDeclaration
1278 ? ts_estree_1.AST_NODE_TYPES.ClassDeclaration
1279 : ts_estree_1.AST_NODE_TYPES.ClassExpression;
1280 const superClass = heritageClauses.find(clause => clause.token === SyntaxKind.ExtendsKeyword);
1281 const implementsClause = heritageClauses.find(clause => clause.token === SyntaxKind.ImplementsKeyword);
1282 const result = this.createNode(node, {
1283 type: classNodeType,
1284 id: this.convertChild(node.name),
1285 body: this.createNode(node, {
1286 type: ts_estree_1.AST_NODE_TYPES.ClassBody,
1287 body: [],
1288 range: [node.members.pos - 1, node.end],
1289 }),
1290 superClass: (superClass === null || superClass === void 0 ? void 0 : superClass.types[0])
1291 ? this.convertChild(superClass.types[0].expression)
1292 : null,
1293 });
1294 if (superClass) {
1295 if (superClass.types.length > 1) {
1296 throw (0, node_utils_1.createError)(this.ast, superClass.types[1].pos, 'Classes can only extend a single class.');
1297 }
1298 if ((_e = superClass.types[0]) === null || _e === void 0 ? void 0 : _e.typeArguments) {
1299 result.superTypeParameters =
1300 this.convertTypeArgumentsToTypeParameters(superClass.types[0].typeArguments, superClass.types[0]);
1301 }
1302 }
1303 if (node.typeParameters) {
1304 result.typeParameters =
1305 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1306 }
1307 if (implementsClause) {
1308 result.implements = implementsClause.types.map(el => this.convertChild(el));
1309 }
1310 /**
1311 * TypeScript class declarations can be defined as "abstract"
1312 */
1313 if ((0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node)) {
1314 result.abstract = true;
1315 }
1316 if ((0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node)) {
1317 result.declare = true;
1318 }
1319 if (node.decorators) {
1320 result.decorators = node.decorators.map(el => this.convertChild(el));
1321 }
1322 const filteredMembers = node.members.filter(node_utils_1.isESTreeClassMember);
1323 if (filteredMembers.length) {
1324 result.body.body = filteredMembers.map(el => this.convertChild(el));
1325 }
1326 // check for exports
1327 return this.fixExports(node, result);
1328 }
1329 // Modules
1330 case SyntaxKind.ModuleBlock:
1331 return this.createNode(node, {
1332 type: ts_estree_1.AST_NODE_TYPES.TSModuleBlock,
1333 body: this.convertBodyExpressions(node.statements, node),
1334 });
1335 case SyntaxKind.ImportDeclaration: {
1336 this.assertModuleSpecifier(node);
1337 const result = this.createNode(node, {
1338 type: ts_estree_1.AST_NODE_TYPES.ImportDeclaration,
1339 source: this.convertChild(node.moduleSpecifier),
1340 specifiers: [],
1341 importKind: 'value',
1342 assertions: this.convertAssertClasue(node.assertClause),
1343 });
1344 if (node.importClause) {
1345 if (node.importClause.isTypeOnly) {
1346 result.importKind = 'type';
1347 }
1348 if (node.importClause.name) {
1349 result.specifiers.push(this.convertChild(node.importClause));
1350 }
1351 if (node.importClause.namedBindings) {
1352 switch (node.importClause.namedBindings.kind) {
1353 case SyntaxKind.NamespaceImport:
1354 result.specifiers.push(this.convertChild(node.importClause.namedBindings));
1355 break;
1356 case SyntaxKind.NamedImports:
1357 result.specifiers = result.specifiers.concat(node.importClause.namedBindings.elements.map(el => this.convertChild(el)));
1358 break;
1359 }
1360 }
1361 }
1362 return result;
1363 }
1364 case SyntaxKind.NamespaceImport:
1365 return this.createNode(node, {
1366 type: ts_estree_1.AST_NODE_TYPES.ImportNamespaceSpecifier,
1367 local: this.convertChild(node.name),
1368 });
1369 case SyntaxKind.ImportSpecifier:
1370 return this.createNode(node, {
1371 type: ts_estree_1.AST_NODE_TYPES.ImportSpecifier,
1372 local: this.convertChild(node.name),
1373 imported: this.convertChild((_f = node.propertyName) !== null && _f !== void 0 ? _f : node.name),
1374 importKind: node.isTypeOnly ? 'type' : 'value',
1375 });
1376 case SyntaxKind.ImportClause: {
1377 const local = this.convertChild(node.name);
1378 return this.createNode(node, {
1379 type: ts_estree_1.AST_NODE_TYPES.ImportDefaultSpecifier,
1380 local,
1381 range: local.range,
1382 });
1383 }
1384 case SyntaxKind.ExportDeclaration: {
1385 this.assertModuleSpecifier(node);
1386 if (((_g = node.exportClause) === null || _g === void 0 ? void 0 : _g.kind) === SyntaxKind.NamedExports) {
1387 return this.createNode(node, {
1388 type: ts_estree_1.AST_NODE_TYPES.ExportNamedDeclaration,
1389 source: this.convertChild(node.moduleSpecifier),
1390 specifiers: node.exportClause.elements.map(el => this.convertChild(el)),
1391 exportKind: node.isTypeOnly ? 'type' : 'value',
1392 declaration: null,
1393 assertions: this.convertAssertClasue(node.assertClause),
1394 });
1395 }
1396 else {
1397 return this.createNode(node, {
1398 type: ts_estree_1.AST_NODE_TYPES.ExportAllDeclaration,
1399 source: this.convertChild(node.moduleSpecifier),
1400 exportKind: node.isTypeOnly ? 'type' : 'value',
1401 exported:
1402 // note - for compat with 3.7.x, where node.exportClause is always undefined and
1403 // SyntaxKind.NamespaceExport does not exist yet (i.e. is undefined), this
1404 // cannot be shortened to an optional chain, or else you end up with
1405 // undefined === undefined, and the true path will hard error at runtime
1406 node.exportClause &&
1407 node.exportClause.kind === SyntaxKind.NamespaceExport
1408 ? this.convertChild(node.exportClause.name)
1409 : null,
1410 assertions: this.convertAssertClasue(node.assertClause),
1411 });
1412 }
1413 }
1414 case SyntaxKind.ExportSpecifier:
1415 return this.createNode(node, {
1416 type: ts_estree_1.AST_NODE_TYPES.ExportSpecifier,
1417 local: this.convertChild((_h = node.propertyName) !== null && _h !== void 0 ? _h : node.name),
1418 exported: this.convertChild(node.name),
1419 exportKind: node.isTypeOnly ? 'type' : 'value',
1420 });
1421 case SyntaxKind.ExportAssignment:
1422 if (node.isExportEquals) {
1423 return this.createNode(node, {
1424 type: ts_estree_1.AST_NODE_TYPES.TSExportAssignment,
1425 expression: this.convertChild(node.expression),
1426 });
1427 }
1428 else {
1429 return this.createNode(node, {
1430 type: ts_estree_1.AST_NODE_TYPES.ExportDefaultDeclaration,
1431 declaration: this.convertChild(node.expression),
1432 exportKind: 'value',
1433 });
1434 }
1435 // Unary Operations
1436 case SyntaxKind.PrefixUnaryExpression:
1437 case SyntaxKind.PostfixUnaryExpression: {
1438 const operator = (0, node_utils_1.getTextForTokenKind)(node.operator);
1439 /**
1440 * ESTree uses UpdateExpression for ++/--
1441 */
1442 if (operator === '++' || operator === '--') {
1443 return this.createNode(node, {
1444 type: ts_estree_1.AST_NODE_TYPES.UpdateExpression,
1445 operator,
1446 prefix: node.kind === SyntaxKind.PrefixUnaryExpression,
1447 argument: this.convertChild(node.operand),
1448 });
1449 }
1450 else {
1451 return this.createNode(node, {
1452 type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1453 operator,
1454 prefix: node.kind === SyntaxKind.PrefixUnaryExpression,
1455 argument: this.convertChild(node.operand),
1456 });
1457 }
1458 }
1459 case SyntaxKind.DeleteExpression:
1460 return this.createNode(node, {
1461 type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1462 operator: 'delete',
1463 prefix: true,
1464 argument: this.convertChild(node.expression),
1465 });
1466 case SyntaxKind.VoidExpression:
1467 return this.createNode(node, {
1468 type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1469 operator: 'void',
1470 prefix: true,
1471 argument: this.convertChild(node.expression),
1472 });
1473 case SyntaxKind.TypeOfExpression:
1474 return this.createNode(node, {
1475 type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1476 operator: 'typeof',
1477 prefix: true,
1478 argument: this.convertChild(node.expression),
1479 });
1480 case SyntaxKind.TypeOperator:
1481 return this.createNode(node, {
1482 type: ts_estree_1.AST_NODE_TYPES.TSTypeOperator,
1483 operator: (0, node_utils_1.getTextForTokenKind)(node.operator),
1484 typeAnnotation: this.convertChild(node.type),
1485 });
1486 // Binary Operations
1487 case SyntaxKind.BinaryExpression: {
1488 // TypeScript uses BinaryExpression for sequences as well
1489 if ((0, node_utils_1.isComma)(node.operatorToken)) {
1490 const result = this.createNode(node, {
1491 type: ts_estree_1.AST_NODE_TYPES.SequenceExpression,
1492 expressions: [],
1493 });
1494 const left = this.convertChild(node.left);
1495 if (left.type === ts_estree_1.AST_NODE_TYPES.SequenceExpression &&
1496 node.left.kind !== SyntaxKind.ParenthesizedExpression) {
1497 result.expressions = result.expressions.concat(left.expressions);
1498 }
1499 else {
1500 result.expressions.push(left);
1501 }
1502 result.expressions.push(this.convertChild(node.right));
1503 return result;
1504 }
1505 else {
1506 const type = (0, node_utils_1.getBinaryExpressionType)(node.operatorToken);
1507 if (this.allowPattern &&
1508 type === ts_estree_1.AST_NODE_TYPES.AssignmentExpression) {
1509 return this.createNode(node, {
1510 type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
1511 left: this.convertPattern(node.left, node),
1512 right: this.convertChild(node.right),
1513 });
1514 }
1515 return this.createNode(node, {
1516 type,
1517 operator: (0, node_utils_1.getTextForTokenKind)(node.operatorToken.kind),
1518 left: this.converter(node.left, node, this.inTypeMode, type === ts_estree_1.AST_NODE_TYPES.AssignmentExpression),
1519 right: this.convertChild(node.right),
1520 });
1521 }
1522 }
1523 case SyntaxKind.PropertyAccessExpression: {
1524 const object = this.convertChild(node.expression);
1525 const property = this.convertChild(node.name);
1526 const computed = false;
1527 const result = this.createNode(node, {
1528 type: ts_estree_1.AST_NODE_TYPES.MemberExpression,
1529 object,
1530 property,
1531 computed,
1532 optional: node.questionDotToken !== undefined,
1533 });
1534 return this.convertChainExpression(result, node);
1535 }
1536 case SyntaxKind.ElementAccessExpression: {
1537 const object = this.convertChild(node.expression);
1538 const property = this.convertChild(node.argumentExpression);
1539 const computed = true;
1540 const result = this.createNode(node, {
1541 type: ts_estree_1.AST_NODE_TYPES.MemberExpression,
1542 object,
1543 property,
1544 computed,
1545 optional: node.questionDotToken !== undefined,
1546 });
1547 return this.convertChainExpression(result, node);
1548 }
1549 case SyntaxKind.CallExpression: {
1550 if (node.expression.kind === SyntaxKind.ImportKeyword) {
1551 if (node.arguments.length !== 1 && node.arguments.length !== 2) {
1552 throw (0, node_utils_1.createError)(this.ast, node.arguments.pos, 'Dynamic import requires exactly one or two arguments.');
1553 }
1554 return this.createNode(node, {
1555 type: ts_estree_1.AST_NODE_TYPES.ImportExpression,
1556 source: this.convertChild(node.arguments[0]),
1557 attributes: node.arguments[1]
1558 ? this.convertChild(node.arguments[1])
1559 : null,
1560 });
1561 }
1562 const callee = this.convertChild(node.expression);
1563 const args = node.arguments.map(el => this.convertChild(el));
1564 const result = this.createNode(node, {
1565 type: ts_estree_1.AST_NODE_TYPES.CallExpression,
1566 callee,
1567 arguments: args,
1568 optional: node.questionDotToken !== undefined,
1569 });
1570 if (node.typeArguments) {
1571 result.typeParameters = this.convertTypeArgumentsToTypeParameters(node.typeArguments, node);
1572 }
1573 return this.convertChainExpression(result, node);
1574 }
1575 case SyntaxKind.NewExpression: {
1576 // NOTE - NewExpression cannot have an optional chain in it
1577 const result = this.createNode(node, {
1578 type: ts_estree_1.AST_NODE_TYPES.NewExpression,
1579 callee: this.convertChild(node.expression),
1580 arguments: node.arguments
1581 ? node.arguments.map(el => this.convertChild(el))
1582 : [],
1583 });
1584 if (node.typeArguments) {
1585 result.typeParameters = this.convertTypeArgumentsToTypeParameters(node.typeArguments, node);
1586 }
1587 return result;
1588 }
1589 case SyntaxKind.ConditionalExpression:
1590 return this.createNode(node, {
1591 type: ts_estree_1.AST_NODE_TYPES.ConditionalExpression,
1592 test: this.convertChild(node.condition),
1593 consequent: this.convertChild(node.whenTrue),
1594 alternate: this.convertChild(node.whenFalse),
1595 });
1596 case SyntaxKind.MetaProperty: {
1597 return this.createNode(node, {
1598 type: ts_estree_1.AST_NODE_TYPES.MetaProperty,
1599 meta: this.createNode(
1600 // TODO: do we really want to convert it to Token?
1601 node.getFirstToken(), {
1602 type: ts_estree_1.AST_NODE_TYPES.Identifier,
1603 name: (0, node_utils_1.getTextForTokenKind)(node.keywordToken),
1604 }),
1605 property: this.convertChild(node.name),
1606 });
1607 }
1608 case SyntaxKind.Decorator: {
1609 return this.createNode(node, {
1610 type: ts_estree_1.AST_NODE_TYPES.Decorator,
1611 expression: this.convertChild(node.expression),
1612 });
1613 }
1614 // Literals
1615 case SyntaxKind.StringLiteral: {
1616 return this.createNode(node, {
1617 type: ts_estree_1.AST_NODE_TYPES.Literal,
1618 value: parent.kind === SyntaxKind.JsxAttribute
1619 ? (0, node_utils_1.unescapeStringLiteralText)(node.text)
1620 : node.text,
1621 raw: node.getText(),
1622 });
1623 }
1624 case SyntaxKind.NumericLiteral: {
1625 return this.createNode(node, {
1626 type: ts_estree_1.AST_NODE_TYPES.Literal,
1627 value: Number(node.text),
1628 raw: node.getText(),
1629 });
1630 }
1631 case SyntaxKind.BigIntLiteral: {
1632 const range = (0, node_utils_1.getRange)(node, this.ast);
1633 const rawValue = this.ast.text.slice(range[0], range[1]);
1634 const bigint = rawValue
1635 // remove suffix `n`
1636 .slice(0, -1)
1637 // `BigInt` doesn't accept numeric separator
1638 // and `bigint` property should not include numeric separator
1639 .replace(/_/g, '');
1640 const value = typeof BigInt !== 'undefined' ? BigInt(bigint) : null;
1641 return this.createNode(node, {
1642 type: ts_estree_1.AST_NODE_TYPES.Literal,
1643 raw: rawValue,
1644 value: value,
1645 bigint: value === null ? bigint : String(value),
1646 range,
1647 });
1648 }
1649 case SyntaxKind.RegularExpressionLiteral: {
1650 const pattern = node.text.slice(1, node.text.lastIndexOf('/'));
1651 const flags = node.text.slice(node.text.lastIndexOf('/') + 1);
1652 let regex = null;
1653 try {
1654 regex = new RegExp(pattern, flags);
1655 }
1656 catch (exception) {
1657 regex = null;
1658 }
1659 return this.createNode(node, {
1660 type: ts_estree_1.AST_NODE_TYPES.Literal,
1661 value: regex,
1662 raw: node.text,
1663 regex: {
1664 pattern,
1665 flags,
1666 },
1667 });
1668 }
1669 case SyntaxKind.TrueKeyword:
1670 return this.createNode(node, {
1671 type: ts_estree_1.AST_NODE_TYPES.Literal,
1672 value: true,
1673 raw: 'true',
1674 });
1675 case SyntaxKind.FalseKeyword:
1676 return this.createNode(node, {
1677 type: ts_estree_1.AST_NODE_TYPES.Literal,
1678 value: false,
1679 raw: 'false',
1680 });
1681 case SyntaxKind.NullKeyword: {
1682 if (!version_check_1.typescriptVersionIsAtLeast['4.0'] && this.inTypeMode) {
1683 // 4.0 started nesting null types inside a LiteralType node, but we still need to support pre-4.0
1684 return this.createNode(node, {
1685 type: ts_estree_1.AST_NODE_TYPES.TSNullKeyword,
1686 });
1687 }
1688 return this.createNode(node, {
1689 type: ts_estree_1.AST_NODE_TYPES.Literal,
1690 value: null,
1691 raw: 'null',
1692 });
1693 }
1694 case SyntaxKind.EmptyStatement:
1695 return this.createNode(node, {
1696 type: ts_estree_1.AST_NODE_TYPES.EmptyStatement,
1697 });
1698 case SyntaxKind.DebuggerStatement:
1699 return this.createNode(node, {
1700 type: ts_estree_1.AST_NODE_TYPES.DebuggerStatement,
1701 });
1702 // JSX
1703 case SyntaxKind.JsxElement:
1704 return this.createNode(node, {
1705 type: ts_estree_1.AST_NODE_TYPES.JSXElement,
1706 openingElement: this.convertChild(node.openingElement),
1707 closingElement: this.convertChild(node.closingElement),
1708 children: node.children.map(el => this.convertChild(el)),
1709 });
1710 case SyntaxKind.JsxFragment:
1711 return this.createNode(node, {
1712 type: ts_estree_1.AST_NODE_TYPES.JSXFragment,
1713 openingFragment: this.convertChild(node.openingFragment),
1714 closingFragment: this.convertChild(node.closingFragment),
1715 children: node.children.map(el => this.convertChild(el)),
1716 });
1717 case SyntaxKind.JsxSelfClosingElement: {
1718 return this.createNode(node, {
1719 type: ts_estree_1.AST_NODE_TYPES.JSXElement,
1720 /**
1721 * Convert SyntaxKind.JsxSelfClosingElement to SyntaxKind.JsxOpeningElement,
1722 * TypeScript does not seem to have the idea of openingElement when tag is self-closing
1723 */
1724 openingElement: this.createNode(node, {
1725 type: ts_estree_1.AST_NODE_TYPES.JSXOpeningElement,
1726 typeParameters: node.typeArguments
1727 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
1728 : undefined,
1729 selfClosing: true,
1730 name: this.convertJSXTagName(node.tagName, node),
1731 attributes: node.attributes.properties.map(el => this.convertChild(el)),
1732 range: (0, node_utils_1.getRange)(node, this.ast),
1733 }),
1734 closingElement: null,
1735 children: [],
1736 });
1737 }
1738 case SyntaxKind.JsxOpeningElement:
1739 return this.createNode(node, {
1740 type: ts_estree_1.AST_NODE_TYPES.JSXOpeningElement,
1741 typeParameters: node.typeArguments
1742 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
1743 : undefined,
1744 selfClosing: false,
1745 name: this.convertJSXTagName(node.tagName, node),
1746 attributes: node.attributes.properties.map(el => this.convertChild(el)),
1747 });
1748 case SyntaxKind.JsxClosingElement:
1749 return this.createNode(node, {
1750 type: ts_estree_1.AST_NODE_TYPES.JSXClosingElement,
1751 name: this.convertJSXTagName(node.tagName, node),
1752 });
1753 case SyntaxKind.JsxOpeningFragment:
1754 return this.createNode(node, {
1755 type: ts_estree_1.AST_NODE_TYPES.JSXOpeningFragment,
1756 });
1757 case SyntaxKind.JsxClosingFragment:
1758 return this.createNode(node, {
1759 type: ts_estree_1.AST_NODE_TYPES.JSXClosingFragment,
1760 });
1761 case SyntaxKind.JsxExpression: {
1762 const expression = node.expression
1763 ? this.convertChild(node.expression)
1764 : this.createNode(node, {
1765 type: ts_estree_1.AST_NODE_TYPES.JSXEmptyExpression,
1766 range: [node.getStart(this.ast) + 1, node.getEnd() - 1],
1767 });
1768 if (node.dotDotDotToken) {
1769 return this.createNode(node, {
1770 type: ts_estree_1.AST_NODE_TYPES.JSXSpreadChild,
1771 expression,
1772 });
1773 }
1774 else {
1775 return this.createNode(node, {
1776 type: ts_estree_1.AST_NODE_TYPES.JSXExpressionContainer,
1777 expression,
1778 });
1779 }
1780 }
1781 case SyntaxKind.JsxAttribute: {
1782 return this.createNode(node, {
1783 type: ts_estree_1.AST_NODE_TYPES.JSXAttribute,
1784 name: this.convertJSXNamespaceOrIdentifier(node.name),
1785 value: this.convertChild(node.initializer),
1786 });
1787 }
1788 case SyntaxKind.JsxText: {
1789 const start = node.getFullStart();
1790 const end = node.getEnd();
1791 const text = this.ast.text.slice(start, end);
1792 return this.createNode(node, {
1793 type: ts_estree_1.AST_NODE_TYPES.JSXText,
1794 value: (0, node_utils_1.unescapeStringLiteralText)(text),
1795 raw: text,
1796 range: [start, end],
1797 });
1798 }
1799 case SyntaxKind.JsxSpreadAttribute:
1800 return this.createNode(node, {
1801 type: ts_estree_1.AST_NODE_TYPES.JSXSpreadAttribute,
1802 argument: this.convertChild(node.expression),
1803 });
1804 case SyntaxKind.QualifiedName: {
1805 return this.createNode(node, {
1806 type: ts_estree_1.AST_NODE_TYPES.TSQualifiedName,
1807 left: this.convertChild(node.left),
1808 right: this.convertChild(node.right),
1809 });
1810 }
1811 // TypeScript specific
1812 case SyntaxKind.TypeReference: {
1813 return this.createNode(node, {
1814 type: ts_estree_1.AST_NODE_TYPES.TSTypeReference,
1815 typeName: this.convertType(node.typeName),
1816 typeParameters: node.typeArguments
1817 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
1818 : undefined,
1819 });
1820 }
1821 case SyntaxKind.TypeParameter: {
1822 return this.createNode(node, {
1823 type: ts_estree_1.AST_NODE_TYPES.TSTypeParameter,
1824 name: this.convertType(node.name),
1825 constraint: node.constraint
1826 ? this.convertType(node.constraint)
1827 : undefined,
1828 default: node.default ? this.convertType(node.default) : undefined,
1829 });
1830 }
1831 case SyntaxKind.ThisType:
1832 return this.createNode(node, {
1833 type: ts_estree_1.AST_NODE_TYPES.TSThisType,
1834 });
1835 case SyntaxKind.AnyKeyword:
1836 case SyntaxKind.BigIntKeyword:
1837 case SyntaxKind.BooleanKeyword:
1838 case SyntaxKind.NeverKeyword:
1839 case SyntaxKind.NumberKeyword:
1840 case SyntaxKind.ObjectKeyword:
1841 case SyntaxKind.StringKeyword:
1842 case SyntaxKind.SymbolKeyword:
1843 case SyntaxKind.UnknownKeyword:
1844 case SyntaxKind.VoidKeyword:
1845 case SyntaxKind.UndefinedKeyword:
1846 case SyntaxKind.IntrinsicKeyword: {
1847 return this.createNode(node, {
1848 type: ts_estree_1.AST_NODE_TYPES[`TS${SyntaxKind[node.kind]}`],
1849 });
1850 }
1851 case SyntaxKind.NonNullExpression: {
1852 const nnExpr = this.createNode(node, {
1853 type: ts_estree_1.AST_NODE_TYPES.TSNonNullExpression,
1854 expression: this.convertChild(node.expression),
1855 });
1856 return this.convertChainExpression(nnExpr, node);
1857 }
1858 case SyntaxKind.TypeLiteral: {
1859 return this.createNode(node, {
1860 type: ts_estree_1.AST_NODE_TYPES.TSTypeLiteral,
1861 members: node.members.map(el => this.convertChild(el)),
1862 });
1863 }
1864 case SyntaxKind.ArrayType: {
1865 return this.createNode(node, {
1866 type: ts_estree_1.AST_NODE_TYPES.TSArrayType,
1867 elementType: this.convertType(node.elementType),
1868 });
1869 }
1870 case SyntaxKind.IndexedAccessType: {
1871 return this.createNode(node, {
1872 type: ts_estree_1.AST_NODE_TYPES.TSIndexedAccessType,
1873 objectType: this.convertType(node.objectType),
1874 indexType: this.convertType(node.indexType),
1875 });
1876 }
1877 case SyntaxKind.ConditionalType: {
1878 return this.createNode(node, {
1879 type: ts_estree_1.AST_NODE_TYPES.TSConditionalType,
1880 checkType: this.convertType(node.checkType),
1881 extendsType: this.convertType(node.extendsType),
1882 trueType: this.convertType(node.trueType),
1883 falseType: this.convertType(node.falseType),
1884 });
1885 }
1886 case SyntaxKind.TypeQuery: {
1887 return this.createNode(node, {
1888 type: ts_estree_1.AST_NODE_TYPES.TSTypeQuery,
1889 exprName: this.convertType(node.exprName),
1890 });
1891 }
1892 case SyntaxKind.MappedType: {
1893 const result = this.createNode(node, {
1894 type: ts_estree_1.AST_NODE_TYPES.TSMappedType,
1895 typeParameter: this.convertType(node.typeParameter),
1896 nameType: (_j = this.convertType(node.nameType)) !== null && _j !== void 0 ? _j : null,
1897 });
1898 if (node.readonlyToken) {
1899 if (node.readonlyToken.kind === SyntaxKind.ReadonlyKeyword) {
1900 result.readonly = true;
1901 }
1902 else {
1903 result.readonly = (0, node_utils_1.getTextForTokenKind)(node.readonlyToken.kind);
1904 }
1905 }
1906 if (node.questionToken) {
1907 if (node.questionToken.kind === SyntaxKind.QuestionToken) {
1908 result.optional = true;
1909 }
1910 else {
1911 result.optional = (0, node_utils_1.getTextForTokenKind)(node.questionToken.kind);
1912 }
1913 }
1914 if (node.type) {
1915 result.typeAnnotation = this.convertType(node.type);
1916 }
1917 return result;
1918 }
1919 case SyntaxKind.ParenthesizedExpression:
1920 return this.convertChild(node.expression, parent);
1921 case SyntaxKind.TypeAliasDeclaration: {
1922 const result = this.createNode(node, {
1923 type: ts_estree_1.AST_NODE_TYPES.TSTypeAliasDeclaration,
1924 id: this.convertChild(node.name),
1925 typeAnnotation: this.convertType(node.type),
1926 });
1927 if ((0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node)) {
1928 result.declare = true;
1929 }
1930 // Process typeParameters
1931 if (node.typeParameters) {
1932 result.typeParameters =
1933 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1934 }
1935 // check for exports
1936 return this.fixExports(node, result);
1937 }
1938 case SyntaxKind.MethodSignature: {
1939 return this.convertMethodSignature(node);
1940 }
1941 case SyntaxKind.PropertySignature: {
1942 const result = this.createNode(node, {
1943 type: ts_estree_1.AST_NODE_TYPES.TSPropertySignature,
1944 optional: (0, node_utils_1.isOptional)(node) || undefined,
1945 computed: (0, node_utils_1.isComputedProperty)(node.name),
1946 key: this.convertChild(node.name),
1947 typeAnnotation: node.type
1948 ? this.convertTypeAnnotation(node.type, node)
1949 : undefined,
1950 initializer: this.convertChild(node.initializer) || undefined,
1951 readonly: (0, node_utils_1.hasModifier)(SyntaxKind.ReadonlyKeyword, node) || undefined,
1952 static: (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node) || undefined,
1953 export: (0, node_utils_1.hasModifier)(SyntaxKind.ExportKeyword, node) || undefined,
1954 });
1955 const accessibility = (0, node_utils_1.getTSNodeAccessibility)(node);
1956 if (accessibility) {
1957 result.accessibility = accessibility;
1958 }
1959 return result;
1960 }
1961 case SyntaxKind.IndexSignature: {
1962 const result = this.createNode(node, {
1963 type: ts_estree_1.AST_NODE_TYPES.TSIndexSignature,
1964 parameters: node.parameters.map(el => this.convertChild(el)),
1965 });
1966 if (node.type) {
1967 result.typeAnnotation = this.convertTypeAnnotation(node.type, node);
1968 }
1969 if ((0, node_utils_1.hasModifier)(SyntaxKind.ReadonlyKeyword, node)) {
1970 result.readonly = true;
1971 }
1972 const accessibility = (0, node_utils_1.getTSNodeAccessibility)(node);
1973 if (accessibility) {
1974 result.accessibility = accessibility;
1975 }
1976 if ((0, node_utils_1.hasModifier)(SyntaxKind.ExportKeyword, node)) {
1977 result.export = true;
1978 }
1979 if ((0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node)) {
1980 result.static = true;
1981 }
1982 return result;
1983 }
1984 case SyntaxKind.ConstructorType: {
1985 const result = this.createNode(node, {
1986 type: ts_estree_1.AST_NODE_TYPES.TSConstructorType,
1987 params: this.convertParameters(node.parameters),
1988 abstract: (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node),
1989 });
1990 if (node.type) {
1991 result.returnType = this.convertTypeAnnotation(node.type, node);
1992 }
1993 if (node.typeParameters) {
1994 result.typeParameters =
1995 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
1996 }
1997 return result;
1998 }
1999 case SyntaxKind.FunctionType:
2000 case SyntaxKind.ConstructSignature:
2001 case SyntaxKind.CallSignature: {
2002 const type = node.kind === SyntaxKind.ConstructSignature
2003 ? ts_estree_1.AST_NODE_TYPES.TSConstructSignatureDeclaration
2004 : node.kind === SyntaxKind.CallSignature
2005 ? ts_estree_1.AST_NODE_TYPES.TSCallSignatureDeclaration
2006 : ts_estree_1.AST_NODE_TYPES.TSFunctionType;
2007 const result = this.createNode(node, {
2008 type: type,
2009 params: this.convertParameters(node.parameters),
2010 });
2011 if (node.type) {
2012 result.returnType = this.convertTypeAnnotation(node.type, node);
2013 }
2014 if (node.typeParameters) {
2015 result.typeParameters =
2016 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
2017 }
2018 return result;
2019 }
2020 case SyntaxKind.ExpressionWithTypeArguments: {
2021 const result = this.createNode(node, {
2022 type: parent && parent.kind === SyntaxKind.InterfaceDeclaration
2023 ? ts_estree_1.AST_NODE_TYPES.TSInterfaceHeritage
2024 : ts_estree_1.AST_NODE_TYPES.TSClassImplements,
2025 expression: this.convertChild(node.expression),
2026 });
2027 if (node.typeArguments) {
2028 result.typeParameters = this.convertTypeArgumentsToTypeParameters(node.typeArguments, node);
2029 }
2030 return result;
2031 }
2032 case SyntaxKind.InterfaceDeclaration: {
2033 const interfaceHeritageClauses = (_k = node.heritageClauses) !== null && _k !== void 0 ? _k : [];
2034 const result = this.createNode(node, {
2035 type: ts_estree_1.AST_NODE_TYPES.TSInterfaceDeclaration,
2036 body: this.createNode(node, {
2037 type: ts_estree_1.AST_NODE_TYPES.TSInterfaceBody,
2038 body: node.members.map(member => this.convertChild(member)),
2039 range: [node.members.pos - 1, node.end],
2040 }),
2041 id: this.convertChild(node.name),
2042 });
2043 if (node.typeParameters) {
2044 result.typeParameters =
2045 this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters);
2046 }
2047 if (interfaceHeritageClauses.length > 0) {
2048 const interfaceExtends = [];
2049 const interfaceImplements = [];
2050 for (const heritageClause of interfaceHeritageClauses) {
2051 if (heritageClause.token === SyntaxKind.ExtendsKeyword) {
2052 for (const n of heritageClause.types) {
2053 interfaceExtends.push(this.convertChild(n, node));
2054 }
2055 }
2056 else {
2057 for (const n of heritageClause.types) {
2058 interfaceImplements.push(this.convertChild(n, node));
2059 }
2060 }
2061 }
2062 if (interfaceExtends.length) {
2063 result.extends = interfaceExtends;
2064 }
2065 if (interfaceImplements.length) {
2066 result.implements = interfaceImplements;
2067 }
2068 }
2069 if ((0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node)) {
2070 result.abstract = true;
2071 }
2072 if ((0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node)) {
2073 result.declare = true;
2074 }
2075 // check for exports
2076 return this.fixExports(node, result);
2077 }
2078 case SyntaxKind.TypePredicate: {
2079 const result = this.createNode(node, {
2080 type: ts_estree_1.AST_NODE_TYPES.TSTypePredicate,
2081 asserts: node.assertsModifier !== undefined,
2082 parameterName: this.convertChild(node.parameterName),
2083 typeAnnotation: null,
2084 });
2085 /**
2086 * Specific fix for type-guard location data
2087 */
2088 if (node.type) {
2089 result.typeAnnotation = this.convertTypeAnnotation(node.type, node);
2090 result.typeAnnotation.loc = result.typeAnnotation.typeAnnotation.loc;
2091 result.typeAnnotation.range =
2092 result.typeAnnotation.typeAnnotation.range;
2093 }
2094 return result;
2095 }
2096 case SyntaxKind.ImportType:
2097 return this.createNode(node, {
2098 type: ts_estree_1.AST_NODE_TYPES.TSImportType,
2099 isTypeOf: !!node.isTypeOf,
2100 parameter: this.convertChild(node.argument),
2101 qualifier: this.convertChild(node.qualifier),
2102 typeParameters: node.typeArguments
2103 ? this.convertTypeArgumentsToTypeParameters(node.typeArguments, node)
2104 : null,
2105 });
2106 case SyntaxKind.EnumDeclaration: {
2107 const result = this.createNode(node, {
2108 type: ts_estree_1.AST_NODE_TYPES.TSEnumDeclaration,
2109 id: this.convertChild(node.name),
2110 members: node.members.map(el => this.convertChild(el)),
2111 });
2112 // apply modifiers first...
2113 this.applyModifiersToResult(result, node.modifiers);
2114 // ...then check for exports
2115 return this.fixExports(node, result);
2116 }
2117 case SyntaxKind.EnumMember: {
2118 const result = this.createNode(node, {
2119 type: ts_estree_1.AST_NODE_TYPES.TSEnumMember,
2120 id: this.convertChild(node.name),
2121 });
2122 if (node.initializer) {
2123 result.initializer = this.convertChild(node.initializer);
2124 }
2125 if (node.name.kind === ts.SyntaxKind.ComputedPropertyName) {
2126 result.computed = true;
2127 }
2128 return result;
2129 }
2130 case SyntaxKind.ModuleDeclaration: {
2131 const result = this.createNode(node, {
2132 type: ts_estree_1.AST_NODE_TYPES.TSModuleDeclaration,
2133 id: this.convertChild(node.name),
2134 });
2135 if (node.body) {
2136 result.body = this.convertChild(node.body);
2137 }
2138 // apply modifiers first...
2139 this.applyModifiersToResult(result, node.modifiers);
2140 if (node.flags & ts.NodeFlags.GlobalAugmentation) {
2141 result.global = true;
2142 }
2143 // ...then check for exports
2144 return this.fixExports(node, result);
2145 }
2146 // TypeScript specific types
2147 case SyntaxKind.ParenthesizedType: {
2148 return this.convertType(node.type);
2149 }
2150 case SyntaxKind.UnionType: {
2151 return this.createNode(node, {
2152 type: ts_estree_1.AST_NODE_TYPES.TSUnionType,
2153 types: node.types.map(el => this.convertType(el)),
2154 });
2155 }
2156 case SyntaxKind.IntersectionType: {
2157 return this.createNode(node, {
2158 type: ts_estree_1.AST_NODE_TYPES.TSIntersectionType,
2159 types: node.types.map(el => this.convertType(el)),
2160 });
2161 }
2162 case SyntaxKind.AsExpression: {
2163 return this.createNode(node, {
2164 type: ts_estree_1.AST_NODE_TYPES.TSAsExpression,
2165 expression: this.convertChild(node.expression),
2166 typeAnnotation: this.convertType(node.type),
2167 });
2168 }
2169 case SyntaxKind.InferType: {
2170 return this.createNode(node, {
2171 type: ts_estree_1.AST_NODE_TYPES.TSInferType,
2172 typeParameter: this.convertType(node.typeParameter),
2173 });
2174 }
2175 case SyntaxKind.LiteralType: {
2176 if (version_check_1.typescriptVersionIsAtLeast['4.0'] &&
2177 node.literal.kind === SyntaxKind.NullKeyword) {
2178 // 4.0 started nesting null types inside a LiteralType node
2179 // but our AST is designed around the old way of null being a keyword
2180 return this.createNode(node.literal, {
2181 type: ts_estree_1.AST_NODE_TYPES.TSNullKeyword,
2182 });
2183 }
2184 else {
2185 return this.createNode(node, {
2186 type: ts_estree_1.AST_NODE_TYPES.TSLiteralType,
2187 literal: this.convertType(node.literal),
2188 });
2189 }
2190 }
2191 case SyntaxKind.TypeAssertionExpression: {
2192 return this.createNode(node, {
2193 type: ts_estree_1.AST_NODE_TYPES.TSTypeAssertion,
2194 typeAnnotation: this.convertType(node.type),
2195 expression: this.convertChild(node.expression),
2196 });
2197 }
2198 case SyntaxKind.ImportEqualsDeclaration: {
2199 return this.createNode(node, {
2200 type: ts_estree_1.AST_NODE_TYPES.TSImportEqualsDeclaration,
2201 id: this.convertChild(node.name),
2202 moduleReference: this.convertChild(node.moduleReference),
2203 importKind: node.isTypeOnly ? 'type' : 'value',
2204 isExport: (0, node_utils_1.hasModifier)(SyntaxKind.ExportKeyword, node),
2205 });
2206 }
2207 case SyntaxKind.ExternalModuleReference: {
2208 return this.createNode(node, {
2209 type: ts_estree_1.AST_NODE_TYPES.TSExternalModuleReference,
2210 expression: this.convertChild(node.expression),
2211 });
2212 }
2213 case SyntaxKind.NamespaceExportDeclaration: {
2214 return this.createNode(node, {
2215 type: ts_estree_1.AST_NODE_TYPES.TSNamespaceExportDeclaration,
2216 id: this.convertChild(node.name),
2217 });
2218 }
2219 case SyntaxKind.AbstractKeyword: {
2220 return this.createNode(node, {
2221 type: ts_estree_1.AST_NODE_TYPES.TSAbstractKeyword,
2222 });
2223 }
2224 // Tuple
2225 case SyntaxKind.TupleType: {
2226 // In TS 4.0, the `elementTypes` property was changed to `elements`.
2227 // To support both at compile time, we cast to access the newer version
2228 // if the former does not exist.
2229 const elementTypes = 'elementTypes' in node
2230 ? node.elementTypes.map((el) => this.convertType(el))
2231 : node.elements.map(el => this.convertType(el));
2232 return this.createNode(node, {
2233 type: ts_estree_1.AST_NODE_TYPES.TSTupleType,
2234 elementTypes,
2235 });
2236 }
2237 case SyntaxKind.NamedTupleMember: {
2238 const member = this.createNode(node, {
2239 type: ts_estree_1.AST_NODE_TYPES.TSNamedTupleMember,
2240 elementType: this.convertType(node.type, node),
2241 label: this.convertChild(node.name, node),
2242 optional: node.questionToken != null,
2243 });
2244 if (node.dotDotDotToken) {
2245 // adjust the start to account for the "..."
2246 member.range[0] = member.label.range[0];
2247 member.loc.start = member.label.loc.start;
2248 return this.createNode(node, {
2249 type: ts_estree_1.AST_NODE_TYPES.TSRestType,
2250 typeAnnotation: member,
2251 });
2252 }
2253 return member;
2254 }
2255 case SyntaxKind.OptionalType: {
2256 return this.createNode(node, {
2257 type: ts_estree_1.AST_NODE_TYPES.TSOptionalType,
2258 typeAnnotation: this.convertType(node.type),
2259 });
2260 }
2261 case SyntaxKind.RestType: {
2262 return this.createNode(node, {
2263 type: ts_estree_1.AST_NODE_TYPES.TSRestType,
2264 typeAnnotation: this.convertType(node.type),
2265 });
2266 }
2267 // Template Literal Types
2268 case SyntaxKind.TemplateLiteralType: {
2269 const result = this.createNode(node, {
2270 type: ts_estree_1.AST_NODE_TYPES.TSTemplateLiteralType,
2271 quasis: [this.convertChild(node.head)],
2272 types: [],
2273 });
2274 node.templateSpans.forEach(templateSpan => {
2275 result.types.push(this.convertChild(templateSpan.type));
2276 result.quasis.push(this.convertChild(templateSpan.literal));
2277 });
2278 return result;
2279 }
2280 case SyntaxKind.ClassStaticBlockDeclaration: {
2281 return this.createNode(node, {
2282 type: ts_estree_1.AST_NODE_TYPES.StaticBlock,
2283 body: this.convertBodyExpressions(node.body.statements, node),
2284 });
2285 }
2286 case SyntaxKind.AssertEntry: {
2287 return this.createNode(node, {
2288 type: ts_estree_1.AST_NODE_TYPES.ImportAttribute,
2289 key: this.convertChild(node.name),
2290 value: this.convertChild(node.value),
2291 });
2292 }
2293 default:
2294 return this.deeplyCopy(node);
2295 }
2296 }
2297}
2298exports.Converter = Converter;
2299//# sourceMappingURL=convert.js.map
\No newline at end of file