5
5
* LICENSE file in the root directory of this source tree.
6
6
*/
7
7
8
- import { parse , ParserPlugin } from "@babel/parser" ;
8
+ import { parse as babelParse , ParserPlugin } from "@babel/parser" ;
9
+ import * as HermesParser from "hermes-parser" ;
9
10
import traverse , { NodePath } from "@babel/traverse" ;
10
11
import * as t from "@babel/types" ;
11
12
import {
@@ -42,8 +43,26 @@ import {
42
43
PrintedCompilerPipelineValue ,
43
44
} from "./Output" ;
44
45
46
+ function parseInput ( input : string , language : "flow" | "typescript" ) {
47
+ // Extract the first line to quickly check for custom test directives
48
+ if ( language === "flow" ) {
49
+ return HermesParser . parse ( input , {
50
+ babel : true ,
51
+ flow : "all" ,
52
+ sourceType : "module" ,
53
+ enableExperimentalComponentSyntax : true ,
54
+ } ) ;
55
+ } else {
56
+ return babelParse ( input , {
57
+ plugins : [ "typescript" , "jsx" ] ,
58
+ sourceType : "module" ,
59
+ } ) ;
60
+ }
61
+ }
62
+
45
63
function parseFunctions (
46
- source : string
64
+ source : string ,
65
+ language : "flow" | "typescript"
47
66
) : Array <
48
67
NodePath <
49
68
t . FunctionDeclaration | t . ArrowFunctionExpression | t . FunctionExpression
@@ -55,20 +74,7 @@ function parseFunctions(
55
74
>
56
75
> = [ ] ;
57
76
try {
58
- const isFlow = source
59
- . trim ( )
60
- . split ( "\n" , 1 ) [ 0 ]
61
- . match ( / \s * \/ \/ \s * \@ f l o w \s * / ) ;
62
- let type_transform : ParserPlugin ;
63
- if ( isFlow ) {
64
- type_transform = "flow" ;
65
- } else {
66
- type_transform = "typescript" ;
67
- }
68
- const ast = parse ( source , {
69
- plugins : [ type_transform , "jsx" ] ,
70
- sourceType : "module" ,
71
- } ) ;
77
+ const ast = parseInput ( source , language ) ;
72
78
traverse ( ast , {
73
79
FunctionDeclaration ( nodePath ) {
74
80
items . push ( nodePath ) ;
@@ -163,7 +169,7 @@ function getReactFunctionType(
163
169
return "Other" ;
164
170
}
165
171
166
- function compile ( source : string ) : CompilerOutput {
172
+ function compile ( source : string ) : [ CompilerOutput , "flow" | "typescript" ] {
167
173
const results = new Map < string , PrintedCompilerPipelineValue [ ] > ( ) ;
168
174
const error = new CompilerError ( ) ;
169
175
const upsert = ( result : PrintedCompilerPipelineValue ) => {
@@ -174,12 +180,18 @@ function compile(source: string): CompilerOutput {
174
180
results . set ( result . name , [ result ] ) ;
175
181
}
176
182
} ;
183
+ let language : "flow" | "typescript" ;
184
+ if ( source . match ( / \@ f l o w / ) ) {
185
+ language = "flow" ;
186
+ } else {
187
+ language = "typescript" ;
188
+ }
177
189
try {
178
190
// Extract the first line to quickly check for custom test directives
179
191
const pragma = source . substring ( 0 , source . indexOf ( "\n" ) ) ;
180
192
const config = parseConfigPragma ( pragma ) ;
181
193
182
- for ( const fn of parseFunctions ( source ) ) {
194
+ for ( const fn of parseFunctions ( source , language ) ) {
183
195
if ( ! fn . isFunctionDeclaration ( ) ) {
184
196
error . pushErrorDetail (
185
197
new CompilerErrorDetail ( {
@@ -279,17 +291,17 @@ function compile(source: string): CompilerOutput {
279
291
}
280
292
}
281
293
if ( error . hasErrors ( ) ) {
282
- return { kind : "err" , results, error : error } ;
294
+ return [ { kind : "err" , results, error : error } , language ] ;
283
295
}
284
- return { kind : "ok" , results } ;
296
+ return [ { kind : "ok" , results } , language ] ;
285
297
}
286
298
287
299
export default function Editor ( ) {
288
300
const store = useStore ( ) ;
289
301
const deferredStore = useDeferredValue ( store ) ;
290
302
const dispatchStore = useStoreDispatch ( ) ;
291
303
const { enqueueSnackbar } = useSnackbar ( ) ;
292
- const compilerOutput = useMemo (
304
+ const [ compilerOutput , language ] = useMemo (
293
305
( ) => compile ( deferredStore . source ) ,
294
306
[ deferredStore . source ]
295
307
) ;
@@ -321,6 +333,7 @@ export default function Editor() {
321
333
< div className = "relative flex basis top-14" >
322
334
< div className = { clsx ( "relative sm:basis-1/4" ) } >
323
335
< Input
336
+ language = { language }
324
337
errors = {
325
338
compilerOutput . kind === "err" ? compilerOutput . error . details : [ ]
326
339
}
0 commit comments