@@ -28,11 +28,25 @@ import type {
28
28
StringTypeAnnotation ,
29
29
VoidTypeAnnotation ,
30
30
NativeModuleFloatTypeAnnotation ,
31
+ NativeModuleParamTypeAnnotation ,
32
+ NamedShape ,
31
33
} from '../CodegenSchema' ;
32
34
import type { ParserType } from './errors' ;
33
- import type { TypeAliasResolutionStatus } from './utils' ;
35
+ import type {
36
+ ParserErrorCapturer ,
37
+ TypeAliasResolutionStatus ,
38
+ TypeDeclarationMap ,
39
+ } from './utils' ;
40
+
41
+ const { UnnamedFunctionParamParserError} = require ( './errors' ) ;
34
42
35
43
const {
44
+ throwIfUnsupportedFunctionParamTypeAnnotationParserError,
45
+ throwIfUnsupportedFunctionReturnTypeAnnotationParserError,
46
+ } = require ( './error-utils' ) ;
47
+
48
+ const {
49
+ unwrapNullable,
36
50
wrapNullable,
37
51
assertGenericTypeAnnotationHasExactlyOneTypeParameter,
38
52
} = require ( './parsers-commons' ) ;
@@ -190,6 +204,137 @@ function emitFloat(
190
204
} ) ;
191
205
}
192
206
207
+ function getTypeAnnotationParameters(
208
+ typeAnnotation: $FlowFixMe,
209
+ language: ParserType,
210
+ ): $ReadOnlyArray< $FlowFixMe > {
211
+ return language === 'Flow'
212
+ ? typeAnnotation . params
213
+ : typeAnnotation . parameters ;
214
+ }
215
+
216
+ function getFunctionNameFromParameter(
217
+ param: NamedShape< Nullable < NativeModuleParamTypeAnnotation > > ,
218
+ language : ParserType ,
219
+ ) {
220
+ return language === 'Flow' ? param . name : param . typeAnnotation ;
221
+ }
222
+
223
+ function getParameterName(param: $FlowFixMe, language: ParserType): string {
224
+ return language === 'Flow' ? param . name . name : param . name ;
225
+ }
226
+
227
+ function getParameterTypeAnnotation(param: $FlowFixMe, language: ParserType) {
228
+ return language === 'Flow'
229
+ ? param . typeAnnotation
230
+ : param . typeAnnotation . typeAnnotation ;
231
+ }
232
+
233
+ function getTypeAnnotationReturnType(
234
+ typeAnnotation: $FlowFixMe,
235
+ language: ParserType,
236
+ ) {
237
+ return language === 'Flow'
238
+ ? typeAnnotation . returnType
239
+ : typeAnnotation . typeAnnotation . typeAnnotation ;
240
+ }
241
+
242
+ function translateFunctionTypeAnnotation(
243
+ hasteModuleName: string,
244
+ // TODO(T108222691): Use flow-types for @babel/parser
245
+ // TODO(T71778680): This is a FunctionTypeAnnotation. Type this.
246
+ typeAnnotation: $FlowFixMe,
247
+ types: TypeDeclarationMap,
248
+ aliasMap: { ...NativeModuleAliasMap } ,
249
+ tryParse: ParserErrorCapturer,
250
+ cxxOnly: boolean,
251
+ translateTypeAnnotation: $FlowFixMe,
252
+ language: ParserType,
253
+ ): NativeModuleFunctionTypeAnnotation {
254
+ type Param = NamedShape < Nullable < NativeModuleParamTypeAnnotation >> ;
255
+ const params : Array < Param > = [ ] ;
256
+
257
+ for ( const param of getTypeAnnotationParameters ( typeAnnotation , language ) ) {
258
+ const parsedParam = tryParse ( ( ) => {
259
+ if ( getFunctionNameFromParameter ( param , language ) == null ) {
260
+ throw new UnnamedFunctionParamParserError (
261
+ param ,
262
+ hasteModuleName ,
263
+ language ,
264
+ ) ;
265
+ }
266
+
267
+ const paramName = getParameterName ( param , language ) ;
268
+
269
+ const [ paramTypeAnnotation , isParamTypeAnnotationNullable ] =
270
+ unwrapNullable (
271
+ translateTypeAnnotation (
272
+ hasteModuleName ,
273
+ getParameterTypeAnnotation ( param , language ) ,
274
+ types ,
275
+ aliasMap ,
276
+ tryParse ,
277
+ cxxOnly ,
278
+ ) ,
279
+ ) ;
280
+
281
+ if (
282
+ paramTypeAnnotation . type === 'VoidTypeAnnotation' ||
283
+ paramTypeAnnotation . type === 'PromiseTypeAnnotation'
284
+ ) {
285
+ return throwIfUnsupportedFunctionParamTypeAnnotationParserError (
286
+ hasteModuleName ,
287
+ param . typeAnnotation ,
288
+ paramName ,
289
+ paramTypeAnnotation . type ,
290
+ ) ;
291
+ }
292
+
293
+ return {
294
+ name : paramName ,
295
+ optional : Boolean ( param . optional ) ,
296
+ typeAnnotation : wrapNullable (
297
+ isParamTypeAnnotationNullable ,
298
+ paramTypeAnnotation ,
299
+ ) ,
300
+ } ;
301
+ } ) ;
302
+
303
+ if ( parsedParam != null ) {
304
+ params . push ( parsedParam ) ;
305
+ }
306
+ }
307
+
308
+ const [returnTypeAnnotation, isReturnTypeAnnotationNullable] = unwrapNullable(
309
+ translateTypeAnnotation(
310
+ hasteModuleName,
311
+ getTypeAnnotationReturnType(typeAnnotation, language),
312
+ types,
313
+ aliasMap,
314
+ tryParse,
315
+ cxxOnly,
316
+ ),
317
+ );
318
+
319
+ throwIfUnsupportedFunctionReturnTypeAnnotationParserError(
320
+ hasteModuleName,
321
+ typeAnnotation,
322
+ 'FunctionTypeAnnotation',
323
+ language,
324
+ cxxOnly,
325
+ returnTypeAnnotation.type,
326
+ );
327
+
328
+ return {
329
+ type : 'FunctionTypeAnnotation' ,
330
+ returnTypeAnnotation : wrapNullable (
331
+ isReturnTypeAnnotationNullable ,
332
+ returnTypeAnnotation ,
333
+ ) ,
334
+ params ,
335
+ } ;
336
+ }
337
+
193
338
module . exports = {
194
339
emitBoolean ,
195
340
emitDouble ,
@@ -205,4 +350,5 @@ module.exports = {
205
350
emitStringish ,
206
351
emitMixedTypeAnnotation ,
207
352
typeAliasResolution ,
353
+ translateFunctionTypeAnnotation ,
208
354
} ;
0 commit comments