• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import { SourceFile } from 'typescript';
2import { convertError, Converter, ASTMaps } from './convert';
3import { convertComments } from './convert-comments';
4import { convertTokens } from './node-utils';
5import { Extra } from './parser-options';
6import { TSESTree } from './ts-estree';
7import { simpleTraverse } from './simple-traverse';
8
9export function astConverter(
10  ast: SourceFile,
11  extra: Extra,
12  shouldPreserveNodeMaps: boolean,
13): { estree: TSESTree.Program; astMaps: ASTMaps } {
14  /**
15   * The TypeScript compiler produced fundamental parse errors when parsing the
16   * source.
17   */
18  // internal typescript api...
19  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20  const parseDiagnostics = (ast as any).parseDiagnostics;
21  if (parseDiagnostics.length) {
22    throw convertError(parseDiagnostics[0]);
23  }
24
25  /**
26   * Recursively convert the TypeScript AST into an ESTree-compatible AST
27   */
28  const instance = new Converter(ast, {
29    errorOnUnknownASTType: extra.errorOnUnknownASTType || false,
30    useJSXTextNode: extra.useJSXTextNode || false,
31    shouldPreserveNodeMaps,
32  });
33
34  const estree = instance.convertProgram();
35
36  /**
37   * Optionally remove range and loc if specified
38   */
39  if (!extra.range || !extra.loc) {
40    simpleTraverse(estree, {
41      enter: node => {
42        if (!extra.range) {
43          // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TS 4.0 made this an error because the types aren't optional
44          // @ts-expect-error
45          delete node.range;
46        }
47        if (!extra.loc) {
48          // eslint-disable-next-line @typescript-eslint/ban-ts-comment -- TS 4.0 made this an error because the types aren't optional
49          // @ts-expect-error
50          delete node.loc;
51        }
52      },
53    });
54  }
55
56  /**
57   * Optionally convert and include all tokens in the AST
58   */
59  if (extra.tokens) {
60    estree.tokens = convertTokens(ast);
61  }
62
63  /**
64   * Optionally convert and include all comments in the AST
65   */
66  if (extra.comment) {
67    estree.comments = convertComments(ast, extra.code);
68  }
69
70  const astMaps = instance.getASTMaps();
71
72  return { estree, astMaps };
73}
74