/
parse.ts
75 lines (68 loc) · 1.71 KB
/
parse.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import {
type ParseResult,
type ParserOptions,
type ParserPlugin,
parse,
parseExpression,
} from '@babel/parser'
import { REGEX_LANG_JSX, isTs } from './lang'
import type * as t from '@babel/types'
function hasPlugin(
plugins: ParserPlugin[],
plugin: Exclude<ParserPlugin, any[]>
) {
return plugins.some((p) => (Array.isArray(p) ? p[0] : p) === plugin)
}
function getParserOptions(
lang?: string,
options: ParserOptions = {}
): ParserOptions {
const plugins: ParserPlugin[] = [...(options.plugins || [])]
if (isTs(lang)) {
if (!hasPlugin(plugins, 'typescript')) {
plugins.push(
lang === 'dts' ? ['typescript', { dts: true }] : 'typescript'
)
}
if (
!hasPlugin(plugins, 'decorators') &&
!hasPlugin(plugins, 'decorators-legacy')
) {
plugins.push('decorators-legacy')
}
if (
!hasPlugin(plugins, 'importAttributes') &&
!hasPlugin(plugins, 'importAssertions')
) {
plugins.push(['importAttributes', { deprecatedAssertSyntax: true }])
}
if (REGEX_LANG_JSX.test(lang!) && !hasPlugin(plugins, 'jsx')) {
plugins.push('jsx')
}
} else if (!hasPlugin(plugins, 'jsx')) {
plugins.push('jsx')
}
return {
sourceType: 'module',
...options,
plugins,
}
}
export function babelParse(
code: string,
lang?: string,
options: ParserOptions = {}
): ParseResult<t.Program> {
const { program, errors } = parse(code, getParserOptions(lang, options))
return { ...program, errors }
}
export function babelParseExpression<T extends t.Node = t.Expression>(
code: string,
lang?: string,
options: ParserOptions = {}
) {
return parseExpression(
code,
getParserOptions(lang, options)
) as ParseResult<T>
}