@@ -5,7 +5,7 @@ import * as Path from 'path'
55import _resolve from 'resolve'
66import { promisify } from 'util'
77import * as defaultBabelParser from '@babel/parser'
8- import { ParserOptions } from '@babel/parser'
8+ import { ParserOptions , ParserPlugin } from '@babel/parser'
99import { readFile as _readFile , readFileSync } from 'fs'
1010const readFile = promisify ( _readFile )
1111
@@ -42,39 +42,40 @@ export class Parser {
4242 }
4343}
4444
45+ const tsPlugins : ParserPlugin [ ] = [
46+ 'asyncGenerators' ,
47+ 'bigInt' ,
48+ 'classPrivateMethods' ,
49+ 'classPrivateProperties' ,
50+ 'classProperties' ,
51+ 'decorators-legacy' ,
52+ 'doExpressions' ,
53+ 'dynamicImport' ,
54+ 'exportDefaultFrom' ,
55+ 'exportNamespaceFrom' ,
56+ 'functionBind' ,
57+ 'functionSent' ,
58+ 'importMeta' ,
59+ 'nullishCoalescingOperator' ,
60+ 'numericSeparator' ,
61+ 'objectRestSpread' ,
62+ 'optionalCatchBinding' ,
63+ 'optionalChaining' ,
64+ [ 'pipelineOperator' , { proposal : 'minimal' } ] ,
65+ 'throwExpressions' ,
66+ 'typescript' ,
67+ ]
68+
4569const tsParser : Parser = new Parser ( defaultBabelParser , {
4670 sourceType : 'module' ,
4771 allowImportExportEverywhere : true ,
4872 allowReturnOutsideFunction : true ,
4973 startLine : 1 ,
50- tokens : true ,
51- plugins : [
52- 'asyncGenerators' ,
53- 'bigInt' ,
54- 'classPrivateMethods' ,
55- 'classPrivateProperties' ,
56- 'classProperties' ,
57- 'decorators-legacy' ,
58- 'doExpressions' ,
59- 'dynamicImport' ,
60- 'exportDefaultFrom' ,
61- 'exportNamespaceFrom' ,
62- 'functionBind' ,
63- 'functionSent' ,
64- 'importMeta' ,
65- 'nullishCoalescingOperator' ,
66- 'numericSeparator' ,
67- 'objectRestSpread' ,
68- 'optionalCatchBinding' ,
69- 'optionalChaining' ,
70- [ 'pipelineOperator' , { proposal : 'minimal' } ] ,
71- 'throwExpressions' ,
72- 'typescript' ,
73- ] ,
74+ plugins : tsPlugins ,
7475} )
7576const tsxParser : Parser = new Parser ( defaultBabelParser , {
7677 ...tsParser . parserOpts ,
77- plugins : [ ...( tsParser . parserOpts . plugins || [ ] ) , 'jsx' ] ,
78+ plugins : [ ...tsPlugins , 'jsx' ] ,
7879} )
7980const jsParser : Parser = new Parser ( defaultBabelParser , {
8081 sourceType : 'module' ,
@@ -143,83 +144,86 @@ export function getParserSync(
143144 file : string ,
144145 options ?: Omit < ParserOptions , 'plugins' >
145146) : Parser {
146- if ( / \. t s $ / . test ( file ) ) return tsParser
147- if ( / \. t s x $ / . test ( file ) ) return tsxParser
148-
149- const parentDir = Path . dirname ( file )
150-
151- let result = syncCache . get ( parentDir )
152-
153- if ( ! result ) {
154- try {
155- const babelPath = _resolve . sync ( '@babel/core' , {
156- basedir : parentDir ,
157- } )
158- // eslint-disable-next-line @typescript-eslint/no-var-requires
159- const babel = require ( babelPath )
160- requiredPaths . push ( babelPath )
161-
162- const parserPath = _resolve . sync ( '@babel/parser' , {
163- basedir : parentDir ,
164- } )
165- // eslint-disable-next-line @typescript-eslint/no-var-requires
166- const parser = require ( parserPath )
167- requiredPaths . push ( parserPath )
168-
169- const config = babel . loadOptionsSync ( {
170- filename : file ,
171- cwd : Path . dirname ( file ) ,
172- rootMode : 'upward-optional' ,
173- } )
174- result = createParserFromConfig ( parser , config )
175- } catch ( error ) {
176- result = jsParser
177- }
178- syncCache . set ( parentDir , result )
179- asyncCache . set ( parentDir , Promise . resolve ( result ) )
180- }
181- return ! options || isEmpty ( options ) ? result : result . bindParserOpts ( options )
182- }
183-
184- export async function getParserAsync (
185- file : string ,
186- options ?: Omit < ParserOptions , 'plugins' >
187- ) : Promise < Parser > {
188- if ( / \. t s $ / . test ( file ) ) return tsParser
189- if ( / \. t s x $ / . test ( file ) ) return tsxParser
190-
191- const parentDir = Path . dirname ( file )
192-
193- let promise = asyncCache . get ( parentDir )
194-
195- if ( ! promise ) {
196- promise = ( async ( ) : Promise < Parser > => {
197- let result
147+ let result
148+ if ( / \. t s $ / . test ( file ) ) result = tsParser
149+ else if ( / \. t s x $ / . test ( file ) ) result = tsxParser
150+ else {
151+ const parentDir = Path . dirname ( file )
152+ result = syncCache . get ( parentDir )
153+
154+ if ( ! result ) {
198155 try {
199- const babelPath = await resolve ( '@babel/core' , {
156+ const babelPath = _resolve . sync ( '@babel/core' , {
200157 basedir : parentDir ,
201158 } )
202- const babel = await import ( babelPath )
159+ // eslint-disable-next-line @typescript-eslint/no-var-requires
160+ const babel = require ( babelPath )
203161 requiredPaths . push ( babelPath )
204162
205- const parserPath = await resolve ( '@babel/parser' , {
163+ const parserPath = _resolve . sync ( '@babel/parser' , {
206164 basedir : parentDir ,
207165 } )
208- const parser = await import ( parserPath )
166+ // eslint-disable-next-line @typescript-eslint/no-var-requires
167+ const parser = require ( parserPath )
209168 requiredPaths . push ( parserPath )
210169
211- const config = await babel . loadOptionsAsync ( {
170+ const config = babel . loadOptionsSync ( {
212171 filename : file ,
213- cwd : process . cwd ( ) ,
172+ cwd : Path . dirname ( file ) ,
173+ rootMode : 'upward-optional' ,
214174 } )
215175 result = createParserFromConfig ( parser , config )
216176 } catch ( error ) {
217177 result = jsParser
218178 }
219179 syncCache . set ( parentDir , result )
220- return result
221- } ) ( )
222- asyncCache . set ( parentDir , promise )
180+ asyncCache . set ( parentDir , Promise . resolve ( result ) )
181+ }
182+ }
183+ return ! options || isEmpty ( options ) ? result : result . bindParserOpts ( options )
184+ }
185+
186+ export async function getParserAsync (
187+ file : string ,
188+ options ?: Omit < ParserOptions , 'plugins' >
189+ ) : Promise < Parser > {
190+ let promise
191+ if ( / \. t s $ / . test ( file ) ) promise = Promise . resolve ( tsParser )
192+ else if ( / \. t s x $ / . test ( file ) ) promise = Promise . resolve ( tsxParser )
193+ else {
194+ const parentDir = Path . dirname ( file )
195+
196+ promise = asyncCache . get ( parentDir )
197+
198+ if ( ! promise ) {
199+ promise = ( async ( ) : Promise < Parser > => {
200+ let result
201+ try {
202+ const babelPath = await resolve ( '@babel/core' , {
203+ basedir : parentDir ,
204+ } )
205+ const babel = await import ( babelPath )
206+ requiredPaths . push ( babelPath )
207+
208+ const parserPath = await resolve ( '@babel/parser' , {
209+ basedir : parentDir ,
210+ } )
211+ const parser = await import ( parserPath )
212+ requiredPaths . push ( parserPath )
213+
214+ const config = await babel . loadOptionsAsync ( {
215+ filename : file ,
216+ cwd : parentDir ,
217+ } )
218+ result = createParserFromConfig ( parser , config )
219+ } catch ( error ) {
220+ result = jsParser
221+ }
222+ syncCache . set ( parentDir , result )
223+ return result
224+ } ) ( )
225+ asyncCache . set ( parentDir , promise )
226+ }
223227 }
224228 const result = await promise
225229 return ! options || isEmpty ( options ) ? result : result . bindParserOpts ( options )
0 commit comments