diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 36e08a6bb6e..0e2a5ec60dc 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -262,7 +262,7 @@ export type SchemaType = $ReadOnly<{| export type NativeModuleShape = $ReadOnly<{| // We only support aliases to Objects aliases: NativeModuleAliasMap, - properties: $ReadOnlyArray, + properties: $ReadOnlyArray, |}>; export type NativeModuleAliasMap = $ReadOnly<{ @@ -276,16 +276,15 @@ export type ObjectTypeAliasTypeShape = $ReadOnly<{| properties: $ReadOnlyArray, |}>; -export type NativeModuleMethodTypeShape = $ReadOnly<{| +export type NativeModulePropertyShape = $ReadOnly<{| name: string, - typeAnnotation: FunctionTypeAnnotation, -|}>; - -export type FunctionTypeAnnotation = $ReadOnly<{| - type: 'FunctionTypeAnnotation', - params: $ReadOnlyArray, - returnTypeAnnotation: FunctionTypeAnnotationReturn, optional: boolean, + typeAnnotation: $ReadOnly<{| + type: 'FunctionTypeAnnotation', + params: $ReadOnlyArray, + returnTypeAnnotation: FunctionTypeAnnotationReturn, + nullable: boolean, + |}>, |}>; export type FunctionTypeAnnotationReturn = diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js index 5054146e4ff..43937022e4f 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js @@ -13,7 +13,7 @@ import type { FunctionTypeAnnotationParam, FunctionTypeAnnotationReturn, - NativeModuleMethodTypeShape, + NativeModulePropertyShape, ObjectTypeAliasTypeShape, SchemaType, } from '../../CodegenSchema'; @@ -156,7 +156,7 @@ function translateFunctionReturnTypeToJavaType( // Build special-cased runtime check for getConstants(). function buildGetConstantsMethod( - method: NativeModuleMethodTypeShape, + method: NativeModulePropertyShape, imports: Set, ): string { if ( 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 cea663c8b1b..1c5a3b9127d 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 @@ -34,6 +34,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { properties: [ { name: 'getConstants', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -64,11 +65,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { ], }, params: [], - optional: false, + nullable: false, }, }, { name: 'voidFunc', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -76,11 +78,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: false, + nullable: false, }, }, { name: 'getBool', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -96,11 +99,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getNumber', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -116,11 +120,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getString', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -136,11 +141,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getArray', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -162,11 +168,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getObject', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -182,11 +189,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getRootTag', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -204,11 +212,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getValue', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -238,11 +247,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getValueWithCallback', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -258,11 +268,12 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'getValueWithPromise', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -278,7 +289,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, ], @@ -297,6 +308,7 @@ const TWO_MODULES_SAME_FILE: SchemaType = { properties: [ { name: 'voidFunc', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -304,7 +316,7 @@ const TWO_MODULES_SAME_FILE: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: false, + nullable: false, }, }, ], @@ -314,6 +326,7 @@ const TWO_MODULES_SAME_FILE: SchemaType = { properties: [ { name: 'voidFunc', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -321,7 +334,7 @@ const TWO_MODULES_SAME_FILE: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: false, + nullable: false, }, }, ], @@ -340,6 +353,7 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { properties: [ { name: 'voidFunc', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -347,7 +361,7 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: false, + nullable: false, }, }, ], @@ -361,6 +375,7 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { properties: [ { name: 'getConstants', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -369,11 +384,12 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { properties: [], }, params: [], - optional: false, + nullable: false, }, }, { name: 'voidFunc', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -381,7 +397,7 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: false, + nullable: false, }, }, ], @@ -400,6 +416,7 @@ const COMPLEX_OBJECTS: SchemaType = { properties: [ { name: 'difficult', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -491,11 +508,12 @@ const COMPLEX_OBJECTS: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'optionals', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -567,11 +585,12 @@ const COMPLEX_OBJECTS: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'optionalMethod', + optional: true, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -617,11 +636,12 @@ const COMPLEX_OBJECTS: SchemaType = { }, }, ], - optional: true, + nullable: true, }, }, { name: 'getArrays', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -698,7 +718,7 @@ const COMPLEX_OBJECTS: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, ], @@ -806,6 +826,7 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { properties: [ { name: 'getConstants', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -814,11 +835,12 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { properties: [], }, params: [], - optional: false, + nullable: false, }, }, { name: 'cropImage', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -835,7 +857,7 @@ const NATIVE_MODULES_WITH_TYPE_ALIASES: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, ], @@ -1092,6 +1114,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { properties: [ { name: 'getConstants', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1100,11 +1123,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { properties: [], }, params: [], - optional: false, + nullable: false, }, }, { name: 'getPhotos', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1121,11 +1145,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'saveToCameraRoll', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1148,11 +1173,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'deletePhotos', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1171,7 +1197,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, ], @@ -1185,6 +1211,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { properties: [ { name: 'openCameraDialog', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1230,7 +1257,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, ], @@ -1350,6 +1377,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { properties: [ { name: 'reportFatalException', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1383,11 +1411,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'reportSoftException', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1421,11 +1450,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'reportException', + optional: true, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1442,11 +1472,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: true, + nullable: true, }, }, { name: 'updateExceptionMessage', + optional: false, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1480,11 +1511,12 @@ const REAL_MODULE_EXAMPLE: SchemaType = { }, }, ], - optional: false, + nullable: false, }, }, { name: 'dismissRedbox', + optional: true, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { @@ -1492,7 +1524,7 @@ const REAL_MODULE_EXAMPLE: SchemaType = { type: 'VoidTypeAnnotation', }, params: [], - optional: true, + nullable: true, }, }, ], 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 1fcaee4231a..54ae74f6566 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 @@ -75,8 +75,9 @@ Object { "properties": Array [ Object { "name": "getNumber", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -95,8 +96,9 @@ Object { }, Object { "name": "getVoid", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -107,8 +109,9 @@ Object { }, Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "a", @@ -139,8 +142,9 @@ Object { }, Object { "name": "getStringFromAlias", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "a", @@ -176,8 +180,9 @@ Object { "properties": Array [ Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -218,8 +223,9 @@ Object { "properties": Array [ Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -256,8 +262,9 @@ Object { "properties": Array [ Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -282,8 +289,9 @@ Object { }, Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -324,8 +332,9 @@ Object { "properties": Array [ Object { "name": "passBool", + "optional": true, "typeAnnotation": Object { - "optional": true, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -344,8 +353,9 @@ Object { }, Object { "name": "passNumber", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -364,8 +374,9 @@ Object { }, Object { "name": "passString", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -384,8 +395,9 @@ Object { }, Object { "name": "passStringish", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -420,8 +432,9 @@ Object { "properties": Array [ Object { "name": "getValueWithCallback", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "callback", @@ -456,8 +469,9 @@ Object { "properties": Array [ Object { "name": "getArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -516,8 +530,9 @@ Object { "properties": Array [ Object { "name": "getObject", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -572,8 +587,9 @@ Object { }, Object { "name": "getReadOnlyObject", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -628,8 +644,9 @@ Object { }, Object { "name": "getObject2", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -657,8 +674,9 @@ Object { }, Object { "name": "getObjectInArray", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -732,8 +750,9 @@ Object { "properties": Array [ Object { "name": "getConstants", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -834,8 +853,9 @@ Object { "properties": Array [ Object { "name": "getInt", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -854,8 +874,9 @@ Object { }, Object { "name": "getFloat", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -924,8 +945,9 @@ Object { "properties": Array [ Object { "name": "foo1", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "x", @@ -946,8 +968,9 @@ Object { }, Object { "name": "foo2", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "x", @@ -983,8 +1006,9 @@ Object { "properties": Array [ Object { "name": "voidFunc", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "arg", @@ -1032,8 +1056,9 @@ Object { "properties": Array [ Object { "name": "getConstants", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -1063,8 +1088,9 @@ Object { }, Object { "name": "getConstants2", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -1123,8 +1149,9 @@ Object { "properties": Array [ Object { "name": "getValueWithPromise", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -1135,8 +1162,9 @@ Object { }, Object { "name": "getValueWithPromiseDefinedSomewhereElse", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -1147,8 +1175,9 @@ Object { }, Object { "name": "getValueWithPromiseObjDefinedSomewhereElse", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [], "returnTypeAnnotation": Object { "nullable": false, @@ -1175,8 +1204,9 @@ Object { "properties": Array [ Object { "name": "getRootTag", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "rootTag", @@ -1213,8 +1243,9 @@ Object { "properties": Array [ Object { "name": "getObject", + "optional": false, "typeAnnotation": Object { - "optional": false, + "nullable": false, "params": Array [ Object { "name": "o", 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 17764051194..e3773c01215 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/methods.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/methods.js @@ -11,7 +11,7 @@ 'use strict'; import type { - NativeModuleMethodTypeShape, + NativeModulePropertyShape, FunctionTypeAnnotationParam, FunctionTypeAnnotationReturn, } from '../../../CodegenSchema.js'; @@ -24,9 +24,6 @@ const { } = require('./properties'); const invariant = require('invariant'); -// $FlowFixMe there's no flowtype for ASTs -type MethodAST = Object; - function getTypeAnnotationForParam( name: string, paramAnnotation: ASTNode, @@ -315,16 +312,35 @@ function getReturnTypeAnnotation( } function buildMethodSchema( - property: MethodAST, + // TODO(T71778680): This is an ObjectTypeProperty containing either: + // - a FunctionTypeAnnotation or GenericTypeAnnotation + // - a NullableTypeAnnoation containing a FunctionTypeAnnotation or GenericTypeAnnotation + // Flow type this node + property: $FlowFixMe, types: TypeDeclarationMap, -): NativeModuleMethodTypeShape { - const name: string = property.key.name; - const value = getValueFromTypes(property.value, types); +): NativeModulePropertyShape { + let nullable = false; + let {key, value} = property; + + // Unwrap Nullable types + if (value.type === 'NullableTypeAnnotation') { + nullable = true; + value = value.typeAnnotation; + } + + const name: string = key.name; + + // Resolve type aliases + if (value.type === 'GenericTypeAnnotation') { + value = getValueFromTypes(value, types); + } + if (value.type !== 'FunctionTypeAnnotation') { throw new Error( `Only methods are supported as module properties. Found ${value.type} in ${property.key.name}`, ); } + const params = value.params.map(param => getTypeAnnotationForParam(name, param, types), ); @@ -334,20 +350,22 @@ function buildMethodSchema( value.returnType, types, ); + return { name, + optional: property.optional, typeAnnotation: { type: 'FunctionTypeAnnotation', returnTypeAnnotation, params, - optional: property.optional, + nullable, }, }; } function getMethods( types: TypeDeclarationMap, -): $ReadOnlyArray { +): $ReadOnlyArray { const moduleInterfaceNames = Object.keys(types).filter((typeName: string) => { const declaration = types[typeName]; return ( @@ -368,8 +386,7 @@ function getMethods( const declaration = types[moduleInterfaceName]; return declaration.body.properties .filter(property => property.type === 'ObjectTypeProperty') - .map(property => buildMethodSchema(property, types)) - .filter(Boolean); + .map(property => buildMethodSchema(property, types)); } module.exports = {