diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 3bc12a1161..0b909a9879 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -151,6 +151,11 @@ export type FunctionTypeAnnotationParamTypeAnnotation = | $ReadOnly<{| type: 'ObjectTypeAnnotation', properties: $ReadOnlyArray, + |}> + | $ReadOnly<{| + type: 'FunctionTypeAnnotation', + params: $ReadOnlyArray, + returnTypeAnnotation: FunctionTypeAnnotationReturn, |}>; export type FunctionTypeAnnotationReturnArrayElementType = FunctionTypeAnnotationParamTypeAnnotation; @@ -170,7 +175,7 @@ export type FunctionTypeAnnotationReturn = |}> | $ReadOnly<{| type: 'PromiseTypeAnnotation', - resolvingType: FunctionTypeAnnotationReturn, + resolvedType: FunctionTypeAnnotationReturn, |}> | $ReadOnly<{| type: 'ObjectTypeAnnotation', diff --git a/packages/react-native-codegen/src/parsers/flow/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/__test_fixtures__/fixtures.js index 936eefaea7..d0365fdd25 100644 --- a/packages/react-native-codegen/src/parsers/flow/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/__test_fixtures__/fixtures.js @@ -269,6 +269,34 @@ export interface Spec extends TurboModule { } export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); + +`; + +const NATIVE_MODULE_WITH_CALLBACK = ` +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +'use strict'; + +import type {TurboModule} from '../RCTExport'; +import * as TurboModuleRegistry from '../TurboModuleRegistry'; + +export interface Spec extends TurboModule { + // Exported methods. + +getValueWithCallback: ( + callback: (value: string, arr: Array>) => void, + ) => void; +} + +export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); + `; const EVENT_DEFINITION = ` @@ -820,6 +848,7 @@ module.exports = { NATIVE_MODULE_WITH_COMPLEX_ARRAY, NATIVE_MODULE_WITH_ARRAY_WITH_ALIAS, NATIVE_MODULE_WITH_BASIC_PARAM_TYPES, + NATIVE_MODULE_WITH_CALLBACK, EMPTY_NATIVE_MODULE, ALL_PROP_TYPES_NO_EVENTS, ARRAY_PROP_TYPES_NO_EVENTS, diff --git a/packages/react-native-codegen/src/parsers/flow/__tests__/__snapshots__/parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/__tests__/__snapshots__/parser-test.js.snap index fe6decfdab..3f9b1abb98 100644 --- a/packages/react-native-codegen/src/parsers/flow/__tests__/__snapshots__/parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/__tests__/__snapshots__/parser-test.js.snap @@ -3482,6 +3482,65 @@ Object { } `; +exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_CALLBACK 1`] = ` +Object { + "modules": Object { + "SampleTurboModule": Object { + "nativeModules": Object { + "SampleTurboModule": Object { + "properties": Array [ + Object { + "name": "getValueWithCallback", + "typeAnnotation": Object { + "optional": false, + "params": Array [ + Object { + "name": "callback", + "nullable": false, + "typeAnnotation": Object { + "params": Array [ + Object { + "name": "value", + "nullable": false, + "typeAnnotation": Object { + "type": "StringTypeAnnotation", + }, + }, + Object { + "name": "arr", + "nullable": false, + "typeAnnotation": Object { + "elementType": Object { + "elementType": Object { + "type": "StringTypeAnnotation", + }, + "type": "ArrayTypeAnnotation", + }, + "type": "ArrayTypeAnnotation", + }, + }, + ], + "returnTypeAnnotation": Object { + "type": "VoidTypeAnnotation", + }, + "type": "FunctionTypeAnnotation", + }, + }, + ], + "returnTypeAnnotation": Object { + "type": "VoidTypeAnnotation", + }, + "type": "FunctionTypeAnnotation", + }, + }, + ], + }, + }, + }, + }, +} +`; + exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_COMPLEX_ARRAY 1`] = ` Object { "modules": Object { @@ -3734,7 +3793,7 @@ Object { "optional": false, "params": Array [], "returnTypeAnnotation": Object { - "resolvingType": Object { + "resolvedType": Object { "type": "StringTypeAnnotation", }, "type": "PromiseTypeAnnotation", @@ -3748,7 +3807,7 @@ Object { "optional": false, "params": Array [], "returnTypeAnnotation": Object { - "resolvingType": Object { + "resolvedType": Object { "type": "StringTypeAnnotation", }, "type": "PromiseTypeAnnotation", diff --git a/packages/react-native-codegen/src/parsers/flow/methods.js b/packages/react-native-codegen/src/parsers/flow/methods.js index 5191cd5970..2b412052cc 100644 --- a/packages/react-native-codegen/src/parsers/flow/methods.js +++ b/packages/react-native-codegen/src/parsers/flow/methods.js @@ -174,7 +174,7 @@ function getTypeAnnotationForParam( ); } } - if (param.typeAnnotation.type === 'ObjectTypeAnnotation') { + if (typeAnnotation.type === 'ObjectTypeAnnotation') { return { nullable, name: paramName, @@ -189,6 +189,25 @@ function getTypeAnnotationForParam( }, }; } + if (typeAnnotation.type === 'FunctionTypeAnnotation') { + const params = typeAnnotation.params.map(callbackParam => + getTypeAnnotationForParam(name, callbackParam, types), + ); + const returnTypeAnnotation = getReturnTypeAnnotation( + name, + typeAnnotation.returnType, + types, + ); + return { + name: paramName, + nullable, + typeAnnotation: { + type: 'FunctionTypeAnnotation', + params, + returnTypeAnnotation, + }, + }; + } const type = typeAnnotation.type; if ( @@ -230,7 +249,7 @@ function getReturnTypeAnnotation( ) { return { type: 'PromiseTypeAnnotation', - resolvingType: getReturnTypeAnnotation( + resolvedType: getReturnTypeAnnotation( methodName, typeAnnotation.typeParameters.params[0], types,