From 094a9b585d329c8659e334b9dde3da8d07b44495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Osadnik?= Date: Thu, 1 Aug 2019 04:19:28 -0700 Subject: [PATCH] Add e2e tests and bunch of improvements for codegen Summary: This diff contains bunch of minor and straightforward fixes which need to be shipped together. They are all related to integrating objCpp codegen and compiling examples. #Facebook I explain in comments my thoughts Reviewed By: RSNara Differential Revision: D16520560 fbshipit-source-id: 15392017a92f5a7ec5da71b552ec6c6904625a86 --- packages/react-native-codegen/BUCK | 6 +- .../buck_tests/emptyFile.cpp | 2 - .../modules/NativeObjectTurboModule.js | 39 ++- .../modules/GenerateModuleHObjCpp.js | 72 ++++- .../generators/modules/GenerateModuleMm.js | 77 ++++- .../modules/ObjCppUtils/GenerateStructs.js | 32 +-- .../GenerateStructsForConstants.js | 13 +- .../modules/__test_fixtures__/fixtures.js | 101 +++++++ .../GenerateModuleCpp-test.js.snap | 31 +++ .../GenerateModuleH-test.js.snap | 32 +++ .../GenerateModuleHObjCpp-test.js.snap | 260 ++++++++++++++++- .../GenerateModuleMm-test.js.snap | 51 ++++ .../GenerateStructs-test.js.snap | 263 ++++++++---------- 13 files changed, 773 insertions(+), 206 deletions(-) diff --git a/packages/react-native-codegen/BUCK b/packages/react-native-codegen/BUCK index 06bfef1f59c..b14a33976e7 100644 --- a/packages/react-native-codegen/BUCK +++ b/packages/react-native-codegen/BUCK @@ -1,4 +1,4 @@ -load("@fbsource//tools/build_defs:default_platform_defs.bzl", "ANDROID", "APPLE") +load("@fbsource//tools/build_defs:default_platform_defs.bzl", "ANDROID", "APPLE", "IOS") load("@fbsource//tools/build_defs:fb_native_wrapper.bzl", "fb_native") load("@fbsource//tools/build_defs:fb_xplat_cxx_binary.bzl", "fb_xplat_cxx_binary") load("@fbsource//tools/build_defs/oss:rn_defs.bzl", "rn_android_library", "rn_xplat_cxx_library") @@ -68,7 +68,6 @@ fb_xplat_cxx_binary( visibility = ["PUBLIC"], deps = [ ":generated_components-codegen_tests", - ":generated_modules-codegen_tests", ], ) @@ -107,7 +106,6 @@ rn_xplat_cxx_library( ], deps = [ ":generated_components-codegen_tests", - ":generated_modules-codegen_tests", ], ) @@ -115,6 +113,7 @@ rn_xplat_cxx_library( name = "rn_codegen_library_mm", srcs = ["buck_tests/emptyFile.mm"], headers = [], + apple_sdks = (IOS,), compiler_flags = [ "-fexceptions", "-frtti", @@ -130,6 +129,7 @@ rn_xplat_cxx_library( "PUBLIC", ], deps = [ + "fbsource//xplat/js:React", ":generated_components-codegen_tests", ":generated_modules-codegen_tests", ], diff --git a/packages/react-native-codegen/buck_tests/emptyFile.cpp b/packages/react-native-codegen/buck_tests/emptyFile.cpp index 8359d471ce8..156913d4dfa 100644 --- a/packages/react-native-codegen/buck_tests/emptyFile.cpp +++ b/packages/react-native-codegen/buck_tests/emptyFile.cpp @@ -1,6 +1,4 @@ #import -#import -#import // TODO: Import every prop and event to asset they're generated diff --git a/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeObjectTurboModule.js b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeObjectTurboModule.js index b2761cbecd5..beafdf8f437 100644 --- a/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeObjectTurboModule.js +++ b/packages/react-native-codegen/e2e/__test_fixtures__/modules/NativeObjectTurboModule.js @@ -19,10 +19,43 @@ type AnotherGenericObject = GenericObject; export interface Spec extends TurboModule { +getGenericObject: (arg: Object) => Object; +getGenericObjectWithAlias: (arg: GenericObject) => AnotherGenericObject; + +difficultObject: (A: {| + D: boolean, + E: {| + D: boolean, + E: number, + F: string, + |}, + F: string, + |}) => {| + D: boolean, + E: {| + D: boolean, + E: {| + D: boolean, + E: number, + F: string, + |}, + F: string, + |}, + F: string, + |}; +getConstants: () => {| - const1: boolean, - const2: number, - const3: string, + D: boolean, + E: {| + D: boolean, + E: {| + D: boolean, + E: {| + D: boolean, + E: number, + F: string, + |}, + F: string, + |}, + F: string, + |}, + F: string, |}; } diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js index 3ba5cf40fc1..f2555ea6dcd 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js @@ -14,8 +14,14 @@ import type { SchemaType, FunctionTypeAnnotationParamTypeAnnotation, FunctionTypeAnnotationReturn, + ObjectParamTypeAnnotation, } from '../../CodegenSchema'; +const { + translateObjectsForStructs, + capitalizeFirstLetter, +} = require('./ObjCppUtils/GenerateStructs'); + type FilesOutput = Map; const moduleTemplate = ` @@ -24,7 +30,9 @@ public: Native::_MODULE_NAME_::SpecJSI(id instance, std::shared_ptr jsInvoker); };`; -const protolocTemplate = ` +const protocolTemplate = ` +::_STRUCTS_:: + @protocol Native::_MODULE_NAME_::Spec ::_MODULE_PROPERTIES_:: @end @@ -56,6 +64,10 @@ const template = ` #import #import +#import +#import +#import +#import ::_PROTOCOLS_:: @@ -67,6 +79,17 @@ namespace react { } // namespace facebook `; +type ObjectForGeneratingStructs = $ReadOnly<{| + name: string, + object: $ReadOnly<{| + type: 'ObjectTypeAnnotation', + properties: $ReadOnlyArray, + |}>, +|}>; + +const constants = `- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants;`; + function translatePrimitiveJSTypeToObjCType( type: | FunctionTypeAnnotationParamTypeAnnotation @@ -86,13 +109,13 @@ function translatePrimitiveJSTypeToObjCType( case 'BooleanTypeAnnotation': return 'BOOL'; case 'GenericObjectTypeAnnotation': - case 'ObjectTypeAnnotation': return 'NSDictionary *'; case 'ArrayTypeAnnotation': return 'NSArray> *'; case 'FunctionTypeAnnotation': return 'RCTResponseSenderBlock'; - + case 'ObjectTypeAnnotation': + return 'NSDictionary *'; default: throw new Error(error); } @@ -120,11 +143,26 @@ module.exports = { const protocols = Object.keys(nativeModules) .map(name => { + const objectForGeneratingStructs: Array = []; const {properties} = nativeModules[name]; const implementations = properties .map(prop => { const nativeArgs = prop.typeAnnotation.params .map((param, i) => { + if ( + param.typeAnnotation.type === 'ObjectTypeAnnotation' && + param.typeAnnotation.properties + ) { + objectForGeneratingStructs.push({ + name: + capitalizeFirstLetter(prop.name) + + capitalizeFirstLetter(param.name), + object: { + type: 'ObjectTypeAnnotation', + properties: param.typeAnnotation.properties, + }, + }); + } const paramObjCType = translatePrimitiveJSTypeToObjCType( param.typeAnnotation, `Unspopported type for param "${param.name}" in ${ @@ -137,12 +175,26 @@ module.exports = { }) .join('\n ') .concat(callbackArgs(prop)); + const {returnTypeAnnotation} = prop.typeAnnotation; + if ( + returnTypeAnnotation.type === 'ObjectTypeAnnotation' && + returnTypeAnnotation.properties + ) { + objectForGeneratingStructs.push({ + name: capitalizeFirstLetter(prop.name) + 'ReturnType', + + object: { + type: 'ObjectTypeAnnotation', + properties: returnTypeAnnotation.properties, + }, + }); + } const implementation = methodImplementationTemplate .replace('::_PROPERTY_NAME_::', prop.name) .replace( '::_RETURN_VALUE_::', translatePrimitiveJSTypeToObjCType( - prop.typeAnnotation.returnTypeAnnotation, + returnTypeAnnotation, `Unspopported return type for ${prop.name}. Found: ${ prop.typeAnnotation.returnTypeAnnotation.type }`, @@ -150,16 +202,16 @@ module.exports = { ) .replace('::_ARGS_::', nativeArgs); if (prop.name === 'getConstants') { - return ( - implementation + - '\n' + - implementation.replace('getConstants', 'constantsToExport') - ); + return constants.replace(/::_MODULE_NAME_::/, name); } return implementation; }) .join('\n'); - return protolocTemplate + return protocolTemplate + .replace( + /::_STRUCTS_::/g, + translateObjectsForStructs(objectForGeneratingStructs), + ) .replace(/::_MODULE_PROPERTIES_::/g, implementations) .replace(/::_MODULE_NAME_::/g, name) .replace('::_PROPERTIES_MAP_::', ''); diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js index 5c5f4e31b82..5acd161969e 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js @@ -10,7 +10,10 @@ 'use strict'; -import type {SchemaType} from '../../CodegenSchema'; +import type {SchemaType, NativeModuleShape} from '../../CodegenSchema'; + +const {capitalizeFirstLetter} = require('./ObjCppUtils/GenerateStructs'); +const {flatObjects} = require('./ObjCppUtils/Utils'); type FilesOutput = Map; @@ -36,6 +39,15 @@ Native::_MODULE_NAME_::SpecJSI::Native::_MODULE_NAME_::SpecJSI(id(json); +} +@end +`.trim(); + const template = ` /** * Copyright (c) Facebook, Inc. and its affiliates. @@ -45,7 +57,7 @@ const template = ` */ #include - +::_GETTERS_:: namespace facebook { namespace react { @@ -117,7 +129,9 @@ function tranlsateMethodForImplementation(property): string { module.exports = { generate(libraryName: string, schema: SchemaType): FilesOutput { - const nativeModules = Object.keys(schema.modules) + const nativeModules: {[name: string]: NativeModuleShape} = Object.keys( + schema.modules, + ) .map(moduleName => { const modules = schema.modules[moduleName].nativeModules; if (modules == null) { @@ -129,6 +143,62 @@ module.exports = { .filter(Boolean) .reduce((acc, modules) => Object.assign(acc, modules), {}); + const gettersImplementations = Object.keys(nativeModules) + .reduce((acc, moduleName: string) => { + const module: NativeModuleShape = nativeModules[moduleName]; + return acc.concat( + flatObjects( + module.properties.reduce((moduleAcc, property) => { + const {returnTypeAnnotation} = property.typeAnnotation; + if (returnTypeAnnotation.type === 'ObjectTypeAnnotation') { + const {properties} = returnTypeAnnotation; + if (properties) { + moduleAcc.push({ + name: capitalizeFirstLetter(property.name) + 'ReturnType', + object: { + type: 'ObjectTypeAnnotation', + properties: properties, + }, + }); + } + } + if (property.typeAnnotation.params) { + return moduleAcc.concat( + property.typeAnnotation.params + .map(param => { + if ( + param.typeAnnotation.type === 'ObjectTypeAnnotation' + ) { + const {properties} = param.typeAnnotation; + if (properties) { + return { + name: + capitalizeFirstLetter(property.name) + + capitalizeFirstLetter(param.name), + object: { + type: 'ObjectTypeAnnotation', + properties: properties, + }, + }; + } + } + }) + .filter(Boolean), + ); + } + return moduleAcc; + }, []), + ) + .map(object => + getterTemplate + .replace(/::_GETTER_NAME_::/g, object.name) + .replace(/::_MODULE_NAME_::/g, moduleName), + ) + .join('\n'), + ); + }, []) + .join('\n'); + const modules = Object.keys(nativeModules) .map(name => { const {properties} = nativeModules[name]; @@ -153,6 +223,7 @@ module.exports = { const fileName = 'RCTNativeModules.mm'; const replacedTemplate = template + .replace(/::_GETTERS_::/g, gettersImplementations) .replace(/::_MODULES_::/g, modules) .replace(/::_LIBRARY_NAME_::/g, libraryName); return new Map([[fileName, replacedTemplate]]); diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js index 5603aae33b3..30743826ba9 100644 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js +++ b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js @@ -11,23 +11,12 @@ 'use strict'; import type {ObjectParamTypeAnnotation} from '../../../CodegenSchema'; -import {flatObjects, capitalizeFirstLetter} from './Utils'; -import {generateStructsForConstants} from './GenerateStructsForConstants'; +const {flatObjects, capitalizeFirstLetter} = require('./Utils'); +const {generateStructsForConstants} = require('./GenerateStructsForConstants'); const template = ` -/** - * 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. - */ - #import -::_CONSTANTS_:: - -::_STRUCTS_:: - -::_INLINES_:: +::_CONSTANTS_::::_STRUCTS_::::_INLINES_:: `; const structTemplate = ` @@ -49,7 +38,7 @@ namespace JS { `; const inlineTemplate = ` -inline ::_RETURN_TYPE_:: *JS::Native::_MODULE_NAME_::::Spec::_STRUCT_NAME_::::::_PROPERTY_NAME_::() const +inline ::_RETURN_TYPE_::JS::Native::_MODULE_NAME_::::Spec::_STRUCT_NAME_::::::_PROPERTY_NAME_::() const { id const p = _v[@"a"]; return ::_RETURN_VALUE_::; @@ -95,22 +84,22 @@ function getInlineMethodImplementation( switch (typeAnnotation.type) { case 'StringTypeAnnotation': return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'NSString') + .replace(/::_RETURN_TYPE_::/, 'NSString *') .replace(/::_RETURN_VALUE_::/, 'RCTBridgingToString(p)'); case 'NumberTypeAnnotation': case 'FloatTypeAnnotation': case 'Int32TypeAnnotation': return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'double') + .replace(/::_RETURN_TYPE_::/, 'double ') .replace(/::_RETURN_VALUE_::/, 'RCTBridgingToDouble(p)'); case 'BooleanTypeAnnotation': return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'bool') + .replace(/::_RETURN_TYPE_::/, 'bool ') .replace(/::_RETURN_VALUE_::/, 'RCTBridgingToBool(p)'); case 'GenericObjectTypeAnnotation': case 'AnyTypeAnnotation': return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'id') + .replace(/::_RETURN_TYPE_::/, 'id *') .replace(/::_RETURN_VALUE_::/, 'p'); case 'ObjectTypeAnnotation': return inlineTemplate @@ -118,7 +107,7 @@ function getInlineMethodImplementation( /::_RETURN_TYPE_::/, `JS::Native::_MODULE_NAME_::::Spec${name}${capitalizeFirstLetter( property.name, - )}`, + )} `, ) .replace( /::_RETURN_VALUE_::/, @@ -130,7 +119,7 @@ function getInlineMethodImplementation( return inlineTemplate .replace( /::_RETURN_TYPE_::/, - 'facebook::react::LazyVector>', + 'facebook::react::LazyVector> *', ) .replace( /::_RETURN_VALUE_::/, @@ -180,6 +169,7 @@ function translateObjectsForStructs( ) .replace(/::_STRUCT_NAME_::/g, object.name), ) + .reverse() .join('\n'); const translatedConstants = generateStructsForConstants(annotations); diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js index eb8bb813d57..a352af5d281 100644 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js +++ b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js @@ -11,7 +11,7 @@ 'use strict'; import type {ObjectParamTypeAnnotation} from '../../../CodegenSchema'; -import {flatObjects, capitalizeFirstLetter} from './Utils'; +const {flatObjects, capitalizeFirstLetter} = require('./Utils'); const structTemplate = ` namespace JS { @@ -42,13 +42,6 @@ namespace JS { } } -@protocol Native::_MODULE_NAME_::Spec - -- (facebook::react::ModuleConstants)constantsToExport; -- (facebook::react::ModuleConstants)getConstants; - -@end - inline JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::Builder::Builder(const Input i) : _factory(^{ NSMutableDictionary *d = [NSMutableDictionary new]; ::_PROPERTIES_:: @@ -119,7 +112,7 @@ function numberAndBoolGetter(name: string) { function unsafeGetter(name: string) { return ` auto ${name} = i.${name}.get(); - d[@"${name}"] = ${name}; + d[@"${name}"] = ${name}.buildUnsafeRawValue(); `.trim(); } @@ -179,7 +172,9 @@ function generateStructsForConstants( ), [], ) + .reverse() .join('\n') + .replace(/SpecGetConstantsReturnType/g, 'Constants') .replace(/GetConstantsReturnType/g, 'Constants'); } module.exports = { 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 b20abf2c8ec..7866eefccb4 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 @@ -351,7 +351,108 @@ const TWO_MODULES_DIFFERENT_FILES: SchemaType = { }, }; +const COMPLEX_OBJECTS: SchemaType = { + modules: { + NativeSampleTurboModule: { + nativeModules: { + SampleTurboModule: { + properties: [ + { + name: 'difficult', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'D', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + { + optional: false, + name: 'E', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'F', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + ], + }, + params: [ + { + nullable: false, + name: 'A', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'D', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + { + optional: false, + name: 'E', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'D', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + { + optional: false, + name: 'E', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'F', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + ], + }, + }, + { + optional: false, + name: 'F', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + ], + }, + }, + ], + optional: false, + }, + }, + ], + }, + }, + }, + }, +}; module.exports = { + COMPLEX_OBJECTS, TWO_MODULES_SAME_FILE, TWO_MODULES_DIFFERENT_FILES, EMPTY_NATIVE_MODULES, diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap index 932923f5025..f7b06ba7791 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap @@ -1,5 +1,36 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GenerateModuleCpp can generate fixture COMPLEX_OBJECTS 1`] = ` +Map { + "NativeModules.cpp" => " +/** + * 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. + */ + +#include + +namespace facebook { +namespace react { + +static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_difficult(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->difficult(rt, args[0].getObject(rt)); +} + +NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker) + : TurboModule(\\"SampleTurboModule\\", jsInvoker) { + methodMap_[\\"difficult\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_difficult}; +} + + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateModuleCpp can generate fixture EMPTY_NATIVE_MODULES 1`] = ` Map { "NativeModules.cpp" => " diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap index fa2609784ce..a047c9e9986 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap @@ -1,5 +1,37 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GenerateModuleCpp can generate fixture COMPLEX_OBJECTS 1`] = ` +Map { + "NativeModules.h" => " +/** + * 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. + */ + +#pragma once + +#include + +namespace facebook { +namespace react { + +class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { +protected: + NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); + +public: +virtual jsi::Object difficult(jsi::Runtime &rt, const jsi::Object &A) = 0; + +}; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateModuleCpp can generate fixture EMPTY_NATIVE_MODULES 1`] = ` Map { "NativeModules.h" => " diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap index e5d9f42e0ad..0013895d867 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap @@ -1,5 +1,172 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GenerateModuleHObjCpp can generate fixture COMPLEX_OBJECTS 1`] = ` +Map { + "RCTNativeModules.h" => " +/** + * 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. + */ + +// NOTE: This entire file should be codegen'ed. + +#import + +#import + +#import + +#import +#import +#import +#import +#import + + + +#import + +namespace JS { + namespace NativeSampleTurboModule { + struct SpecDifficultAE { + bool D() const; + double E() const; + NSString *F() const; + + SpecDifficultAE(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModule_SpecDifficultAE) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultAE:(id)json; +@end + + +namespace JS { + namespace NativeSampleTurboModule { + struct SpecDifficultReturnType { + bool D() const; + double E() const; + NSString *F() const; + + SpecDifficultReturnType(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModule_SpecDifficultReturnType) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultReturnType:(id)json; +@end + + +namespace JS { + namespace NativeSampleTurboModule { + struct SpecDifficultA { + bool D() const; + JS::NativeSampleTurboModule::SpecDifficultAE E() const; + NSString *F() const; + + SpecDifficultA(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModule_SpecDifficultA) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultA:(id)json; +@end + +inline bool JS::NativeSampleTurboModule::SpecDifficultA::D() const +{ + id const p = _v[@\\"a\\"]; + return RCTBridgingToBool(p); +} + + +inline JS::NativeSampleTurboModule::SpecDifficultAE JS::NativeSampleTurboModule::SpecDifficultA::E() const +{ + id const p = _v[@\\"a\\"]; + return JS::NativeSampleTurboModule::SpecDifficultAE(p); +} + + +inline NSString *JS::NativeSampleTurboModule::SpecDifficultA::F() const +{ + id const p = _v[@\\"a\\"]; + return RCTBridgingToString(p); +} + + +inline bool JS::NativeSampleTurboModule::SpecDifficultReturnType::D() const +{ + id const p = _v[@\\"a\\"]; + return RCTBridgingToBool(p); +} + + +inline double JS::NativeSampleTurboModule::SpecDifficultReturnType::E() const +{ + id const p = _v[@\\"a\\"]; + return RCTBridgingToDouble(p); +} + + +inline NSString *JS::NativeSampleTurboModule::SpecDifficultReturnType::F() const +{ + id const p = _v[@\\"a\\"]; + return RCTBridgingToString(p); +} + + +inline bool JS::NativeSampleTurboModule::SpecDifficultAE::D() const +{ + id const p = _v[@\\"a\\"]; + return RCTBridgingToBool(p); +} + + +inline double JS::NativeSampleTurboModule::SpecDifficultAE::E() const +{ + id const p = _v[@\\"a\\"]; + return RCTBridgingToDouble(p); +} + + +inline NSString *JS::NativeSampleTurboModule::SpecDifficultAE::F() const +{ + id const p = _v[@\\"a\\"]; + return RCTBridgingToString(p); +} + + + +@protocol NativeSampleTurboModuleSpec +- (NSDictionary *) difficult:(NSDictionary *)A; +@end + + +namespace facebook { +namespace react { + +class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { +public: + NativeSampleTurboModuleSpecJSI(id instance, std::shared_ptr jsInvoker); +}; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateModuleHObjCpp can generate fixture EMPTY_NATIVE_MODULES 1`] = ` Map { "RCTNativeModules.h" => " @@ -19,6 +186,15 @@ Map { #import #import +#import +#import +#import +#import + + + +#import + @protocol NativeSampleTurboModuleSpec @@ -59,11 +235,63 @@ Map { #import #import +#import +#import +#import +#import + + + +#import + +namespace JS { + namespace NativeSampleTurboModule { + struct Constants { + + struct Builder { + struct Input { + RCTRequired const1; + RCTRequired const2; + RCTRequired const3; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} + +inline JS::NativeSampleTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto const1 = i.const1.get(); + d[@\\"const1\\"] = @(const1); +auto const2 = i.const2.get(); + d[@\\"const2\\"] = @(const2); +auto const3 = i.const3.get(); + d[@\\"const3\\"] = const3; + return d; +}) {} +inline JS::NativeSampleTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} @protocol NativeSampleTurboModuleSpec -- (NSDictionary *) getConstants; -- (NSDictionary *) constantsToExport; +- (facebook::react::ModuleConstants)constantsToExport; +- (facebook::react::ModuleConstants)getConstants; - (void) voidFunc; - (BOOL) getBool:(BOOL)arg; - (NSNumber *) getNumber:(NSNumber *)arg; @@ -113,6 +341,15 @@ Map { #import #import +#import +#import +#import +#import + + + +#import + @protocol NativeSampleTurboModuleSpec @@ -120,6 +357,11 @@ Map { @end + +#import + + + @protocol NativeSample2TurboModuleSpec - (void) voidFunc; @end @@ -163,6 +405,15 @@ Map { #import #import +#import +#import +#import +#import + + + +#import + @protocol NativeSampleTurboModuleSpec @@ -170,6 +421,11 @@ Map { @end + +#import + + + @protocol NativeSample2TurboModuleSpec - (void) voidFunc; @end diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap index b500c709695..36ee8c57fd6 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap @@ -1,5 +1,54 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`GenerateModuleHObjCpp can generate fixture COMPLEX_OBJECTS 1`] = ` +Map { + "RCTNativeModules.mm" => " +/** + * 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. + */ + +#include +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultReturnType) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultReturnType:(id)json +{ + return facebook::react::managedPointer(json); +} +@end +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultA) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultA:(id)json +{ + return facebook::react::managedPointer(json); +} +@end +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultAE) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultAE:(id)json +{ + return facebook::react::managedPointer(json); +} +@end +namespace facebook { +namespace react { + +static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_difficult(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, ObjectKind, \\"difficult\\", @selector(difficult:), args, count); +} + +NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule(\\"SampleTurboModule\\", instance, jsInvoker) { + methodMap_[\\"difficult\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_difficult}; +} + + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateModuleHObjCpp can generate fixture EMPTY_NATIVE_MODULES 1`] = ` Map { "RCTNativeModules.mm" => " @@ -118,6 +167,7 @@ Map { #include + namespace facebook { namespace react { @@ -159,6 +209,7 @@ Map { #include + namespace facebook { namespace react { diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateStructs-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateStructs-test.js.snap index 7c17abfbd09..64022c3fea1 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateStructs-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateStructs-test.js.snap @@ -2,120 +2,8 @@ exports[`GenerateStructs can generate fixture SIMPLE_CONSTANTS 1`] = ` " -/** - * 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. - */ - #import -namespace JS { - namespace NativeSampleTurboModule { - struct Constants { - - struct Builder { - struct Input { - RCTRequired a; - RCTRequired b; - RCTRequired c; - RCTRequired d; - }; - - /** Initialize with a set of values */ - Builder(const Input i); - /** Initialize with an existing Constants */ - Builder(Constants i); - /** Builds the object. Generally used only by the infrastructure. */ - NSDictionary *buildUnsafeRawValue() const { return _factory(); }; - private: - NSDictionary *(^_factory)(void); - }; - - static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } - NSDictionary *unsafeRawValue() const { return _v; } - private: - Constants(NSDictionary *const v) : _v(v) {} - NSDictionary *_v; - }; - } -} - -@protocol NativeSampleTurboModuleSpec - -- (facebook::react::ModuleConstants)constantsToExport; -- (facebook::react::ModuleConstants)getConstants; - -@end - -inline JS::NativeSampleTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ - NSMutableDictionary *d = [NSMutableDictionary new]; - auto a = i.a.get(); - d[@\\"a\\"] = @(a); -auto b = i.b.get(); - d[@\\"b\\"] = @(b); -auto c = i.c.get(); - d[@\\"c\\"] = c; -auto d = i.d.get(); - d[@\\"d\\"] = d; - return d; -}) {} -inline JS::NativeSampleTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ - return i.unsafeRawValue(); -}) {} - -namespace JS { - namespace NativeSampleTurboModule { - struct ConstantsD { - - struct Builder { - struct Input { - RCTRequired e; - RCTRequired f; - RCTRequired g; - }; - - /** Initialize with a set of values */ - Builder(const Input i); - /** Initialize with an existing ConstantsD */ - Builder(ConstantsD i); - /** Builds the object. Generally used only by the infrastructure. */ - NSDictionary *buildUnsafeRawValue() const { return _factory(); }; - private: - NSDictionary *(^_factory)(void); - }; - - static ConstantsD fromUnsafeRawValue(NSDictionary *const v) { return {v}; } - NSDictionary *unsafeRawValue() const { return _v; } - private: - ConstantsD(NSDictionary *const v) : _v(v) {} - NSDictionary *_v; - }; - } -} - -@protocol NativeSampleTurboModuleSpec - -- (facebook::react::ModuleConstants)constantsToExport; -- (facebook::react::ModuleConstants)getConstants; - -@end - -inline JS::NativeSampleTurboModule::ConstantsD::Builder::Builder(const Input i) : _factory(^{ - NSMutableDictionary *d = [NSMutableDictionary new]; - auto e = i.e.get(); - d[@\\"e\\"] = @(e); -auto f = i.f.get(); - d[@\\"f\\"] = @(f); -auto g = i.g.get(); - d[@\\"g\\"] = g; - return d; -}) {} -inline JS::NativeSampleTurboModule::ConstantsD::Builder::Builder(ConstantsD i) : _factory(^{ - return i.unsafeRawValue(); -}) {} - namespace JS { namespace NativeSampleTurboModule { struct ConstantsDG { @@ -146,13 +34,6 @@ namespace JS { } } -@protocol NativeSampleTurboModuleSpec - -- (facebook::react::ModuleConstants)constantsToExport; -- (facebook::react::ModuleConstants)getConstants; - -@end - inline JS::NativeSampleTurboModule::ConstantsDG::Builder::Builder(const Input i) : _factory(^{ NSMutableDictionary *d = [NSMutableDictionary new]; auto h = i.h.get(); @@ -167,42 +48,119 @@ inline JS::NativeSampleTurboModule::ConstantsDG::Builder::Builder(ConstantsDG i) return i.unsafeRawValue(); }) {} +namespace JS { + namespace NativeSampleTurboModule { + struct ConstantsD { + struct Builder { + struct Input { + RCTRequired e; + RCTRequired f; + RCTRequired g; + }; + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ConstantsD */ + Builder(ConstantsD i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + static ConstantsD fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ConstantsD(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} + +inline JS::NativeSampleTurboModule::ConstantsD::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto e = i.e.get(); + d[@\\"e\\"] = @(e); +auto f = i.f.get(); + d[@\\"f\\"] = @(f); +auto g = i.g.get(); + d[@\\"g\\"] = g.buildUnsafeRawValue(); + return d; +}) {} +inline JS::NativeSampleTurboModule::ConstantsD::Builder::Builder(ConstantsD i) : _factory(^{ + return i.unsafeRawValue(); +}) {} + +namespace JS { + namespace NativeSampleTurboModule { + struct Constants { + + struct Builder { + struct Input { + RCTRequired a; + RCTRequired b; + RCTRequired c; + RCTRequired d; + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing Constants */ + Builder(Constants i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static Constants fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + Constants(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +} + +inline JS::NativeSampleTurboModule::Constants::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; + auto a = i.a.get(); + d[@\\"a\\"] = @(a); +auto b = i.b.get(); + d[@\\"b\\"] = @(b); +auto c = i.c.get(); + d[@\\"c\\"] = c; +auto d = i.d.get(); + d[@\\"d\\"] = d.buildUnsafeRawValue(); + return d; +}) {} +inline JS::NativeSampleTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ + return i.unsafeRawValue(); +}) {} " `; exports[`GenerateStructs can generate fixture SIMPLE_STRUCT 1`] = ` " -/** - * 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. - */ - #import - - namespace JS { namespace NativeSampleTurboModule { - struct SpecSampleFuncReturnType { - bool a() const; - double b() const; - NSString *c() const; - JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD d() const; + struct SpecSampleFuncReturnTypeDG { + bool h() const; + double i() const; + NSString *j() const; - SpecSampleFuncReturnType(NSDictionary *const v) : _v(v) {} + SpecSampleFuncReturnTypeDG(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeSampleTurboModule_SpecSampleFuncReturnType) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecSampleFuncReturnType:(id)json; +@interface RCTCxxConvert (NativeSampleTurboModule_SpecSampleFuncReturnTypeDG) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecSampleFuncReturnTypeDG:(id)json; @end @@ -227,32 +185,31 @@ namespace JS { namespace JS { namespace NativeSampleTurboModule { - struct SpecSampleFuncReturnTypeDG { - bool h() const; - double i() const; - NSString *j() const; + struct SpecSampleFuncReturnType { + bool a() const; + double b() const; + NSString *c() const; + JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD d() const; - SpecSampleFuncReturnTypeDG(NSDictionary *const v) : _v(v) {} + SpecSampleFuncReturnType(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeSampleTurboModule_SpecSampleFuncReturnTypeDG) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecSampleFuncReturnTypeDG:(id)json; +@interface RCTCxxConvert (NativeSampleTurboModule_SpecSampleFuncReturnType) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecSampleFuncReturnType:(id)json; @end - - -inline bool *JS::NativeSampleTurboModule::SpecSampleFuncReturnType::a() const +inline bool JS::NativeSampleTurboModule::SpecSampleFuncReturnType::a() const { id const p = _v[@\\"a\\"]; return RCTBridgingToBool(p); } -inline double *JS::NativeSampleTurboModule::SpecSampleFuncReturnType::b() const +inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnType::b() const { id const p = _v[@\\"a\\"]; return RCTBridgingToDouble(p); @@ -266,42 +223,42 @@ inline NSString *JS::NativeSampleTurboModule::SpecSampleFuncReturnType::c() cons } -inline JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD *JS::NativeSampleTurboModule::SpecSampleFuncReturnType::d() const +inline JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD JS::NativeSampleTurboModule::SpecSampleFuncReturnType::d() const { id const p = _v[@\\"a\\"]; return JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD(p); } -inline bool *JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::e() const +inline bool JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::e() const { id const p = _v[@\\"a\\"]; return RCTBridgingToBool(p); } -inline double *JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::f() const +inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::f() const { id const p = _v[@\\"a\\"]; return RCTBridgingToDouble(p); } -inline JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG *JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::g() const +inline JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::g() const { id const p = _v[@\\"a\\"]; return JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG(p); } -inline bool *JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG::h() const +inline bool JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG::h() const { id const p = _v[@\\"a\\"]; return RCTBridgingToBool(p); } -inline double *JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG::i() const +inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG::i() const { id const p = _v[@\\"a\\"]; return RCTBridgingToDouble(p);