diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 3835ad2adc..a10b8d2951 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -163,6 +163,7 @@ export type FunctionTypeAnnotationParamTypeAnnotation = export type FunctionTypeAnnotationReturnArrayElementType = FunctionTypeAnnotationParamTypeAnnotation; export type ObjectParamTypeAnnotation = $ReadOnly<{| + optional: boolean, name: string, typeAnnotation: FunctionTypeAnnotationParamTypeAnnotation, |}>; diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js index e644232c85..b20abf2c8e 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js @@ -38,18 +38,21 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { type: 'ObjectTypeAnnotation', properties: [ { + optional: false, name: 'const1', typeAnnotation: { type: 'BooleanTypeAnnotation', }, }, { + optional: false, name: 'const2', typeAnnotation: { type: 'NumberTypeAnnotation', }, }, { + optional: false, name: 'const3', typeAnnotation: { type: 'StringTypeAnnotation', diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js index fba7c561d7..44f6a70496 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js @@ -66,6 +66,42 @@ export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); `; +const NATIVE_MODULE_WITH_COMPLEX_OBJECTS_WITH_NULLABLE_KEY = ` +/** + * 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 { + +getConstants: () => {| + isTesting: boolean, + reactNativeVersion: {| + major: number, + minor: number, + patch: number, + prerelease: ?number, + |}, + forceTouchAvailable: boolean, + osVersion: string, + systemName: string, + interfaceIdiom: string, + |}; +} + +export default TurboModuleRegistry.getEnforcing('PlatformConstants'); + +`; + const NATIVE_MODULE_WITH_BASIC_PARAM_TYPES = ` /** * Copyright (c) Facebook, Inc. and its affiliates. @@ -224,6 +260,38 @@ export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); `; +const NATIVE_MODULE_WITH_OBJECT_WITH_OBJECT_DEIFNED_IN_FILE_AS_PROPERTY = ` +/** + * 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'; + +type DisplayMetricsAndroid = {| + width: number, +|}; + +export interface Spec extends TurboModule { + +getConstants: () => {| + +Dimensions: { + windowPhysicalPixels: DisplayMetricsAndroid, + }, + |}; +} + +export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); + +`; + const NATIVE_MODULE_WITH_ARRAY_WITH_ALIAS = ` /** * Copyright (c) Facebook, Inc. and its affiliates. @@ -328,10 +396,12 @@ export default TurboModuleRegistry.getEnforcing('SampleTurboModule'); `; module.exports = { + NATIVE_MODULE_WITH_OBJECT_WITH_OBJECT_DEIFNED_IN_FILE_AS_PROPERTY, NATIVE_MODULE_WITH_WITH_FLOAT_AND_INT32, NATIVE_MODULE_WITH_WITH_ALIASES, NATIVE_MODULE_WITH_PROMISE, NATIVE_MODULE_WITH_COMPLEX_OBJECTS, + NATIVE_MODULE_WITH_COMPLEX_OBJECTS_WITH_NULLABLE_KEY, NATIVE_MODULE_WITH_SIMPLE_OBJECT, NATIVE_MODULE_WITH_NULLABLE_PARAM, NATIVE_MODULE_WITH_BASIC_ARRAY, diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap index 91ba4b0071..6696de0339 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-test.js.snap @@ -325,10 +325,12 @@ Object { "properties": Array [ Object { "name": "const1", + "optional": false, "typeAnnotation": Object { "properties": Array [ Object { "name": "const1", + "optional": false, "typeAnnotation": Object { "type": "BooleanTypeAnnotation", }, @@ -346,10 +348,12 @@ Object { "properties": Array [ Object { "name": "const1", + "optional": false, "typeAnnotation": Object { "properties": Array [ Object { "name": "const1", + "optional": false, "typeAnnotation": Object { "type": "BooleanTypeAnnotation", }, @@ -376,6 +380,7 @@ Object { "properties": Array [ Object { "name": "a", + "optional": false, "typeAnnotation": Object { "type": "StringTypeAnnotation", }, @@ -403,10 +408,12 @@ Object { "properties": Array [ Object { "name": "const1", + "optional": false, "typeAnnotation": Object { "properties": Array [ Object { "name": "const1", + "optional": false, "typeAnnotation": Object { "type": "BooleanTypeAnnotation", }, @@ -425,10 +432,12 @@ Object { "properties": Array [ Object { "name": "const1", + "optional": false, "typeAnnotation": Object { "properties": Array [ Object { "name": "const1", + "optional": false, "typeAnnotation": Object { "type": "BooleanTypeAnnotation", }, @@ -453,6 +462,106 @@ Object { } `; +exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_COMPLEX_OBJECTS_WITH_NULLABLE_KEY 1`] = ` +Object { + "modules": Object { + "NativeSampleTurboModule": Object { + "nativeModules": Object { + "SampleTurboModule": Object { + "properties": Array [ + Object { + "name": "getConstants", + "typeAnnotation": Object { + "optional": false, + "params": Array [], + "returnTypeAnnotation": Object { + "properties": Array [ + Object { + "name": "isTesting", + "optional": false, + "typeAnnotation": Object { + "type": "BooleanTypeAnnotation", + }, + }, + Object { + "name": "reactNativeVersion", + "optional": false, + "typeAnnotation": Object { + "properties": Array [ + Object { + "name": "major", + "optional": false, + "typeAnnotation": Object { + "type": "NumberTypeAnnotation", + }, + }, + Object { + "name": "minor", + "optional": false, + "typeAnnotation": Object { + "type": "NumberTypeAnnotation", + }, + }, + Object { + "name": "patch", + "optional": false, + "typeAnnotation": Object { + "type": "NumberTypeAnnotation", + }, + }, + Object { + "name": "prerelease", + "optional": true, + "typeAnnotation": Object { + "type": "NumberTypeAnnotation", + }, + }, + ], + "type": "ObjectTypeAnnotation", + }, + }, + Object { + "name": "forceTouchAvailable", + "optional": false, + "typeAnnotation": Object { + "type": "BooleanTypeAnnotation", + }, + }, + Object { + "name": "osVersion", + "optional": false, + "typeAnnotation": Object { + "type": "StringTypeAnnotation", + }, + }, + Object { + "name": "systemName", + "optional": false, + "typeAnnotation": Object { + "type": "StringTypeAnnotation", + }, + }, + Object { + "name": "interfaceIdiom", + "optional": false, + "typeAnnotation": Object { + "type": "StringTypeAnnotation", + }, + }, + ], + "type": "ObjectTypeAnnotation", + }, + "type": "FunctionTypeAnnotation", + }, + }, + ], + }, + }, + }, + }, +} +`; + exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_NULLABLE_PARAM 1`] = ` Object { "modules": Object { @@ -487,6 +596,59 @@ Object { } `; +exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_OBJECT_WITH_OBJECT_DEIFNED_IN_FILE_AS_PROPERTY 1`] = ` +Object { + "modules": Object { + "NativeSampleTurboModule": Object { + "nativeModules": Object { + "SampleTurboModule": Object { + "properties": Array [ + Object { + "name": "getConstants", + "typeAnnotation": Object { + "optional": false, + "params": Array [], + "returnTypeAnnotation": Object { + "properties": Array [ + Object { + "name": "Dimensions", + "optional": false, + "typeAnnotation": Object { + "properties": Array [ + Object { + "name": "windowPhysicalPixels", + "optional": false, + "typeAnnotation": Object { + "properties": Array [ + Object { + "name": "width", + "optional": false, + "typeAnnotation": Object { + "type": "NumberTypeAnnotation", + }, + }, + ], + "type": "ObjectTypeAnnotation", + }, + }, + ], + "type": "ObjectTypeAnnotation", + }, + }, + ], + "type": "ObjectTypeAnnotation", + }, + "type": "FunctionTypeAnnotation", + }, + }, + ], + }, + }, + }, + }, +} +`; + exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_PROMISE 1`] = ` Object { "modules": Object { @@ -621,6 +783,7 @@ Object { "properties": Array [ Object { "name": "a", + "optional": false, "typeAnnotation": Object { "type": "NumberTypeAnnotation", }, diff --git a/packages/react-native-codegen/src/parsers/flow/modules/methods.js b/packages/react-native-codegen/src/parsers/flow/modules/methods.js index a7a12b0dc0..a544d210e4 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/methods.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/methods.js @@ -30,15 +30,24 @@ function getObjectProperties( paramName: string, types: TypeMap, ): $ReadOnlyArray { - return objectParam.properties.map(objectTypeProperty => ({ - name: objectTypeProperty.key.name, - typeAnnotation: getElementTypeForArrayOrObject( - name, - objectTypeProperty.value, - paramName, - types, - ), - })); + return objectParam.properties.map(objectTypeProperty => { + let optional = false; + let value = objectTypeProperty.value; + if (value.type === 'NullableTypeAnnotation') { + optional = true; + value = objectTypeProperty.value.typeAnnotation; + } + return { + optional, + name: objectTypeProperty.key.name, + typeAnnotation: getElementTypeForArrayOrObject( + name, + value, + paramName, + types, + ), + }; + }); } function getElementTypeForArrayOrObject( @@ -80,7 +89,7 @@ function getElementTypeForArrayOrObject( case 'ObjectTypeAnnotation': return { type: 'ObjectTypeAnnotation', - properties: getObjectProperties(name, arrayParam, paramName, types), + properties: getObjectProperties(name, typeAnnotation, paramName, types), }; case 'AnyTypeAnnotation': return { @@ -166,7 +175,7 @@ function getTypeAnnotationForParam( type: 'ObjectTypeAnnotation', properties: getObjectProperties( name, - param.typeAnnotation, + typeAnnotation, paramName, types, ),