From c267b8de7291a0aef67f6fb24d78dbc85385c120 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 29 Sep 2020 14:33:06 -0700 Subject: [PATCH] Rewrite ObjC++ module generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: ## Misc. Improvements * We now have 95%+ flow coverage in all generator files. Henceforth, we can make changes to these files with more confidence, and trust flow to catch more errors. This should also improve the DevX of working on these files. * Better templates: Instead of doing string replace with RegExps, we instead use functions and leverage JS template literals to generate our code. A few benefits: (1) data dependencies of templates are clearly visible, and statically checked by flow, (2) the templates are more readable in VSCode. * Merged the GenerateModuleHObjCpp.js and GenerateModuleMm.js generators. They can share a lot of logic, so it's not a good idea to keep them separate. * The ObjC++ module generator no longer generates “dead” structs (i.e structs that aren’t used by type-safety infra). In fact, it explicitly only supports the types in our Wiki. (I know this wasn’t the case with the legacy codegen, because we were generating native code for enums in the legacy codegen). This is a mixed bag. The test to verify correctness will be more difficult to write. However, keeping structs in the codegen needlessly complicates the parsers + generators, and creates technical debt for us to clean up later. ## Abstractions - **StructCollector:** As we serialize NativeModule methods, when we detect an ObjectTypeAnnotation in the return type of `getConstants()` or inside a method param, we must create a Struct JS object for it. When we detect a type-alias (also in the same locations), we must look up that type-alias and create a Struct from its RHS. A Struct is basically an ObjectTypeAnnotation with a context (i.e: used in getConstants() vs as a method param), that cannot contain other ObjectTypeAnnotations. - **serializeMethod.js** Given a NativeModule method type annotation, output the protocol method, JS return type, selector, a record of which params were structs, and which structs. Basically, this is all the information necessary to generate the declaration and implementation codegen for a partiular NativeModule method. - **serializeStruct/*.js**: After creating all these Structs, we need to loop over all of them, and tranform them into ObjC++ code. - **serializeStruct.js**: Depending on the struct context, calls either `serializeRegularStruct.js` or `serializeConstantsStruct.js`. Both of these files have the same layout/abstractions. They look very similar. - **serializeModule.js:** Outputs RCTCxxConvert categories for transforming `NSDictionary *` into C++ structs. Outputs ObjCTurboModule subclass. ## Algorithm ``` for spec in NativeModuleSpecs structCollector = new StructCollector resolveAlias = (aliasName) => nullthrows(spec.aliases[aliasName]) methodDatas = [] for method in methods(spec) methodData.push(serializeMethod(method, structCollector, resolveAlias)) end structs = structCollector.getStructs() output generateImplCodegen(methodDatas, structs) output generateHeaderCodegen(methodDatas, structs) end ``` Changelog: [Internal] Reviewed By: hramos Differential Revision: D23633940 fbshipit-source-id: 7c29f458b65434f4865ef1993061b0f0dc7d04ce --- Libraries/TypeSafety/RCTConvertHelpers.h | 1 + Libraries/TypeSafety/RCTConvertHelpers.mm | 6 + packages/react-native-codegen/.babelrc | 1 + packages/react-native-codegen/package.json | 1 + .../src/generators/RNCodegen.js | 6 +- .../modules/GenerateModuleHObjCpp.js | 414 ------ .../generators/modules/GenerateModuleMm.js | 320 ----- .../GenerateModuleObjCpp/StructCollector.js | 191 +++ .../modules/GenerateModuleObjCpp/Utils.js | 36 + .../header/serializeConstantsStruct.js | 263 ++++ .../header/serializeRegularStruct.js | 251 ++++ .../header/serializeStruct.js | 35 + .../modules/GenerateModuleObjCpp/index.js | 210 +++ .../GenerateModuleObjCpp/serializeMethod.js | 413 ++++++ .../source/serializeModule.js | 125 ++ .../modules/ObjCppUtils/GenerateStructs.js | 452 ------- .../GenerateStructsForConstants.js | 275 ---- .../generators/modules/ObjCppUtils/Utils.js | 112 -- .../__test_fixtures__/structFixtures.js | 218 --- .../__tests__/GenerateModuleHObjCpp-test.js | 5 +- .../__tests__/GenerateModuleMm-test.js | 7 +- .../modules/__tests__/GenerateStructs-test.js | 31 - .../GenerateModuleHObjCpp-test.js.snap | 1169 ++++++----------- .../GenerateModuleMm-test.js.snap | 624 +++++---- .../GenerateStructs-test.js.snap | 284 ---- 25 files changed, 2335 insertions(+), 3115 deletions(-) delete mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js delete mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/Utils.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js create mode 100644 packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js delete mode 100644 packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js delete mode 100644 packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js delete mode 100644 packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js delete mode 100644 packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js delete mode 100644 packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js delete mode 100644 packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateStructs-test.js.snap diff --git a/Libraries/TypeSafety/RCTConvertHelpers.h b/Libraries/TypeSafety/RCTConvertHelpers.h index 1b6bf9341e7..0b7144b9c8e 100644 --- a/Libraries/TypeSafety/RCTConvertHelpers.h +++ b/Libraries/TypeSafety/RCTConvertHelpers.h @@ -49,6 +49,7 @@ NSArray *RCTConvertOptionalVecToArray(const folly::Optional &vec) bool RCTBridgingToBool(id value); folly::Optional RCTBridgingToOptionalBool(id value); NSString *RCTBridgingToString(id value); +NSString *RCTBridgingToOptionalString(id value); folly::Optional RCTBridgingToOptionalDouble(id value); double RCTBridgingToDouble(id value); NSArray *RCTBridgingToArray(id value); diff --git a/Libraries/TypeSafety/RCTConvertHelpers.mm b/Libraries/TypeSafety/RCTConvertHelpers.mm index 69fb3e4a3de..cd79c41f6fe 100644 --- a/Libraries/TypeSafety/RCTConvertHelpers.mm +++ b/Libraries/TypeSafety/RCTConvertHelpers.mm @@ -27,6 +27,12 @@ NSString *RCTBridgingToString(id value) return [RCTConvert NSString:RCTNilIfNull(value)]; } +NSString *RCTBridgingToOptionalString(id value) +{ + return RCTBridgingToString(value); +} + + folly::Optional RCTBridgingToOptionalDouble(id value) { if (!RCTNilIfNull(value)) { diff --git a/packages/react-native-codegen/.babelrc b/packages/react-native-codegen/.babelrc index b8ac81899b7..7a6194fbaa5 100644 --- a/packages/react-native-codegen/.babelrc +++ b/packages/react-native-codegen/.babelrc @@ -5,6 +5,7 @@ "@babel/plugin-transform-destructuring", "@babel/plugin-transform-flow-strip-types", "@babel/plugin-syntax-dynamic-import", + "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-nullish-coalescing-operator", "@babel/plugin-proposal-optional-chaining" ] diff --git a/packages/react-native-codegen/package.json b/packages/react-native-codegen/package.json index 6f6cac7bb35..014bd035653 100644 --- a/packages/react-native-codegen/package.json +++ b/packages/react-native-codegen/package.json @@ -24,6 +24,7 @@ }, "devDependencies": { "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", "@babel/plugin-proposal-optional-chaining": "^7.0.0", diff --git a/packages/react-native-codegen/src/generators/RNCodegen.js b/packages/react-native-codegen/src/generators/RNCodegen.js index 576d984abd8..b6f6e02a922 100644 --- a/packages/react-native-codegen/src/generators/RNCodegen.js +++ b/packages/react-native-codegen/src/generators/RNCodegen.js @@ -25,11 +25,10 @@ const generatePropsCpp = require('./components/GeneratePropsCpp.js'); const generatePropsH = require('./components/GeneratePropsH.js'); const generateModuleH = require('./modules/GenerateModuleH.js'); const generateModuleCpp = require('./modules/GenerateModuleCpp.js'); -const generateModuleHObjCpp = require('./modules/GenerateModuleHObjCpp.js'); +const generateModuleObjCpp = require('./modules/GenerateModuleObjCpp'); const generateModuleJavaSpec = require('./modules/GenerateModuleJavaSpec.js'); const GenerateModuleJniCpp = require('./modules/GenerateModuleJniCpp.js'); const GenerateModuleJniH = require('./modules/GenerateModuleJniH.js'); -const generateModuleMm = require('./modules/GenerateModuleMm.js'); const generatePropsJavaInterface = require('./components/GeneratePropsJavaInterface.js'); const generatePropsJavaDelegate = require('./components/GeneratePropsJavaDelegate.js'); const generateTests = require('./components/GenerateTests.js'); @@ -74,8 +73,7 @@ const GENERATORS = { modules: [ generateModuleCpp.generate, generateModuleH.generate, - generateModuleHObjCpp.generate, - generateModuleMm.generate, + generateModuleObjCpp.generate, ], // TODO: Refactor this to consolidate various C++ output variation instead of forking Android. modulesAndroid: [ diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js deleted file mode 100644 index cd54439ff91..00000000000 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js +++ /dev/null @@ -1,414 +0,0 @@ -/** - * 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 strict - * @format - */ - -'use strict'; - -import type { - SchemaType, - FunctionTypeAnnotationParam, - FunctionTypeAnnotationReturn, - ObjectParamTypeAnnotation, - ObjectTypeAliasTypeShape, -} from '../../CodegenSchema'; - -const { - translateObjectsForStructs, - capitalizeFirstLetter, - getNamespacedStructName, -} = require('./ObjCppUtils/GenerateStructs'); - -const {getTypeAliasTypeAnnotation} = require('./Utils'); - -type FilesOutput = Map; - -const moduleTemplate = ` /** - * ObjC++ class for module '::_MODULE_NAME_::' - */ - class JSI_EXPORT Native::_MODULE_NAME_::SpecJSI : public ObjCTurboModule { - public: - Native::_MODULE_NAME_::SpecJSI(const ObjCTurboModule::InitParams ¶ms); - };`; - -const protocolTemplate = `::_STRUCTS_:: - -@protocol Native::_MODULE_NAME_::Spec -::_MODULE_PROPERTIES_:: -@end -`; - -const callbackArgs = prop => - prop.typeAnnotation.returnTypeAnnotation.type === 'PromiseTypeAnnotation' - ? `${ - prop.typeAnnotation.params.length === 0 ? '' : '\n resolve' - }:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject` - : ''; - -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. - * - * ${'@'}generated by codegen project: GenerateModuleHObjCpp.js - */ - -#ifndef __cplusplus -#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. -#endif - -#import - -#import - -#import - -#import -#import -#import - -#import -#import -#import - -#import - -::_PROTOCOLS_:: - -namespace facebook { - namespace react { -::_MODULES_:: - } // 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( - param: FunctionTypeAnnotationParam, - createErrorMessage: (typeName: string) => string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -) { - const {nullable, typeAnnotation} = param; - - function wrapIntoNullableIfNeeded(generatedType: string) { - return nullable ? `${generatedType} _Nullable` : generatedType; - } - - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; - switch (realTypeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (realTypeAnnotation.name) { - case 'RootTag': - return nullable ? 'NSNumber *' : 'double'; - default: - (realTypeAnnotation.name: empty); - throw new Error(createErrorMessage(realTypeAnnotation.name)); - } - case 'StringTypeAnnotation': - return wrapIntoNullableIfNeeded('NSString *'); - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return nullable ? 'NSNumber *' : 'double'; - case 'BooleanTypeAnnotation': - return nullable ? 'NSNumber * _Nullable' : 'BOOL'; - case 'ObjectTypeAnnotation': - if (typeAnnotation.type === 'TypeAliasTypeAnnotation') { - return getNamespacedStructName(typeAnnotation.name) + ' &'; - } - return wrapIntoNullableIfNeeded('NSDictionary *'); - case 'GenericObjectTypeAnnotation': - return wrapIntoNullableIfNeeded('NSDictionary *'); - case 'ArrayTypeAnnotation': - return wrapIntoNullableIfNeeded('NSArray *'); - case 'FunctionTypeAnnotation': - return 'RCTResponseSenderBlock'; - default: - // TODO (T65847278): Figure out why this does not work. - // (type: empty); - throw new Error(createErrorMessage(realTypeAnnotation.type)); - } -} - -function translatePrimitiveJSTypeToObjCTypeForReturn( - typeAnnotation: FunctionTypeAnnotationReturn, - createErrorMessage: (typeName: string) => string, -) { - function wrapIntoNullableIfNeeded(generatedType: string) { - return typeAnnotation.nullable - ? `${generatedType} _Nullable` - : generatedType; - } - switch (typeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { - case 'RootTag': - return wrapIntoNullableIfNeeded('NSNumber *'); - default: - (typeAnnotation.name: empty); - throw new Error(createErrorMessage(typeAnnotation.name)); - } - case 'VoidTypeAnnotation': - case 'PromiseTypeAnnotation': - return 'void'; - case 'StringTypeAnnotation': - return wrapIntoNullableIfNeeded('NSString *'); - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return wrapIntoNullableIfNeeded('NSNumber *'); - case 'BooleanTypeAnnotation': - return typeAnnotation.nullable ? 'NSNumber * _Nullable' : 'BOOL'; - case 'GenericObjectTypeAnnotation': - return wrapIntoNullableIfNeeded('NSDictionary *'); - case 'ArrayTypeAnnotation': - return wrapIntoNullableIfNeeded('NSArray> *'); - case 'ObjectTypeAnnotation': - return wrapIntoNullableIfNeeded('NSDictionary *'); - default: - // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.type: empty); - throw new Error(createErrorMessage(typeAnnotation.type)); - } -} - -function handleArrayOfObjects( - objectForGeneratingStructs: Array, - propOrParam: FunctionTypeAnnotationParam, - name: string, -) { - if ( - propOrParam.typeAnnotation.type === 'ArrayTypeAnnotation' && - propOrParam.typeAnnotation.elementType - ) { - const typeAnnotation = propOrParam.typeAnnotation.elementType; - const type = typeAnnotation.type; - - if ( - type === 'ObjectTypeAnnotation' && - typeAnnotation.properties && - typeAnnotation.properties.length > 0 - ) { - objectForGeneratingStructs.push({ - name, - object: { - type: 'ObjectTypeAnnotation', - properties: typeAnnotation.properties, - }, - }); - } - } -} - -const methodImplementationTemplate = - '- (::_RETURN_VALUE_::) ::_PROPERTY_NAME_::::_ARGS_::;'; - -module.exports = { - generate( - libraryName: string, - schema: SchemaType, - moduleSpecName: string, - ): FilesOutput { - const nativeModules = Object.keys(schema.modules) - .sort() - .map(moduleName => { - const modules = schema.modules[moduleName].nativeModules; - if (modules == null) { - return null; - } - - return modules; - }) - .filter(Boolean) - .reduce((acc, components) => Object.assign(acc, components), {}); - - const modules = Object.keys(nativeModules) - .map(name => moduleTemplate.replace(/::_MODULE_NAME_::/g, name)) - .join('\n'); - - const protocols = Object.keys(nativeModules) - .sort() - .map(name => { - const objectForGeneratingStructs: Array = []; - const {aliases, properties} = nativeModules[name]; - const implementations = properties - .map(prop => { - const nativeArgs = prop.typeAnnotation.params - .map((param, i) => { - let paramObjCType; - if ( - param.typeAnnotation.type === 'ObjectTypeAnnotation' && - param.typeAnnotation.properties - ) { - const variableName = - capitalizeFirstLetter(prop.name) + - capitalizeFirstLetter(param.name); - const structName = 'Spec' + variableName; - objectForGeneratingStructs.push({ - name: structName, - object: { - type: 'ObjectTypeAnnotation', - properties: param.typeAnnotation.properties, - }, - }); - paramObjCType = getNamespacedStructName(structName) + ' &'; - - param.typeAnnotation.properties.map(aProp => { - return handleArrayOfObjects( - objectForGeneratingStructs, - aProp, - 'Spec' + - capitalizeFirstLetter(prop.name) + - capitalizeFirstLetter(param.name) + - capitalizeFirstLetter(aProp.name) + - 'Element', - ); - }); - } else if ( - param.typeAnnotation.type === 'TypeAliasTypeAnnotation' - ) { - const typeAnnotation = getTypeAliasTypeAnnotation( - param.typeAnnotation.name, - aliases, - ); - if (typeAnnotation.type === 'ObjectTypeAnnotation') { - paramObjCType = - getNamespacedStructName(param.typeAnnotation.name) + ' &'; - } else { - throw Error( - `Unsupported type for "${param.typeAnnotation.name}". Found: ${typeAnnotation.type}`, - ); - } - } else { - paramObjCType = translatePrimitiveJSTypeToObjCType( - param, - typeName => - `Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`, - aliases, - ); - - handleArrayOfObjects( - objectForGeneratingStructs, - param, - 'Spec' + - capitalizeFirstLetter(prop.name) + - capitalizeFirstLetter(param.name) + - 'Element', - ); - } - return `${i === 0 ? '' : param.name}:(${paramObjCType})${ - param.name - }`; - }) - .join('\n ') - .concat(callbackArgs(prop)); - const {returnTypeAnnotation} = prop.typeAnnotation; - if ( - returnTypeAnnotation.type === 'ObjectTypeAnnotation' && - returnTypeAnnotation.properties - ) { - objectForGeneratingStructs.push({ - name: 'Spec' + capitalizeFirstLetter(prop.name) + 'ReturnType', - object: { - type: 'ObjectTypeAnnotation', - properties: returnTypeAnnotation.properties, - }, - }); - } - const implementation = methodImplementationTemplate - .replace('::_PROPERTY_NAME_::', prop.name) - .replace( - '::_RETURN_VALUE_::', - translatePrimitiveJSTypeToObjCTypeForReturn( - returnTypeAnnotation, - typeName => - `Unsupported return type for ${prop.name}. Found: ${typeName}`, - ), - ) - .replace('::_ARGS_::', nativeArgs); - if (prop.name === 'getConstants') { - if ( - prop.typeAnnotation.returnTypeAnnotation.properties && - prop.typeAnnotation.returnTypeAnnotation.properties.length === 0 - ) { - return ''; - } - return constants.replace(/::_MODULE_NAME_::/, name); - } - return implementation; - }) - .join('\n'); - - Object.keys(aliases) - .reverse() - .map((aliasName, i) => { - const alias = aliases[aliasName]; - - let paramObjCType = ''; - - switch (alias.type) { - case 'ObjectTypeAnnotation': - if (alias.properties) { - objectForGeneratingStructs.push({ - name: aliasName, - object: { - type: 'ObjectTypeAnnotation', - properties: alias.properties, - }, - }); - paramObjCType = getNamespacedStructName(alias.name) + ' &'; - } - break; - default: - throw Error( - `Unsupported type for "${aliasName}". Found: ${alias.type}`, - ); - } - return `${i === 0 ? '' : aliasName}:(${paramObjCType})${aliasName}`; - }) - .join('\n'); - - return protocolTemplate - .replace( - /::_STRUCTS_::/g, - translateObjectsForStructs( - objectForGeneratingStructs, - name, - aliases, - ), - ) - .replace(/::_MODULE_PROPERTIES_::/g, implementations) - .replace(/::_MODULE_NAME_::/g, name) - .replace('::_PROPERTIES_MAP_::', ''); - }) - .join('\n'); - - const fileName = `${moduleSpecName}.h`; - const replacedTemplate = template - .replace(/::_MODULES_::/g, modules) - .replace(/::_PROTOCOLS_::/g, protocols); - - return new Map([[fileName, replacedTemplate]]); - }, -}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js deleted file mode 100644 index 53a0585886e..00000000000 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js +++ /dev/null @@ -1,320 +0,0 @@ -/** - * 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 strict - * @format - */ - -'use strict'; - -import type {SchemaType, NativeModuleShape} from '../../CodegenSchema'; - -const {capitalizeFirstLetter} = require('./ObjCppUtils/GenerateStructs'); -const {flatObjects} = require('./ObjCppUtils/Utils'); -const {getTypeAliasTypeAnnotation} = require('./Utils'); - -type FilesOutput = Map; - -const propertyHeaderTemplate = - ' static facebook::jsi::Value __hostFunction_Native::_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {'; - -const propertyCastTemplate = `static_cast(turboModule) - .invokeObjCMethod(rt, ::_KIND_::, "::_PROPERTY_NAME_::", @selector(::_PROPERTY_NAME_::::_ARGS_::), args, count);`; - -const propertyTemplate = ` -${propertyHeaderTemplate} - return ${propertyCastTemplate} - }`; - -const propertyDefTemplate = - ' methodMap_["::_PROPERTY_NAME_::"] = MethodMetadata {::_ARGS_COUNT_::, __hostFunction_Native::_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::};'; - -const moduleTemplate = ` - ::_TURBOMODULE_METHOD_INVOKERS_:: - - Native::_MODULE_NAME_::SpecJSI::Native::_MODULE_NAME_::SpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - ::_PROPERTIES_MAP_::::_CONVERSION_SELECTORS_:: - }`.trim(); - -const getterTemplate = ` -@implementation RCTCxxConvert (Native::_MODULE_NAME_::_::_GETTER_NAME_::) -+ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_::_GETTER_NAME_:::(id)json -{ - return facebook::react::managedPointer(json); -} -@end -`; - -const argConvertionTemplate = - '\n setMethodArgConversionSelector(@"::_ARG_NAME_::", ::_ARG_NUMBER_::, @"JS_Native::_MODULE_NAME_::_::_SELECTOR_NAME_:::");'; - -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. - * - * ${'@'}generated by codegen project: GenerateModuleMm.js - */ - -#include <::_INCLUDE_::> -#import - -::_GETTERS_:: -namespace facebook { - namespace react { -::_MODULES_:: - } // namespace react -} // namespace facebook -`; - -function translateReturnTypeToKind(typeAnnotation): string { - switch (typeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (typeAnnotation.name) { - case 'RootTag': - return 'NumberKind'; - default: - (typeAnnotation.name: empty); - throw new Error( - `Invalid ReservedFunctionValueTypeName name, got ${typeAnnotation.name}`, - ); - } - case 'VoidTypeAnnotation': - return 'VoidKind'; - case 'StringTypeAnnotation': - return 'StringKind'; - case 'BooleanTypeAnnotation': - return 'BooleanKind'; - case 'NumberTypeAnnotation': - case 'DoubleTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return 'NumberKind'; - case 'PromiseTypeAnnotation': - return 'PromiseKind'; - case 'GenericObjectTypeAnnotation': - case 'ObjectTypeAnnotation': - return 'ObjectKind'; - case 'ArrayTypeAnnotation': - return 'ArrayKind'; - default: - // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.type: empty); - throw new Error( - `Unknown prop type for returning value, found: ${typeAnnotation.type}"`, - ); - } -} - -function translateMethodForImplementation(property): string { - const {returnTypeAnnotation} = property.typeAnnotation; - - const numberOfParams = - property.typeAnnotation.params.length + - (returnTypeAnnotation.type === 'PromiseTypeAnnotation' ? 2 : 0); - const translatedArguments = property.typeAnnotation.params - .map(param => param.name) - .concat( - returnTypeAnnotation.type === 'PromiseTypeAnnotation' - ? ['resolve', 'reject'] - : [], - ) - .slice(1) - .join(':') - .concat(':'); - if ( - property.name === 'getConstants' && - returnTypeAnnotation.type === 'ObjectTypeAnnotation' && - returnTypeAnnotation.properties && - returnTypeAnnotation.properties.length === 0 - ) { - return ''; - } - return propertyTemplate - .replace(/::_KIND_::/g, translateReturnTypeToKind(returnTypeAnnotation)) - .replace(/::_PROPERTY_NAME_::/g, property.name) - .replace( - /::_ARGS_::/g, - numberOfParams === 0 - ? '' - : (numberOfParams === 1 ? '' : ':') + translatedArguments, - ); -} - -module.exports = { - generate( - libraryName: string, - schema: SchemaType, - moduleSpecName: string, - ): FilesOutput { - const nativeModules: {[name: string]: NativeModuleShape, ...} = Object.keys( - schema.modules, - ) - .map(moduleName => { - const modules = schema.modules[moduleName].nativeModules; - if (modules == null) { - return null; - } - - return modules; - }) - .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: - 'Spec' + - 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: - 'Spec' + - capitalizeFirstLetter(property.name) + - capitalizeFirstLetter(param.name), - object: { - type: 'ObjectTypeAnnotation', - properties: properties, - }, - }; - } - } - }) - .filter(Boolean), - ); - } - return moduleAcc; - }, []) - .concat( - Object.keys(module.aliases).map(aliasName => { - const alias = getTypeAliasTypeAnnotation( - aliasName, - module.aliases, - ); - return { - name: aliasName, - object: {type: alias.type, properties: alias.properties}, - }; - }), - ), - false, - module.aliases, - ) - .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 {aliases, properties} = nativeModules[name]; - const translatedMethods = properties - .map(property => translateMethodForImplementation(property)) - .join('\n'); - return moduleTemplate - .replace(/::_TURBOMODULE_METHOD_INVOKERS_::/g, translatedMethods) - .replace( - '::_PROPERTIES_MAP_::', - properties - .map( - ({ - name: propertyName, - typeAnnotation: {params, returnTypeAnnotation}, - }) => - propertyName === 'getConstants' && - returnTypeAnnotation.type === 'ObjectTypeAnnotation' && - returnTypeAnnotation.properties && - returnTypeAnnotation.properties.length === 0 - ? '' - : propertyDefTemplate - .replace(/::_PROPERTY_NAME_::/g, propertyName) - .replace(/::_ARGS_COUNT_::/g, params.length.toString()), - ) - .join('\n'), - ) - .replace( - '::_CONVERSION_SELECTORS_::', - properties - .map(({name: propertyName, typeAnnotation: {params}}) => - params - .map((param, index) => { - const typeAnnotation = - param.typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation( - param.typeAnnotation.name, - aliases, - ) - : param.typeAnnotation; - const selectorName = - param.typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? param.typeAnnotation.name - : 'Spec' + - capitalizeFirstLetter(propertyName) + - capitalizeFirstLetter(param.name); - - if ( - typeAnnotation.type === 'ObjectTypeAnnotation' && - typeAnnotation.properties - ) { - return argConvertionTemplate - .replace('::_SELECTOR_NAME_::', selectorName) - .replace('::_ARG_NUMBER_::', index.toString()) - .replace('::_ARG_NAME_::', propertyName); - } - - return ''; - }) - .join(''), - ) - .join(''), - ) - .replace(/::_MODULE_NAME_::/g, name); - }) - .join('\n'); - - const fileName = `${moduleSpecName}-generated.mm`; - const replacedTemplate = template - .replace(/::_GETTERS_::/g, gettersImplementations) - .replace(/::_MODULES_::/g, modules) - .replace(/::_LIBRARY_NAME_::/g, libraryName) - .replace(/::_INCLUDE_::/g, `${moduleSpecName}/${moduleSpecName}.h`); - return new Map([[fileName, replacedTemplate]]); - }, -}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js new file mode 100644 index 00000000000..71855f15f4f --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/StructCollector.js @@ -0,0 +1,191 @@ +/** + * 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 strict + * @format + */ + +'use strict'; + +import type { + Required, + NativeModuleObjectTypeAnnotation, + NativeModuleStringTypeAnnotation, + NativeModuleNumberTypeAnnotation, + NativeModuleInt32TypeAnnotation, + NativeModuleDoubleTypeAnnotation, + NativeModuleFloatTypeAnnotation, + NativeModuleBooleanTypeAnnotation, + NativeModuleGenericObjectTypeAnnotation, + NativeModuleReservedFunctionValueTypeAnnotation, + NativeModuleTypeAliasTypeAnnotation, + NativeModuleArrayTypeAnnotation, + NativeModuleBaseTypeAnnotation, +} from '../../../CodegenSchema'; + +import type {AliasResolver} from '../Utils'; + +const {capitalize} = require('./Utils'); + +type StructContext = 'CONSTANTS' | 'REGULAR'; + +export type RegularStruct = $ReadOnly<{| + context: 'REGULAR', + name: string, + properties: $ReadOnlyArray, +|}>; + +export type ConstantsStruct = $ReadOnly<{| + context: 'CONSTANTS', + name: string, + properties: $ReadOnlyArray, +|}>; + +export type Struct = RegularStruct | ConstantsStruct; + +export type StructProperty = $ReadOnly<{| + name: string, + optional: boolean, + typeAnnotation: StructTypeAnnotation, +|}>; + +export type StructTypeAnnotation = + | NativeModuleStringTypeAnnotation + | NativeModuleNumberTypeAnnotation + | NativeModuleInt32TypeAnnotation + | NativeModuleDoubleTypeAnnotation + | NativeModuleFloatTypeAnnotation + | NativeModuleBooleanTypeAnnotation + | NativeModuleGenericObjectTypeAnnotation + | NativeModuleReservedFunctionValueTypeAnnotation + | NativeModuleTypeAliasTypeAnnotation + | NativeModuleArrayTypeAnnotation; + +class StructCollector { + _structs: Map = new Map(); + + process( + structName: string, + structContext: StructContext, + resolveAlias: AliasResolver, + typeAnnotation: NativeModuleBaseTypeAnnotation, + ): StructTypeAnnotation { + switch (typeAnnotation.type) { + case 'ObjectTypeAnnotation': { + this._insertStruct(structName, structContext, resolveAlias, { + ...typeAnnotation, + // The nullability status of this struct is recorded in the type-alias we create for it below. + nullable: false, + }); + return { + type: 'TypeAliasTypeAnnotation', + name: structName, + nullable: typeAnnotation.nullable, + }; + } + case 'ArrayTypeAnnotation': { + if (typeAnnotation.elementType == null) { + return { + type: 'ArrayTypeAnnotation', + nullable: typeAnnotation.nullable, + }; + } + + return { + type: 'ArrayTypeAnnotation', + nullable: typeAnnotation.nullable, + elementType: this.process( + structName + 'Element', + structContext, + resolveAlias, + typeAnnotation.elementType, + ), + }; + } + case 'TypeAliasTypeAnnotation': { + this._insertAlias(typeAnnotation.name, structContext, resolveAlias); + return typeAnnotation; + } + default: { + return typeAnnotation; + } + } + } + + _insertAlias( + aliasName: string, + structContext: StructContext, + resolveAlias: AliasResolver, + ): void { + const usedStruct = this._structs.get(aliasName); + if (usedStruct == null) { + this._insertStruct( + aliasName, + structContext, + resolveAlias, + resolveAlias(aliasName), + ); + } else if (usedStruct.context !== structContext) { + throw new Error( + `Tried to use alias '${aliasName}' in a getConstants() return type and inside a regular struct.`, + ); + } + } + + _insertStruct( + structName: string, + structContext: StructContext, + resolveAlias: AliasResolver, + objectTypeAnnotation: Required, + ): void { + const properties = objectTypeAnnotation.properties.map(property => { + const {typeAnnotation: propertyTypeAnnotation} = property; + const propertyStructName = structName + capitalize(property.name); + + return { + ...property, + typeAnnotation: this.process( + propertyStructName, + structContext, + resolveAlias, + propertyTypeAnnotation, + ), + }; + }); + + switch (structContext) { + case 'REGULAR': + this._structs.set(structName, { + name: structName, + context: 'REGULAR', + properties: properties, + }); + break; + case 'CONSTANTS': + this._structs.set(structName, { + name: structName, + context: 'CONSTANTS', + properties: properties, + }); + break; + default: + (structContext: empty); + throw new Error(`Detected an invalid struct context: ${structContext}`); + } + } + + getAllStructs(): $ReadOnlyArray { + return [...this._structs.values()]; + } + + getStruct(name: string): ?Struct { + return this._structs.get(name); + } +} + +module.exports = { + StructCollector, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/Utils.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/Utils.js new file mode 100644 index 00000000000..0b989b12e03 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/Utils.js @@ -0,0 +1,36 @@ +/** + * 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 strict + * @format + */ + +'use strict'; + +import type {StructProperty} from './StructCollector'; + +function capitalize(string: string): string { + return string.charAt(0).toUpperCase() + string.slice(1); +} +function getSafePropertyName(property: StructProperty): string { + if (property.name === 'id') { + return `${property.name}_`; + } + return property.name; +} + +function getNamespacedStructName( + moduleName: string, + structName: string, +): string { + return `JS::Native${moduleName}::${structName}`; +} + +module.exports = { + capitalize, + getSafePropertyName, + getNamespacedStructName, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js new file mode 100644 index 00000000000..27a71f43a32 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js @@ -0,0 +1,263 @@ +/** + * 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 strict + * @format + */ + +'use strict'; + +const { + capitalize, + getSafePropertyName, + getNamespacedStructName, +} = require('../Utils'); + +import type {StructTypeAnnotation, ConstantsStruct} from '../StructCollector'; +import type {StructSerilizationOutput} from './serializeStruct'; + +const StructTemplate = ({ + moduleName, + structName, + builderInputProps, +}: $ReadOnly<{| + moduleName: string, + structName: string, + builderInputProps: string, +|}>) => ` +namespace JS { + namespace Native${moduleName} { + struct ${structName} { + + struct Builder { + struct Input { + ${builderInputProps} + }; + + /** Initialize with a set of values */ + Builder(const Input i); + /** Initialize with an existing ${structName} */ + Builder(${structName} i); + /** Builds the object. Generally used only by the infrastructure. */ + NSDictionary *buildUnsafeRawValue() const { return _factory(); }; + private: + NSDictionary *(^_factory)(void); + }; + + static ${structName} fromUnsafeRawValue(NSDictionary *const v) { return {v}; } + NSDictionary *unsafeRawValue() const { return _v; } + private: + ${structName}(NSDictionary *const v) : _v(v) {} + NSDictionary *_v; + }; + } +}`; + +const MethodTemplate = ({ + moduleName, + structName, + properties, +}: $ReadOnly<{| + moduleName: string, + structName: string, + properties: string, +|}>) => ` +inline JS::Native${moduleName}::${structName}::Builder::Builder(const Input i) : _factory(^{ + NSMutableDictionary *d = [NSMutableDictionary new]; +${properties} + return d; +}) {} +inline JS::Native${moduleName}::${structName}::Builder::Builder(${structName} i) : _factory(^{ + return i.unsafeRawValue(); +}) {}`; + +function toObjCType( + moduleName: string, + typeAnnotation: StructTypeAnnotation, + isOptional: boolean = false, +): string { + const isRequired = !typeAnnotation.nullable && !isOptional; + const wrapFollyOptional = (type: string) => { + return isRequired ? type : `folly::Optional<${type}>`; + }; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return wrapFollyOptional('double'); + default: + (typeAnnotation.name: empty); + throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); + } + case 'StringTypeAnnotation': + return 'NSString *'; + case 'NumberTypeAnnotation': + return wrapFollyOptional('double'); + case 'FloatTypeAnnotation': + return wrapFollyOptional('double'); + case 'Int32TypeAnnotation': + return wrapFollyOptional('double'); + case 'DoubleTypeAnnotation': + return wrapFollyOptional('double'); + case 'BooleanTypeAnnotation': + return wrapFollyOptional('bool'); + case 'GenericObjectTypeAnnotation': + return isRequired ? 'id ' : 'id _Nullable '; + case 'ArrayTypeAnnotation': + if (typeAnnotation.elementType == null) { + return isRequired ? 'id ' : 'id _Nullable '; + } + + return wrapFollyOptional( + `std::vector<${toObjCType(moduleName, typeAnnotation.elementType)}>`, + ); + case 'TypeAliasTypeAnnotation': + const structName = capitalize(typeAnnotation.name); + const namespacedStructName = getNamespacedStructName( + moduleName, + structName, + ); + return wrapFollyOptional(`${namespacedStructName}::Builder`); + default: + (typeAnnotation.type: empty); + throw new Error( + `Couldn't convert into ObjC type: ${typeAnnotation.type}"`, + ); + } +} + +function toObjCValue( + moduleName: string, + typeAnnotation: StructTypeAnnotation, + value: string, + depth: number, + isOptional: boolean = false, +): string { + const isRequired = !isOptional && !typeAnnotation.nullable; + + function wrapPrimitive(type: string) { + return !isRequired + ? `${value}.hasValue() ? @((${type})${value}.value()) : nil` + : `@(${value})`; + } + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return wrapPrimitive('double'); + default: + (typeAnnotation.name: empty); + throw new Error( + `Couldn't convert into ObjC type: ${typeAnnotation.type}"`, + ); + } + case 'StringTypeAnnotation': + return value; + case 'NumberTypeAnnotation': + return wrapPrimitive('double'); + case 'FloatTypeAnnotation': + return wrapPrimitive('double'); + case 'Int32TypeAnnotation': + return wrapPrimitive('double'); + case 'DoubleTypeAnnotation': + return wrapPrimitive('double'); + case 'BooleanTypeAnnotation': + return wrapPrimitive('BOOL'); + case 'GenericObjectTypeAnnotation': + return value; + case 'ArrayTypeAnnotation': + const {elementType} = typeAnnotation; + if (elementType == null) { + return value; + } + + const localVarName = `el${'_'.repeat(depth + 1)}`; + const elementObjCType = toObjCType(moduleName, elementType); + const elementObjCValue = toObjCValue( + moduleName, + elementType, + localVarName, + depth + 1, + ); + + const RCTConvertVecToArray = transformer => { + return `RCTConvert${ + !isRequired ? 'Optional' : '' + }VecToArray(${value}, ${transformer})`; + }; + + return RCTConvertVecToArray( + `^id(${elementObjCType} ${localVarName}) { return ${elementObjCValue}; }`, + ); + case 'TypeAliasTypeAnnotation': + return !isRequired + ? `${value}.hasValue() ? ${value}.value().buildUnsafeRawValue() : nil` + : `${value}.buildUnsafeRawValue()`; + default: + (typeAnnotation.type: empty); + throw new Error( + `Couldn't convert into ObjC value: ${typeAnnotation.type}"`, + ); + } +} + +function serializeConstantsStruct( + moduleName: string, + struct: ConstantsStruct, +): StructSerilizationOutput { + const declaration = StructTemplate({ + moduleName, + structName: struct.name, + builderInputProps: struct.properties + .map(property => { + const {typeAnnotation, optional} = property; + const propName = getSafePropertyName(property); + const objCType = toObjCType(moduleName, typeAnnotation, optional); + + if (!optional) { + return `RCTRequired<${objCType}> ${propName};`; + } + + const space = ' '.repeat(objCType.endsWith('*') ? 0 : 1); + return `${objCType}${space}${propName};`; + }) + .join('\n '), + }); + + const methods = MethodTemplate({ + moduleName, + structName: struct.name, + properties: struct.properties + .map(property => { + const {typeAnnotation, optional} = property; + const propName = getSafePropertyName(property); + const objCValue = toObjCValue( + moduleName, + typeAnnotation, + propName, + 0, + optional, + ); + + let varDecl = `auto ${propName} = i.${propName}`; + if (!optional) { + varDecl += '.get()'; + } + + const assignment = `d[@"${propName}"] = ` + objCValue; + return ` ${varDecl};\n ${assignment};`; + }) + .join('\n'), + }); + + return {declaration, methods}; +} + +module.exports = { + serializeConstantsStruct, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js new file mode 100644 index 00000000000..ce7b5f12d4f --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeRegularStruct.js @@ -0,0 +1,251 @@ +/** + * 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 strict + * @format + */ + +'use strict'; + +const { + capitalize, + getSafePropertyName, + getNamespacedStructName, +} = require('../Utils'); + +import type {StructTypeAnnotation, RegularStruct} from '../StructCollector'; +import type {StructSerilizationOutput} from './serializeStruct'; + +const StructTemplate = ({ + moduleName, + structName, + structProperties, +}: $ReadOnly<{| + moduleName: string, + structName: string, + structProperties: string, +|}>) => ` +namespace JS { + namespace Native${moduleName} { + struct ${structName} { + ${structProperties} + + ${structName}(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (Native${moduleName}_${structName}) ++ (RCTManagedPointer *)JS_Native${moduleName}_${structName}:(id)json; +@end +`; + +const MethodTemplate = ({ + returnType, + returnValue, + moduleName, + structName, + propertyName, +}: $ReadOnly<{| + returnType: string, + returnValue: string, + moduleName: string, + structName: string, + propertyName: string, +|}>) => ` +inline ${returnType}JS::Native${moduleName}::${structName}::${propertyName}() const +{ + id const p = _v[@"${propertyName}"]; + return ${returnValue}; +} +`; + +function toObjCType( + moduleName: string, + typeAnnotation: StructTypeAnnotation, + isOptional: boolean = false, +): string { + const isRequired = !typeAnnotation.nullable && !isOptional; + const wrapFollyOptional = (type: string) => { + return isRequired ? type : `folly::Optional<${type}>`; + }; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return wrapFollyOptional('double'); + default: + (typeAnnotation.name: empty); + throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); + } + case 'StringTypeAnnotation': + return 'NSString *'; + case 'NumberTypeAnnotation': + return wrapFollyOptional('double'); + case 'FloatTypeAnnotation': + return wrapFollyOptional('double'); + case 'Int32TypeAnnotation': + return wrapFollyOptional('double'); + case 'DoubleTypeAnnotation': + return wrapFollyOptional('double'); + case 'BooleanTypeAnnotation': + return wrapFollyOptional('bool'); + case 'GenericObjectTypeAnnotation': + return isRequired ? 'id ' : 'id _Nullable'; + case 'ArrayTypeAnnotation': + if (typeAnnotation.elementType == null) { + return isRequired ? 'id ' : 'id _Nullable'; + } + return wrapFollyOptional( + `facebook::react::LazyVector<${toObjCType( + moduleName, + typeAnnotation.elementType, + )}>`, + ); + case 'TypeAliasTypeAnnotation': + const structName = capitalize(typeAnnotation.name); + const namespacedStructName = getNamespacedStructName( + moduleName, + structName, + ); + return wrapFollyOptional(namespacedStructName); + default: + (typeAnnotation.type: empty); + throw new Error( + `Couldn't convert into ObjC type: ${typeAnnotation.type}"`, + ); + } +} + +function toObjCValue( + moduleName: string, + typeAnnotation: StructTypeAnnotation, + value: string, + depth: number, + isOptional: boolean = false, +): string { + const isRequired = !typeAnnotation.nullable && !isOptional; + const RCTBridgingTo = (type: string, arg?: string) => { + const args = [value, arg].filter(Boolean).join(', '); + return isRequired + ? `RCTBridgingTo${type}(${args})` + : `RCTBridgingToOptional${type}(${args})`; + }; + + switch (typeAnnotation.type) { + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return RCTBridgingTo('Double'); + default: + (typeAnnotation.name: empty); + throw new Error( + `Couldn't convert into ObjC type: ${typeAnnotation.type}"`, + ); + } + case 'StringTypeAnnotation': + return RCTBridgingTo('String'); + case 'NumberTypeAnnotation': + return RCTBridgingTo('Double'); + case 'FloatTypeAnnotation': + return RCTBridgingTo('Double'); + case 'Int32TypeAnnotation': + return RCTBridgingTo('Double'); + case 'DoubleTypeAnnotation': + return RCTBridgingTo('Double'); + case 'BooleanTypeAnnotation': + return RCTBridgingTo('Bool'); + case 'GenericObjectTypeAnnotation': + return value; + case 'ArrayTypeAnnotation': + const {elementType} = typeAnnotation; + if (elementType == null) { + return value; + } + + const localVarName = `itemValue_${depth}`; + const elementObjCType = toObjCType(moduleName, elementType); + const elementObjCValue = toObjCValue( + moduleName, + elementType, + localVarName, + depth + 1, + ); + + return RCTBridgingTo( + 'Vec', + `^${elementObjCType}(id ${localVarName}) { return ${elementObjCValue}; }`, + ); + case 'TypeAliasTypeAnnotation': + const structName = capitalize(typeAnnotation.name); + const namespacedStructName = getNamespacedStructName( + moduleName, + structName, + ); + + return !isRequired + ? `(p == nil ? folly::none : folly::make_optional(${namespacedStructName}(p)))` + : `${namespacedStructName}(p)`; + default: + (typeAnnotation.type: empty); + throw new Error( + `Couldn't convert into ObjC value: ${typeAnnotation.type}"`, + ); + } +} + +function serializeRegularStruct( + moduleName: string, + struct: RegularStruct, +): StructSerilizationOutput { + const declaration = StructTemplate({ + moduleName: moduleName, + structName: struct.name, + structProperties: struct.properties + .map(property => { + const {typeAnnotation, optional} = property; + const propName = getSafePropertyName(property); + const returnType = toObjCType(moduleName, typeAnnotation, optional); + + const padding = ' '.repeat(returnType.endsWith('*') ? 0 : 1); + return `${returnType}${padding}${propName}() const;`; + }) + .join('\n '), + }); + + const methods = struct.properties + .map(property => { + const {typeAnnotation, optional} = property; + const propName = getSafePropertyName(property); + const returnType = toObjCType(moduleName, typeAnnotation, optional); + const returnValue = toObjCValue( + moduleName, + typeAnnotation, + 'p', + 0, + optional, + ); + + const padding = ' '.repeat(returnType.endsWith('*') ? 0 : 1); + return MethodTemplate({ + moduleName, + structName: struct.name, + returnType: returnType + padding, + returnValue: returnValue, + propertyName: propName, + }); + }) + .join('\n'); + + return {methods, declaration}; +} + +module.exports = { + serializeRegularStruct, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js new file mode 100644 index 00000000000..fe2355333b3 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeStruct.js @@ -0,0 +1,35 @@ +/** + * 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 strict + * @format + */ + +'use strict'; + +import type {Struct} from '../StructCollector'; + +const {serializeConstantsStruct} = require('./serializeConstantsStruct'); +const {serializeRegularStruct} = require('./serializeRegularStruct'); + +export type StructSerilizationOutput = $ReadOnly<{| + methods: string, + declaration: string, +|}>; + +function serializeStruct( + moduleName: string, + struct: Struct, +): StructSerilizationOutput { + if (struct.context === 'REGULAR') { + return serializeRegularStruct(moduleName, struct); + } + return serializeConstantsStruct(moduleName, struct); +} + +module.exports = { + serializeStruct, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js new file mode 100644 index 00000000000..0f1852415b2 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/index.js @@ -0,0 +1,210 @@ +/** + * 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 strict + * @format + */ + +'use strict'; + +import type {SchemaType} from '../../../CodegenSchema'; +import type {MethodSerializationOutput} from './serializeMethod'; + +const {createAliasResolver, getModules} = require('../Utils'); + +const {StructCollector} = require('./StructCollector'); +const {serializeStruct} = require('./header/serializeStruct'); +const {serializeMethod} = require('./serializeMethod'); +const {serializeModuleSource} = require('./source/serializeModule'); + +type FilesOutput = Map; + +const ModuleDeclarationTemplate = ({ + moduleName, + structDeclarations, + protocolMethods, +}: $ReadOnly<{| + moduleName: string, + structDeclarations: string, + protocolMethods: string, +|}>) => ` +${structDeclarations} +@protocol Native${moduleName}Spec + +${protocolMethods} + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module '${moduleName}' + */ + class JSI_EXPORT Native${moduleName}SpecJSI : public ObjCTurboModule { + public: + Native${moduleName}SpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook +`; + +const HeaderFileTemplate = ({ + moduleDeclarations, + structInlineMethods, +}: $ReadOnly<{| + moduleDeclarations: string, + structInlineMethods: string, +|}>) => ` +/** + * ${'C'}opyright (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. + * + * ${'@'}generated by codegen project: GenerateModuleHObjCpp.js + */ + +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif + +#import + +#import + +#import + +#import +#import +#import + +#import +#import +#import + +#import + +${moduleDeclarations} + +${structInlineMethods} +`; + +const SourceFileTemplate = ({ + headerFileName, + moduleImplementations, +}: $ReadOnly<{| + headerFileName: string, + moduleImplementations: string, +|}>) => ` +/** + * ${'C'}opyright (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. + * + * ${'@'}generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. + */ + +#import "${headerFileName}" + +${moduleImplementations} +`; + +module.exports = { + generate( + libraryName: string, + schema: SchemaType, + moduleSpecName: string, + ): FilesOutput { + const nativeModules = getModules(schema); + + const moduleDeclarations: Array = []; + const structInlineMethods: Array = []; + const moduleImplementations: Array = []; + + const moduleNames: Array = Object.keys(nativeModules).sort(); + for (const moduleName of moduleNames) { + const {aliases, properties} = nativeModules[moduleName]; + const resolveAlias = createAliasResolver(aliases); + const structCollector = new StructCollector(); + + const methodSerializations: Array = []; + const serializeProperty = property => { + methodSerializations.push( + ...serializeMethod( + moduleName, + property, + structCollector, + resolveAlias, + ), + ); + }; + + /** + * Note: As we serialize NativeModule methods, we insert structs into + * StructCollector, as we encounter them. + */ + properties + .filter(property => property.name !== 'getConstants') + .forEach(serializeProperty); + properties + .filter(property => property.name === 'getConstants') + .forEach(serializeProperty); + + const generatedStructs = structCollector.getAllStructs(); + const structStrs = []; + const methodStrs = []; + + for (const struct of generatedStructs) { + const {methods, declaration} = serializeStruct(moduleName, struct); + structStrs.push(declaration); + methodStrs.push(methods); + } + + moduleDeclarations.push( + ModuleDeclarationTemplate({ + moduleName: moduleName, + structDeclarations: structStrs.join('\n'), + protocolMethods: methodSerializations + .map(({protocolMethod}) => protocolMethod) + .join('\n'), + }), + ); + + structInlineMethods.push(methodStrs.join('\n')); + + moduleImplementations.push( + serializeModuleSource( + moduleName, + generatedStructs, + methodSerializations.filter( + ({selector}) => selector !== 'constantsToExport', + ), + ), + ); + } + + const headerFileName = `${moduleSpecName}.h`; + const headerFile = HeaderFileTemplate({ + moduleDeclarations: moduleDeclarations.join('\n'), + structInlineMethods: structInlineMethods.join('\n'), + }); + + const sourceFileName = `${moduleSpecName}-generated.mm`; + const sourceFile = SourceFileTemplate({ + headerFileName, + moduleImplementations: moduleImplementations.join('\n'), + }); + + return new Map([ + [headerFileName, headerFile], + [sourceFileName, sourceFile], + ]); + }, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js new file mode 100644 index 00000000000..6fe0c47b288 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js @@ -0,0 +1,413 @@ +/** + * 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 strict + * @format + */ + +'use strict'; + +import type { + NativeModuleMethodParamSchema, + NativeModuleReturnTypeAnnotation, + NativeModulePropertySchema, +} from '../../../CodegenSchema'; + +import type {AliasResolver} from '../Utils'; + +const invariant = require('invariant'); +const {StructCollector} = require('./StructCollector'); +const {capitalize, getNamespacedStructName} = require('./Utils'); + +const ProtocolMethodTemplate = ({ + returnObjCType, + methodName, + params, +}: $ReadOnly<{| + returnObjCType: string, + methodName: string, + params: string, +|}>) => `- (${returnObjCType})${methodName}${params};`; + +export type StructParameterRecord = $ReadOnly<{| + paramIndex: number, + structName: string, +|}>; + +type ReturnJSType = + | 'VoidKind' + | 'PromiseKind' + | 'ObjectKind' + | 'ArrayKind' + | 'NumberKind' + | 'StringKind'; + +export type MethodSerializationOutput = $ReadOnly<{| + methodName: string, + protocolMethod: string, + selector: string, + structParamRecords: $ReadOnlyArray, + returnJSType: ReturnJSType, +|}>; + +function serializeMethod( + moduleName: string, + property: NativeModulePropertySchema, + structCollector: StructCollector, + resolveAlias: AliasResolver, +): $ReadOnlyArray { + const { + name: methodName, + typeAnnotation: {params, returnTypeAnnotation}, + } = property; + + if (methodName === 'getConstants') { + return serializeConstantsProtocolMethods( + moduleName, + property, + structCollector, + resolveAlias, + ); + } + + const methodParams: Array<{|paramName: string, objCType: string|}> = []; + const structParamRecords: Array = []; + + params.forEach((param, index) => { + const structName = `Spec${capitalize(methodName)}${capitalize(param.name)}`; + const {objCType, isStruct} = getParamObjCType( + moduleName, + methodName, + param, + structName, + structCollector, + resolveAlias, + ); + + methodParams.push({paramName: param.name, objCType}); + + if (isStruct) { + structParamRecords.push({paramIndex: index, structName}); + } + }); + + if (returnTypeAnnotation.type === 'PromiseTypeAnnotation') { + methodParams.push( + {paramName: 'resolve', objCType: 'RCTPromiseResolveBlock'}, + {paramName: 'reject', objCType: 'RCTPromiseRejectBlock'}, + ); + } + + /** + * Build Protocol Method + **/ + const returnObjCType = getReturnObjCType(methodName, returnTypeAnnotation); + const paddingMax = `- (${returnObjCType})${methodName}`.length; + + const objCParams = methodParams.reduce( + ($objCParams, {objCType, paramName}, i) => { + const rhs = `(${objCType})${paramName}`; + const padding = ' '.repeat(Math.max(0, paddingMax - paramName.length)); + return i === 0 + ? `:${rhs}` + : `${$objCParams}\n${padding}${paramName}:${rhs}`; + }, + '', + ); + + const protocolMethod = ProtocolMethodTemplate({ + methodName, + returnObjCType, + params: objCParams, + }); + + /** + * Build ObjC Selector + */ + const selector = methodParams + .map(({paramName}) => paramName) + .reduce(($selector, paramName, i) => { + return i === 0 ? `${$selector}:` : `${$selector}${paramName}:`; + }, methodName); + + /** + * Build JS Return type + */ + const returnJSType = getReturnJSType(methodName, returnTypeAnnotation); + + return [ + { + methodName, + protocolMethod, + selector: `@selector(${selector})`, + structParamRecords, + returnJSType, + }, + ]; +} + +function getParamObjCType( + moduleName: string, + methodName: string, + param: NativeModuleMethodParamSchema, + structName: string, + structCollector: StructCollector, + resolveAlias: AliasResolver, +): $ReadOnly<{|objCType: string, isStruct: boolean|}> { + const {name: paramName, typeAnnotation} = param; + const notRequired = param.optional || typeAnnotation.nullable; + + function wrapIntoNullableIfNeeded(generatedType: string) { + return typeAnnotation.nullable + ? `${generatedType} _Nullable` + : generatedType; + } + + const isStruct = (objCType: string) => ({ + isStruct: true, + objCType, + }); + + const notStruct = (objCType: string) => ({ + isStruct: false, + objCType, + }); + + // Handle types that can only be in parameters + switch (typeAnnotation.type) { + case 'FunctionTypeAnnotation': { + return notStruct('RCTResponseSenderBlock'); + } + case 'ArrayTypeAnnotation': { + /** + * Array in params always codegen NSArray * + * + * TODO(T73933406): Support codegen for Arrays of structs and primitives + * + * For example: + * Array => NSArray + * type Animal = {||}; + * Array => NSArray, etc. + */ + return notStruct(wrapIntoNullableIfNeeded('NSArray *')); + } + } + + const structTypeAnnotation = structCollector.process( + structName, + 'REGULAR', + resolveAlias, + typeAnnotation, + ); + + invariant( + structTypeAnnotation.type !== 'ArrayTypeAnnotation', + 'ArrayTypeAnnotations should have been processed earlier', + ); + + switch (structTypeAnnotation.type) { + case 'TypeAliasTypeAnnotation': { + /** + * TODO(T73943261): Support nullable object literals and aliases? + */ + return isStruct( + getNamespacedStructName(moduleName, structTypeAnnotation.name) + ' &', + ); + } + case 'ReservedFunctionValueTypeAnnotation': + switch (structTypeAnnotation.name) { + case 'RootTag': + return notStruct(notRequired ? 'NSNumber *' : 'double'); + default: + (structTypeAnnotation.name: empty); + throw new Error( + `Unsupported type for param "${paramName}" in ${methodName}. Found: ${structTypeAnnotation.type}`, + ); + } + case 'StringTypeAnnotation': + return notStruct(wrapIntoNullableIfNeeded('NSString *')); + case 'NumberTypeAnnotation': + return notStruct(notRequired ? 'NSNumber *' : 'double'); + case 'FloatTypeAnnotation': + return notStruct(notRequired ? 'NSNumber *' : 'double'); + case 'DoubleTypeAnnotation': + return notStruct(notRequired ? 'NSNumber *' : 'double'); + case 'Int32TypeAnnotation': + return notStruct(notRequired ? 'NSNumber *' : 'double'); + case 'BooleanTypeAnnotation': + return notStruct(notRequired ? 'NSNumber *' : 'BOOL'); + case 'GenericObjectTypeAnnotation': + return notStruct(wrapIntoNullableIfNeeded('NSDictionary *')); + default: + (structTypeAnnotation.type: empty); + throw new Error( + `Unsupported type for param "${paramName}" in ${methodName}. Found: ${typeAnnotation.type}`, + ); + } +} + +function getReturnObjCType( + methodName: string, + typeAnnotation: NativeModuleReturnTypeAnnotation, +) { + function wrapIntoNullableIfNeeded(generatedType: string) { + return typeAnnotation.nullable + ? `${generatedType} _Nullable` + : generatedType; + } + + switch (typeAnnotation.type) { + case 'VoidTypeAnnotation': + return 'void'; + case 'PromiseTypeAnnotation': + return 'void'; + case 'ObjectTypeAnnotation': + return wrapIntoNullableIfNeeded('NSDictionary *'); + case 'TypeAliasTypeAnnotation': + return wrapIntoNullableIfNeeded('NSDictionary *'); + case 'ArrayTypeAnnotation': + if (typeAnnotation.elementType == null) { + return wrapIntoNullableIfNeeded('NSArray> *'); + } + + return wrapIntoNullableIfNeeded( + `NSArray<${getReturnObjCType( + methodName, + typeAnnotation.elementType, + )}> *`, + ); + case 'ReservedFunctionValueTypeAnnotation': + switch (typeAnnotation.name) { + case 'RootTag': + return wrapIntoNullableIfNeeded('NSNumber *'); + default: + (typeAnnotation.name: empty); + throw new Error( + `Unsupported return type for ${methodName}. Found: ${typeAnnotation.name}`, + ); + } + case 'StringTypeAnnotation': + // TODO: Can NSString * returns not be _Nullable? + // In the legacy codegen, we don't surround NSSTring * with _Nullable + return wrapIntoNullableIfNeeded('NSString *'); + case 'NumberTypeAnnotation': + return wrapIntoNullableIfNeeded('NSNumber *'); + case 'FloatTypeAnnotation': + return wrapIntoNullableIfNeeded('NSNumber *'); + case 'DoubleTypeAnnotation': + return wrapIntoNullableIfNeeded('NSNumber *'); + case 'Int32TypeAnnotation': + return wrapIntoNullableIfNeeded('NSNumber *'); + case 'BooleanTypeAnnotation': + return wrapIntoNullableIfNeeded('NSNumber *'); + case 'GenericObjectTypeAnnotation': + return wrapIntoNullableIfNeeded('NSDictionary *'); + default: + (typeAnnotation.type: empty); + throw new Error( + `Unsupported return type for ${methodName}. Found: ${typeAnnotation.type}`, + ); + } +} + +function getReturnJSType( + methodName: string, + typeAnnotation: NativeModuleReturnTypeAnnotation, +): ReturnJSType { + switch (typeAnnotation.type) { + case 'VoidTypeAnnotation': + return 'VoidKind'; + case 'PromiseTypeAnnotation': + return 'PromiseKind'; + case 'ObjectTypeAnnotation': + return 'ObjectKind'; + case 'TypeAliasTypeAnnotation': + return 'ObjectKind'; + case 'ArrayTypeAnnotation': + return 'ArrayKind'; + case 'ReservedFunctionValueTypeAnnotation': + return 'NumberKind'; + case 'StringTypeAnnotation': + return 'StringKind'; + case 'NumberTypeAnnotation': + return 'NumberKind'; + case 'FloatTypeAnnotation': + return 'NumberKind'; + case 'DoubleTypeAnnotation': + return 'NumberKind'; + case 'Int32TypeAnnotation': + return 'NumberKind'; + case 'BooleanTypeAnnotation': + return 'NumberKind'; + case 'GenericObjectTypeAnnotation': + return 'ObjectKind'; + default: + (typeAnnotation.type: empty); + throw new Error( + `Unsupported return type for ${methodName}. Found: ${typeAnnotation.type}`, + ); + } +} + +function serializeConstantsProtocolMethods( + moduleName: string, + property: NativeModulePropertySchema, + structCollector: StructCollector, + resolveAlias: AliasResolver, +): $ReadOnlyArray { + if (property.typeAnnotation.params.length !== 0) { + throw new Error( + `${moduleName}.getConstants() may only accept 0 arguments.`, + ); + } + + const {returnTypeAnnotation} = property.typeAnnotation; + if (returnTypeAnnotation.type !== 'ObjectTypeAnnotation') { + throw new Error( + `${moduleName}.getConstants() may only return an object literal: {|...|}.`, + ); + } + + if (returnTypeAnnotation.properties.length === 0) { + return []; + } + + const realTypeAnnotation = structCollector.process( + 'Constants', + 'CONSTANTS', + resolveAlias, + returnTypeAnnotation, + ); + + invariant( + realTypeAnnotation.type === 'TypeAliasTypeAnnotation', + "Unable to generate C++ struct from module's getConstants() method return type.", + ); + + const returnObjCType = `facebook::react::ModuleConstants`; + + return ['constantsToExport', 'getConstants'].map( + methodName => { + const protocolMethod = ProtocolMethodTemplate({ + methodName, + returnObjCType, + params: '', + }); + + return { + methodName: 'getConstants', + protocolMethod, + returnJSType: 'ObjectKind', + selector: 'getConstants', + structParamRecords: [], + }; + }, + ); +} + +module.exports = { + serializeMethod, +}; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js new file mode 100644 index 00000000000..82c69359a06 --- /dev/null +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/source/serializeModule.js @@ -0,0 +1,125 @@ +/** + * 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 strict + * @format + */ + +'use strict'; + +import type {Struct} from '../StructCollector'; +import type { + MethodSerializationOutput, + StructParameterRecord, +} from '../serializeMethod'; + +const ModuleTemplate = ({ + moduleName, + structs, + methodSerializationOutputs, +}: $ReadOnly<{| + moduleName: string, + structs: $ReadOnlyArray, + methodSerializationOutputs: $ReadOnlyArray, +|}>) => ` +${structs + .map(struct => + RCTCxxConvertCategoryTemplate({moduleName, structName: struct.name}), + ) + .join('\n')} +namespace facebook { + namespace react { + ${methodSerializationOutputs + .map(serializedMethodParts => + InlineHostFunctionTemplate({ + moduleName, + methodName: serializedMethodParts.methodName, + returnJSType: serializedMethodParts.returnJSType, + selector: serializedMethodParts.selector, + }), + ) + .join('\n')} + + Native${moduleName}SpecJSI::Native${moduleName}SpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + ${methodSerializationOutputs + .map(({methodName, structParamRecords}) => + MethodMapEntryTemplate({ + moduleName, + methodName, + structParamRecords, + }), + ) + .join('\n' + ' '.repeat(8))} + } + } + } // namespace react +} // namespace facebook +`; + +const RCTCxxConvertCategoryTemplate = ({ + moduleName, + structName, +}: $ReadOnly<{| + moduleName: string, + structName: string, +|}>) => ` +@implementation RCTCxxConvert (Native${moduleName}_${structName}) ++ (RCTManagedPointer *)JS_Native${moduleName}_${structName}:(id)json +{ + return facebook::react::managedPointer(json); +} +@end +`; + +const InlineHostFunctionTemplate = ({ + moduleName, + methodName, + returnJSType, + selector, +}: $ReadOnly<{| + moduleName: string, + methodName: string, + returnJSType: string, + selector: string, +|}>) => ` + static facebook::jsi::Value __hostFunction_Native${moduleName}SpecJSI::${methodName}(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ${returnJSType}, "${methodName}", ${selector}, args, count); + } +`; + +const MethodMapEntryTemplate = ({ + moduleName, + methodName, + structParamRecords, +}: $ReadOnly<{| + moduleName: string, + methodName: string, + structParamRecords: $ReadOnlyArray, +|}>) => ` + methodMap_["${methodName}"] = MethodMetadata {1, __hostFunction_Native${moduleName}SpecJSI_${methodName}}; + ${structParamRecords + .map(({paramIndex, structName}) => { + return `setMethodArgConversionSelector(@"${methodName}", ${paramIndex}, @"JS_Native${moduleName}_${structName}:");`; + }) + .join('\n' + ' '.repeat(8))} +`; + +function serializeModuleSource( + moduleName: string, + structs: $ReadOnlyArray, + methodSerializationOutputs: $ReadOnlyArray, +): string { + return ModuleTemplate({ + moduleName, + structs, + methodSerializationOutputs, + }); +} + +module.exports = { + serializeModuleSource, +}; diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js deleted file mode 100644 index c9e1d817a29..00000000000 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js +++ /dev/null @@ -1,452 +0,0 @@ -/** - * 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 strict - * @format - */ - -'use strict'; - -import type { - ObjectParamTypeAnnotation, - ObjectTypeAliasTypeShape, -} from '../../../CodegenSchema'; -const { - flatObjects, - capitalizeFirstLetter, - getSafePropertyName, -} = require('./Utils'); -const {getTypeAliasTypeAnnotation} = require('../Utils'); -const {generateStructsForConstants} = require('./GenerateStructsForConstants'); - -const template = ` -::_CONSTANTS_::::_STRUCTS_::::_INLINES_:: -`; - -const structTemplate = ` -namespace JS { - namespace Native::_MODULE_NAME_:: { - struct ::_STRUCT_NAME_:: { - ::_STRUCT_PROPERTIES_:: - - ::_STRUCT_NAME_::(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (Native::_MODULE_NAME_::_::_STRUCT_NAME_::) -+ (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_::_STRUCT_NAME_:::(id)json; -@end -`; - -const inlineTemplate = ` -inline ::_RETURN_TYPE_::JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::::_PROPERTY_NAME_::() const -{ - id const p = _v[@"::_PROPERTY_NAME_::"]; - return ::_RETURN_VALUE_::; -} -`; - -function getNamespacedStructName(structName: string): string { - return `JS::Native::_MODULE_NAME_::::${structName}`; -} - -function getElementTypeForArray( - property: ObjectParamTypeAnnotation, - name: string, - moduleName: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - const {typeAnnotation} = property; - - // TODO(T67898313): Workaround for NativeLinking's use of union type. This check may be removed once typeAnnotation is non-optional. - if (!typeAnnotation) { - throw new Error( - `Cannot get array element type, property ${property.name} does not contain a type annotation`, - ); - } - - if (typeAnnotation.type !== 'ArrayTypeAnnotation') { - throw new Error( - `Cannot get array element type for non-array type ${typeAnnotation.type}`, - ); - } - - if (!typeAnnotation.elementType) { - return 'id'; - } - - const type = - typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.elementType.name, aliases) - .type - : typeAnnotation.elementType.type; - switch (type) { - case 'StringTypeAnnotation': - return 'NSString *'; - case 'DoubleTypeAnnotation': - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return 'double'; - case 'ObjectTypeAnnotation': - const structName = - typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' - ? typeAnnotation.elementType.name - : `${property.name}Element`; - return getNamespacedStructName(structName); - case 'GenericObjectTypeAnnotation': - // TODO(T67565166): Generic objects are not type safe and should be disallowed in the schema. This case should throw an error once it is disallowed in schema. - console.error( - `Warning: Generic objects are not type safe and should be avoided whenever possible (see '${property.name}' in ${moduleName}'s ${name})`, - ); - return 'id'; - case 'BooleanTypeAnnotation': - case 'AnyObjectTypeAnnotation': - case 'AnyTypeAnnotation': - case 'ArrayTypeAnnotation': - case 'FunctionTypeAnnotation': - case 'ReservedFunctionValueTypeAnnotation': - case 'ReservedPropTypeAnnotation': - case 'StringEnumTypeAnnotation': - throw new Error(`Unsupported array element type, found: ${type}"`); - default: - (type: empty); - throw new Error(`Unknown array element type, found: ${type}"`); - } -} - -function getInlineMethodSignature( - property: ObjectParamTypeAnnotation, - name: string, - moduleName: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - const {typeAnnotation} = property; - function markOptionalTypeIfNecessary(type: string) { - if (property.optional) { - return `folly::Optional<${type}>`; - } - return type; - } - - // TODO(T67672788): Workaround for values key in NativeLinking which lacks a typeAnnotation. id is not type safe! - if (!typeAnnotation) { - console.error( - `Warning: Unsafe type found (see '${property.name}' in ${moduleName}'s ${name})`, - ); - return `id ${getSafePropertyName(property)}() const;`; - } - - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; - - const variableName = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? `${capitalizeFirstLetter(typeAnnotation.name)}` - : `${capitalizeFirstLetter(name)}${capitalizeFirstLetter( - getSafePropertyName(property), - )}`; - - switch (realTypeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (realTypeAnnotation.name) { - case 'RootTag': - return `double ${getSafePropertyName(property)}() const;`; - default: - (realTypeAnnotation.name: empty); - throw new Error( - `Unknown prop type, found: ${realTypeAnnotation.name}"`, - ); - } - case 'StringTypeAnnotation': - return `NSString *${getSafePropertyName(property)}() const;`; - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return `${markOptionalTypeIfNecessary('double')} ${getSafePropertyName( - property, - )}() const;`; - case 'BooleanTypeAnnotation': - return `${markOptionalTypeIfNecessary('bool')} ${getSafePropertyName( - property, - )}() const;`; - case 'ObjectTypeAnnotation': - return `${markOptionalTypeIfNecessary( - getNamespacedStructName(variableName), - )} ${getSafePropertyName(property)}() const;`; - case 'GenericObjectTypeAnnotation': - case 'AnyTypeAnnotation': - return `id ${ - property.optional ? '_Nullable ' : ' ' - }${getSafePropertyName(property)}() const;`; - case 'ArrayTypeAnnotation': - return `${markOptionalTypeIfNecessary( - `facebook::react::LazyVector<${getElementTypeForArray( - property, - name, - moduleName, - aliases, - )}>`, - )} ${getSafePropertyName(property)}() const;`; - case 'FunctionTypeAnnotation': - default: - throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`); - } -} - -function getInlineMethodImplementation( - property: ObjectParamTypeAnnotation, - name: string, - moduleName: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - const {typeAnnotation} = property; - function markOptionalTypeIfNecessary(type: string): string { - if (property.optional) { - return `folly::Optional<${type}> `; - } - return `${type} `; - } - function markOptionalValueIfNecessary(value: string): string { - if (property.optional) { - return `RCTBridgingToOptional${capitalizeFirstLetter(value)}`; - } - return `RCTBridgingTo${capitalizeFirstLetter(value)}`; - } - function bridgeArrayElementValueIfNecessary(element: string): string { - // TODO(T67898313): Workaround for NativeLinking's use of union type - if (!typeAnnotation) { - throw new Error( - `Cannot get array element type, property ${property.name} does not contain a type annotation`, - ); - } - - if (typeAnnotation.type !== 'ArrayTypeAnnotation') { - throw new Error( - `Cannot get array element type for non-array type ${typeAnnotation.type}`, - ); - } - - if (!typeAnnotation.elementType) { - throw new Error(`Cannot get array element type for ${name}`); - } - - const type = - typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.elementType.name, aliases) - .type - : typeAnnotation.elementType.type; - - switch (type) { - case 'StringTypeAnnotation': - return `RCTBridgingToString(${element})`; - case 'DoubleTypeAnnotation': - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return `RCTBridgingToDouble(${element})`; - case 'BooleanTypeAnnotation': - return `RCTBridgingToBool(${element})`; - case 'ObjectTypeAnnotation': - const structName = - typeAnnotation.elementType.type === 'TypeAliasTypeAnnotation' - ? `${typeAnnotation.elementType.name}(${element})` - : `${getSafePropertyName(property)}Element(${element})`; - return getNamespacedStructName(structName); - case 'GenericObjectTypeAnnotation': - return element; - case 'AnyObjectTypeAnnotation': - case 'AnyTypeAnnotation': - case 'ArrayTypeAnnotation': - case 'FunctionTypeAnnotation': - case 'ReservedFunctionValueTypeAnnotation': - case 'ReservedPropTypeAnnotation': - case 'StringEnumTypeAnnotation': - case 'TupleTypeAnnotation': - throw new Error(`Unsupported array element type, found: ${type}"`); - default: - (type: empty); - throw new Error(`Unknown array element type, found: ${type}"`); - } - } - - // TODO(T67672788): Workaround for values key in NativeLinking which lacks a typeAnnotation. id is not type safe! - if (!typeAnnotation) { - console.error( - `Warning: Unsafe type found (see '${property.name}' in ${moduleName}'s ${name})`, - ); - return inlineTemplate - .replace( - /::_RETURN_TYPE_::/, - property.optional ? 'id _Nullable ' : 'id ', - ) - .replace(/::_RETURN_VALUE_::/, 'p'); - } - - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; - - switch (realTypeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (realTypeAnnotation.name) { - case 'RootTag': - return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'double ') - .replace(/::_RETURN_VALUE_::/, 'RCTBridgingToDouble(p)'); - default: - (realTypeAnnotation.name: empty); - throw new Error( - `Unknown prop type, found: ${realTypeAnnotation.name}"`, - ); - } - case 'StringTypeAnnotation': - return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'NSString *') - .replace(/::_RETURN_VALUE_::/, 'RCTBridgingToString(p)'); - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return inlineTemplate - .replace(/::_RETURN_TYPE_::/, markOptionalTypeIfNecessary('double')) - .replace( - /::_RETURN_VALUE_::/, - `${markOptionalValueIfNecessary('double')}(p)`, - ); - case 'BooleanTypeAnnotation': - return inlineTemplate - .replace(/::_RETURN_TYPE_::/, markOptionalTypeIfNecessary('bool')) - .replace( - /::_RETURN_VALUE_::/, - `${markOptionalValueIfNecessary('bool')}(p)`, - ); - case 'GenericObjectTypeAnnotation': - case 'AnyTypeAnnotation': - return inlineTemplate - .replace( - /::_RETURN_TYPE_::/, - property.optional ? 'id _Nullable ' : 'id ', - ) - .replace(/::_RETURN_VALUE_::/, 'p'); - case 'ObjectTypeAnnotation': - const structName = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? `${capitalizeFirstLetter(typeAnnotation.name)}` - : `${name}${capitalizeFirstLetter(getSafePropertyName(property))}`; - const namespacedStructName = getNamespacedStructName(structName); - return inlineTemplate - .replace( - /::_RETURN_TYPE_::/, - markOptionalTypeIfNecessary(namespacedStructName), - ) - .replace( - /::_RETURN_VALUE_::/, - property.optional - ? `(p == nil ? folly::none : folly::make_optional(${namespacedStructName}(p)))` - : `${namespacedStructName}(p)`, - ); - case 'ArrayTypeAnnotation': - return inlineTemplate - .replace( - /::_RETURN_TYPE_::/, - markOptionalTypeIfNecessary( - `facebook::react::LazyVector<${getElementTypeForArray( - property, - name, - moduleName, - aliases, - )}>`, - ), - ) - .replace( - /::_RETURN_VALUE_::/, - `${markOptionalValueIfNecessary('vec')}(p, ^${getElementTypeForArray( - property, - name, - moduleName, - aliases, - )}(id itemValue_0) { return ${bridgeArrayElementValueIfNecessary( - 'itemValue_0', - )}; })`, - ); - case 'FunctionTypeAnnotation': - default: - throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`); - } -} - -function translateObjectsForStructs( - annotations: $ReadOnlyArray< - $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, - |}>, - >, - moduleName: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - const flattenObjects = flatObjects(annotations, false, aliases); - - const translatedInlineMethods = flattenObjects - .reduce( - (acc, object) => - acc.concat( - object.properties.map(property => - getInlineMethodImplementation( - property, - object.name, - moduleName, - aliases, - ) - .replace(/::_PROPERTY_NAME_::/g, getSafePropertyName(property)) - .replace(/::_STRUCT_NAME_::/g, object.name), - ), - ), - [], - ) - .join('\n'); - - const translatedStructs = flattenObjects - .map(object => { - return structTemplate - .replace( - /::_STRUCT_PROPERTIES_::/g, - object.properties - .map(property => - getInlineMethodSignature( - property, - object.name, - moduleName, - aliases, - ), - ) - .join('\n '), - ) - .replace(/::_STRUCT_NAME_::/g, object.name); - }) - .reverse() - .join('\n'); - const translatedConstants = generateStructsForConstants(annotations, aliases); - - return template - .replace(/::_STRUCTS_::/, translatedStructs) - .replace(/::_INLINES_::/, translatedInlineMethods) - .replace(/::_CONSTANTS_::/, translatedConstants); -} -module.exports = { - translateObjectsForStructs, - capitalizeFirstLetter, - getNamespacedStructName, -}; diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js deleted file mode 100644 index 0433152f7f6..00000000000 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructsForConstants.js +++ /dev/null @@ -1,275 +0,0 @@ -/** - * 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 strict - * @format - */ - -'use strict'; - -import type { - ObjectParamTypeAnnotation, - ObjectTypeAliasTypeShape, -} from '../../../CodegenSchema'; -const {flatObjects, capitalizeFirstLetter} = require('./Utils'); -const {getTypeAliasTypeAnnotation} = require('../Utils'); - -const structTemplate = ` -namespace JS { - namespace Native::_MODULE_NAME_:: { - struct ::_STRUCT_NAME_:: { - - struct Builder { - struct Input { - ::_INPUT_:: - }; - - /** Initialize with a set of values */ - Builder(const Input i); - /** Initialize with an existing ::_STRUCT_NAME_:: */ - Builder(::_STRUCT_NAME_:: i); - /** Builds the object. Generally used only by the infrastructure. */ - NSDictionary *buildUnsafeRawValue() const { return _factory(); }; - private: - NSDictionary *(^_factory)(void); - }; - - static ::_STRUCT_NAME_:: fromUnsafeRawValue(NSDictionary *const v) { return {v}; } - NSDictionary *unsafeRawValue() const { return _v; } - private: - ::_STRUCT_NAME_::(NSDictionary *const v) : _v(v) {} - NSDictionary *_v; - }; - } -} - -inline JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::Builder::Builder(const Input i) : _factory(^{ - NSMutableDictionary *d = [NSMutableDictionary new]; - ::_PROPERTIES_:: - return d; -}) {} -inline JS::Native::_MODULE_NAME_::::::_STRUCT_NAME_::::Builder::Builder(::_STRUCT_NAME_:: i) : _factory(^{ - return i.unsafeRawValue(); -}) {}`; - -function getBuilderInputFieldDeclaration( - property: ObjectParamTypeAnnotation, - name: string, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - function markRequiredIfNecessary(annotation) { - if (!property.optional) { - return 'RCTRequired<' + annotation + '> ' + property.name + ';'; - } - return 'folly::Optional<' + annotation + '> ' + property.name + ';'; - } - const {typeAnnotation} = property; - - // TODO(T67898313): Workaround for NativeLinking's use of union type. This check may be removed once typeAnnotation is non-optional. - if (!typeAnnotation) { - throw new Error( - `Cannot get array element type, property ${property.name} does not contain a type annotation`, - ); - } - - const realTypeAnnotation = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases) - : typeAnnotation; - - const variableName = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? typeAnnotation.name - : `${name}${capitalizeFirstLetter(property.name)}`; - - switch (realTypeAnnotation.type) { - case 'ReservedFunctionValueTypeAnnotation': - switch (realTypeAnnotation.name) { - case 'RootTag': - return markRequiredIfNecessary('double'); - default: - (realTypeAnnotation.name: empty); - throw new Error( - `Unknown prop type, found: ${realTypeAnnotation.name}"`, - ); - } - case 'StringTypeAnnotation': - if (property.optional) { - return 'NSString *' + property.name + ';'; - } - return markRequiredIfNecessary('NSString *'); - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return markRequiredIfNecessary('double'); - case 'BooleanTypeAnnotation': - return markRequiredIfNecessary('bool'); - case 'ObjectTypeAnnotation': - return markRequiredIfNecessary( - `JS::Native::_MODULE_NAME_::::${variableName}::Builder`, - ); - case 'GenericObjectTypeAnnotation': - case 'AnyTypeAnnotation': - if (property.optional) { - return 'id _Nullable ' + property.name + ';'; - } - return markRequiredIfNecessary('id'); - case 'ArrayTypeAnnotation': - return markRequiredIfNecessary('std::vector>'); - case 'FunctionTypeAnnotation': - default: - throw new Error(`Unknown prop type, found: ${realTypeAnnotation.type}"`); - } -} - -function safeGetter(name: string, optional: boolean) { - return ` - auto ${name} = i.${name}${optional ? '' : '.get()'}; - d[@"${name}"] = ${name}; - `.trim(); -} - -function arrayGetter(name: string, optional: boolean) { - return ` - auto ${name} = i.${name}${optional ? '' : '.get()'}; - d[@"${name}"] = RCTConvert${ - optional ? 'Optional' : '' - }VecToArray(${name}, ^id(id el_) { return el_; }); - `.trim(); -} - -function boolGetter(name: string, optional: boolean) { - return ` - auto ${name} = i.${name}${optional ? '' : '.get()'}; - d[@"${name}"] = ${ - optional - ? `${name}.hasValue() ? @((BOOL)${name}.value()) : nil` - : `@(${name})` - }; - `.trim(); -} - -function numberGetter(name: string, optional: boolean) { - return ` - auto ${name} = i.${name}${optional ? '' : '.get()'}; - d[@"${name}"] = ${ - optional - ? `${name}.hasValue() ? @((double)${name}.value()) : nil` - : `@(${name})` - }; - `.trim(); -} - -function unsafeGetter(name: string, optional: boolean) { - return ` - auto ${name} = i.${name}${optional ? '' : '.get()'}; - d[@"${name}"] = ${ - optional - ? `${name}.hasValue() ? ${name}.value().buildUnsafeRawValue() : nil` - : `${name}.buildUnsafeRawValue()` - }; - `.trim(); -} - -function getObjectProperty( - property: ObjectParamTypeAnnotation, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - const {typeAnnotation} = property; - - // TODO(T67898313): Workaround for NativeLinking's use of union type. This check may be removed once typeAnnotation is non-optional. - if (!typeAnnotation) { - throw new Error( - `Cannot get array element type, property ${property.name} does not contain a type annotation`, - ); - } - - const type = - typeAnnotation.type === 'TypeAliasTypeAnnotation' - ? getTypeAliasTypeAnnotation(typeAnnotation.name, aliases).type - : typeAnnotation.type; - - switch (type) { - case 'ReservedFunctionValueTypeAnnotation': - if (typeAnnotation.name == null) { - throw new Error(`Prop type ${type} has no name.`); - } - switch (typeAnnotation.name) { - case 'RootTag': - return numberGetter(property.name, property.optional); - default: - // TODO (T65847278): Figure out why this does not work. - // (typeAnnotation.name: empty); - throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); - } - case 'NumberTypeAnnotation': - case 'FloatTypeAnnotation': - case 'Int32TypeAnnotation': - return numberGetter(property.name, property.optional); - case 'BooleanTypeAnnotation': - return boolGetter(property.name, property.optional); - case 'StringTypeAnnotation': - case 'GenericObjectTypeAnnotation': - case 'AnyTypeAnnotation': - return safeGetter(property.name, property.optional); - case 'ObjectTypeAnnotation': - return unsafeGetter(property.name, property.optional); - case 'ArrayTypeAnnotation': - return arrayGetter(property.name, property.optional); - case 'FunctionTypeAnnotation': - default: - throw new Error(`Unknown prop type, found: ${type}"`); - } -} - -function generateStructsForConstants( - annotations: $ReadOnlyArray< - $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, - |}>, - >, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): string { - return flatObjects(annotations, true, aliases) - .reduce( - (acc, object) => - acc.concat( - structTemplate - .replace( - /::_INPUT_::/g, - object.properties - .map(property => - getBuilderInputFieldDeclaration( - property, - object.name, - aliases, - ), - ) - .join('\n '), - ) - .replace( - /::_PROPERTIES_::/g, - object.properties - .map(property => getObjectProperty(property, aliases)) - .join('\n'), - ) - .replace(/::_STRUCT_NAME_::/g, object.name), - ), - [], - ) - .reverse() - .join('\n') - .replace(/SpecGetConstantsReturnType/g, 'Constants') - .replace(/GetConstantsReturnType/g, 'Constants'); -} -module.exports = { - generateStructsForConstants, - capitalizeFirstLetter, -}; diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js deleted file mode 100644 index fd4dca38468..00000000000 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/Utils.js +++ /dev/null @@ -1,112 +0,0 @@ -/** - * 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 strict - * @format - */ - -'use strict'; - -import type { - ObjectParamTypeAnnotation, - ObjectTypeAliasTypeShape, -} from '../../../CodegenSchema'; -const {getTypeAliasTypeAnnotation} = require('../Utils'); - -function capitalizeFirstLetter(string: string): string { - return string.charAt(0).toUpperCase() + string.slice(1); -} - -function flatObjects( - annotations: $ReadOnlyArray< - $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, - |}>, - >, - forConstants: boolean = false, - aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>, -): $ReadOnlyArray< - $ReadOnly<{| - name: string, - properties: $ReadOnlyArray, - |}>, -> { - let objectTypesToFlatten: Array<{| - properties: $ReadOnlyArray, - name: string, - |}> = annotations - .map(annotation => { - if (annotation.object.type === 'TypeAliasTypeAnnotation') { - const alias = getTypeAliasTypeAnnotation(annotation.name, aliases); - return {name: annotation.name, properties: alias.properties}; - } - return { - name: annotation.name, - properties: annotation.object.properties, - }; - }) - .filter( - annotation => - (annotation.name === 'SpecGetConstantsReturnType') === forConstants, - ) - .filter( - annotation => - annotation.name !== 'SpecGetConstantsReturnType' || - annotation.properties.length > 0, - ); - - let flattenObjects: Array<{| - properties: $ReadOnlyArray, - name: string, - |}> = []; - - while (objectTypesToFlatten.length !== 0) { - const oldObjectTypesToFlatten = objectTypesToFlatten; - objectTypesToFlatten = []; - flattenObjects = flattenObjects.concat( - oldObjectTypesToFlatten.map(object => { - const {properties} = object; - if (properties !== undefined) { - objectTypesToFlatten = objectTypesToFlatten.concat( - properties.reduce((acc, curr) => { - if ( - curr.typeAnnotation && - curr.typeAnnotation.type === 'ObjectTypeAnnotation' && - curr.typeAnnotation.properties - ) { - return acc.concat({ - properties: curr.typeAnnotation.properties, - name: object.name + capitalizeFirstLetter(curr.name), - }); - } - return acc; - }, []), - ); - } - return object; - }), - ); - } - - return flattenObjects; -} - -function getSafePropertyName(property: ObjectParamTypeAnnotation): string { - if (property.name === 'id') { - return `${property.name}_`; - } - return property.name; -} - -module.exports = { - flatObjects, - capitalizeFirstLetter, - getSafePropertyName, -}; diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js deleted file mode 100644 index 2de452b87c2..00000000000 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/structFixtures.js +++ /dev/null @@ -1,218 +0,0 @@ -/** - * 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 strict-local - * @format - */ - -'use strict'; - -import type {ObjectParamTypeAnnotation} from '../../../CodegenSchema.js'; -const SIMPLE_STRUCT: $ReadOnlyArray< - $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, - |}>, -> = [ - { - name: 'SpecSampleFuncReturnType', - object: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'a', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'b', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'c', - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }, - { - optional: false, - name: 'd', - typeAnnotation: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'e', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'f', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'g', - typeAnnotation: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'h', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'i', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'j', - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }, - ], - }, - }, - ], - }, - }, - { - optional: false, - name: 'k', - typeAnnotation: { - type: 'ReservedFunctionValueTypeAnnotation', - name: 'RootTag', - }, - }, - ], - }, - }, -]; - -const SIMPLE_CONSTANTS: $ReadOnlyArray< - $ReadOnly<{| - name: string, - object: $ReadOnly<{| - type: 'ObjectTypeAnnotation', - properties: $ReadOnlyArray, - |}>, - |}>, -> = [ - { - name: 'SpecGetConstantsReturnType', - object: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'a', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'b', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'c', - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }, - { - optional: false, - name: 'd', - typeAnnotation: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'e', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'f', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'g', - typeAnnotation: { - type: 'ObjectTypeAnnotation', - properties: [ - { - optional: false, - name: 'h', - typeAnnotation: { - type: 'BooleanTypeAnnotation', - }, - }, - { - optional: false, - name: 'i', - typeAnnotation: { - type: 'NumberTypeAnnotation', - }, - }, - { - optional: false, - name: 'j', - typeAnnotation: { - type: 'StringTypeAnnotation', - }, - }, - ], - }, - }, - ], - }, - }, - { - optional: false, - name: 'k', - typeAnnotation: { - type: 'ReservedFunctionValueTypeAnnotation', - name: 'RootTag', - }, - }, - ], - }, - }, -]; -module.exports = { - SIMPLE_STRUCT, - SIMPLE_CONSTANTS, -}; diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js index b41441cb2da..3c494397185 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js +++ b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js @@ -12,7 +12,7 @@ 'use strict'; const fixtures = require('../__test_fixtures__/fixtures.js'); -const generator = require('../GenerateModuleHObjCpp.js'); +const generator = require('../GenerateModuleObjCpp'); describe('GenerateModuleHObjCpp', () => { Object.keys(fixtures) @@ -21,8 +21,9 @@ describe('GenerateModuleHObjCpp', () => { const fixture = fixtures[fixtureName]; it(`can generate fixture ${fixtureName}`, () => { + const output = generator.generate(fixtureName, fixture, 'SampleSpec'); expect( - generator.generate(fixtureName, fixture, 'SampleSpec'), + new Map([['SampleSpec.h', output.get('SampleSpec.h')]]), ).toMatchSnapshot(); }); }); diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js index 5bfd8c79e07..ec8f4842a10 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js +++ b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleMm-test.js @@ -12,7 +12,7 @@ 'use strict'; const fixtures = require('../__test_fixtures__/fixtures.js'); -const generator = require('../GenerateModuleMm.js'); +const generator = require('../GenerateModuleObjCpp'); describe('GenerateModuleMm', () => { Object.keys(fixtures) @@ -21,8 +21,11 @@ describe('GenerateModuleMm', () => { const fixture = fixtures[fixtureName]; it(`can generate fixture ${fixtureName}`, () => { + const output = generator.generate(fixtureName, fixture, 'SampleSpec'); expect( - generator.generate(fixtureName, fixture, 'SampleSpec'), + new Map([ + ['SampleSpec-generated.mm', output.get('SampleSpec-generated.mm')], + ]), ).toMatchSnapshot(); }); }); diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js b/packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js deleted file mode 100644 index a66b5ff7e4c..00000000000 --- a/packages/react-native-codegen/src/generators/modules/__tests__/GenerateStructs-test.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * 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. - * - * @emails oncall+react_native - * @flow strict-local - * @format - */ - -'use strict'; - -const fixtures = require('../__test_fixtures__/structFixtures.js'); -const generator = require('../ObjCppUtils/GenerateStructs.js'); - -describe('GenerateStructs', () => { - Object.keys(fixtures) - .sort() - .forEach(fixtureName => { - const fixture = fixtures[fixtureName]; - - it(`can generate fixture ${fixtureName}`, () => { - expect( - generator - .translateObjectsForStructs(fixture, fixtureName, {}) - .replace(/::_MODULE_NAME_::/g, 'SampleTurboModule'), - ).toMatchSnapshot(); - }); - }); -}); 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 939b9bcea8d..2d7f078c525 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 @@ -34,6 +34,45 @@ Map { +namespace JS { + namespace NativeSampleTurboModule { + struct SpecDifficultAE { + bool D() const; + double E() const; + NSString *F() const; + double id_() 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 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 + + namespace JS { namespace NativeSampleTurboModule { struct SpecOptionalsAOptionalObjectProperty { @@ -54,21 +93,22 @@ namespace JS { namespace JS { namespace NativeSampleTurboModule { - struct SpecDifficultAE { - bool D() const; - double E() const; - NSString *F() const; - double id_() const; + struct SpecOptionalsA { + folly::Optional optionalNumberProperty() const; + folly::Optional> optionalArrayProperty() const; + folly::Optional optionalObjectProperty() const; + id _Nullable optionalGenericObjectProperty() const; + folly::Optional optionalBooleanTypeProperty() const; - SpecDifficultAE(NSDictionary *const v) : _v(v) {} + SpecOptionalsA(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeSampleTurboModule_SpecDifficultAE) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultAE:(id)json; +@interface RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsA) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsA:(id)json; @end @@ -96,7 +136,7 @@ namespace JS { folly::Optional> optionalArrayOfNumbers() const; facebook::react::LazyVector arrayOfStrings() const; folly::Optional> optionalArrayOfStrings() const; - facebook::react::LazyVector arrayOfObjects() const; + facebook::react::LazyVector arrayOfObjects() const; SpecGetArraysOptions(NSDictionary *const v) : _v(v) {} private: @@ -109,82 +149,57 @@ namespace JS { + (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetArraysOptions:(id)json; @end +@protocol NativeSampleTurboModuleSpec -namespace JS { - namespace NativeSampleTurboModule { - struct SpecOptionalMethodExtrasElement { - NSString *key() const; - id value() const; +- (NSDictionary *)difficult:(JS::NativeSampleTurboModule::SpecDifficultA &)A; +- (void)optionals:(JS::NativeSampleTurboModule::SpecOptionalsA &)A; +- (void)optionalMethod:(NSDictionary *)options + callback:(RCTResponseSenderBlock)callback + extras:(NSArray *)extras; +- (void)getArrays:(JS::NativeSampleTurboModule::SpecGetArraysOptions &)options; - SpecOptionalMethodExtrasElement(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'SampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; - } + } // namespace react +} // namespace facebook + + + +inline bool JS::NativeSampleTurboModule::SpecDifficultAE::D() const +{ + id const p = _v[@\\"D\\"]; + return RCTBridgingToBool(p); } -@interface RCTCxxConvert (NativeSampleTurboModule_SpecOptionalMethodExtrasElement) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalMethodExtrasElement:(id)json; -@end - -namespace JS { - namespace NativeSampleTurboModule { - struct SpecOptionalsA { - folly::Optional optionalNumberProperty() const; - folly::Optional> optionalArrayProperty() const; - folly::Optional optionalObjectProperty() const; - id _Nullable optionalGenericObjectProperty() const; - folly::Optional optionalBooleanTypeProperty() const; - - SpecOptionalsA(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } +inline double JS::NativeSampleTurboModule::SpecDifficultAE::E() const +{ + id const p = _v[@\\"E\\"]; + return RCTBridgingToDouble(p); } -@interface RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsA) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsA:(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; - }; - } +inline NSString *JS::NativeSampleTurboModule::SpecDifficultAE::F() const +{ + id const p = _v[@\\"F\\"]; + return RCTBridgingToString(p); } -@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; - }; - } +inline double JS::NativeSampleTurboModule::SpecDifficultAE::id_() const +{ + id const p = _v[@\\"id_\\"]; + return RCTBridgingToDouble(p); } -@interface RCTCxxConvert (NativeSampleTurboModule_SpecDifficultA) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultA:(id)json; -@end inline bool JS::NativeSampleTurboModule::SpecDifficultA::D() const { @@ -207,24 +222,17 @@ inline NSString *JS::NativeSampleTurboModule::SpecDifficultA::F() const } -inline bool JS::NativeSampleTurboModule::SpecDifficultReturnType::D() const +inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty::x() const { - id const p = _v[@\\"D\\"]; - return RCTBridgingToBool(p); -} - - -inline double JS::NativeSampleTurboModule::SpecDifficultReturnType::E() const -{ - id const p = _v[@\\"E\\"]; + id const p = _v[@\\"x\\"]; return RCTBridgingToDouble(p); } -inline NSString *JS::NativeSampleTurboModule::SpecDifficultReturnType::F() const +inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty::y() const { - id const p = _v[@\\"F\\"]; - return RCTBridgingToString(p); + id const p = _v[@\\"y\\"]; + return RCTBridgingToDouble(p); } @@ -263,17 +271,10 @@ inline folly::Optional JS::NativeSampleTurboModule::SpecOptionalsA::option } -inline NSString *JS::NativeSampleTurboModule::SpecOptionalMethodExtrasElement::key() const +inline double JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement::numberProperty() const { - id const p = _v[@\\"key\\"]; - return RCTBridgingToString(p); -} - - -inline id JS::NativeSampleTurboModule::SpecOptionalMethodExtrasElement::value() const -{ - id const p = _v[@\\"value\\"]; - return p; + id const p = _v[@\\"numberProperty\\"]; + return RCTBridgingToDouble(p); } @@ -305,84 +306,12 @@ inline folly::Optional> JS::NativeSample } -inline facebook::react::LazyVector JS::NativeSampleTurboModule::SpecGetArraysOptions::arrayOfObjects() const +inline facebook::react::LazyVector JS::NativeSampleTurboModule::SpecGetArraysOptions::arrayOfObjects() const { id const p = _v[@\\"arrayOfObjects\\"]; - return RCTBridgingToVec(p, ^JS::NativeSampleTurboModule::arrayOfObjectsElement(id itemValue_0) { return JS::NativeSampleTurboModule::arrayOfObjectsElement(itemValue_0); }); + return RCTBridgingToVec(p, ^JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement(id itemValue_0) { return JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement(p); }); } - -inline double JS::NativeSampleTurboModule::SpecGetArraysOptionsArrayOfObjectsElement::numberProperty() const -{ - id const p = _v[@\\"numberProperty\\"]; - return RCTBridgingToDouble(p); -} - - -inline bool JS::NativeSampleTurboModule::SpecDifficultAE::D() const -{ - id const p = _v[@\\"D\\"]; - return RCTBridgingToBool(p); -} - - -inline double JS::NativeSampleTurboModule::SpecDifficultAE::E() const -{ - id const p = _v[@\\"E\\"]; - return RCTBridgingToDouble(p); -} - - -inline NSString *JS::NativeSampleTurboModule::SpecDifficultAE::F() const -{ - id const p = _v[@\\"F\\"]; - return RCTBridgingToString(p); -} - - -inline double JS::NativeSampleTurboModule::SpecDifficultAE::id_() const -{ - id const p = _v[@\\"id_\\"]; - return RCTBridgingToDouble(p); -} - - -inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty::x() const -{ - id const p = _v[@\\"x\\"]; - return RCTBridgingToDouble(p); -} - - -inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty::y() const -{ - id const p = _v[@\\"y\\"]; - return RCTBridgingToDouble(p); -} - - - -@protocol NativeSampleTurboModuleSpec -- (NSDictionary *) difficult:(JS::NativeSampleTurboModule::SpecDifficultA &)A; -- (void) optionals:(JS::NativeSampleTurboModule::SpecOptionalsA &)A; -- (void) optionalMethod:(NSDictionary *)options - callback:(RCTResponseSenderBlock)callback - extras:(NSArray * _Nullable)extras; -- (void) getArrays:(JS::NativeSampleTurboModule::SpecGetArraysOptions &)options; -@end - - -namespace facebook { - namespace react { - /** - * ObjC++ class for module 'SampleTurboModule' - */ - class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { - public: - NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - } // namespace react -} // namespace facebook ", } `; @@ -421,24 +350,25 @@ Map { - - @protocol NativeSampleTurboModuleSpec + + @end - - namespace facebook { namespace react { /** - * ObjC++ class for module 'SampleTurboModule' - */ + * ObjC++ class for module 'SampleTurboModule' + */ class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { public: NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; } // namespace react } // namespace facebook + + + ", } `; @@ -479,19 +409,19 @@ Map { namespace JS { namespace NativeAliasTurboModule { - struct OptionsDisplaySize { - double width() const; - double height() const; + struct OptionsOffset { + double x() const; + double y() const; - OptionsDisplaySize(NSDictionary *const v) : _v(v) {} + OptionsOffset(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeAliasTurboModule_OptionsDisplaySize) -+ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsDisplaySize:(id)json; +@interface RCTCxxConvert (NativeAliasTurboModule_OptionsOffset) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsOffset:(id)json; @end @@ -515,19 +445,19 @@ namespace JS { namespace JS { namespace NativeAliasTurboModule { - struct OptionsOffset { - double x() const; - double y() const; + struct OptionsDisplaySize { + double width() const; + double height() const; - OptionsOffset(NSDictionary *const v) : _v(v) {} + OptionsDisplaySize(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } -@interface RCTCxxConvert (NativeAliasTurboModule_OptionsOffset) -+ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsOffset:(id)json; +@interface RCTCxxConvert (NativeAliasTurboModule_OptionsDisplaySize) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsDisplaySize:(id)json; @end @@ -551,40 +481,24 @@ namespace JS { + (RCTManagedPointer *)JS_NativeAliasTurboModule_Options:(id)json; @end -inline JS::NativeAliasTurboModule::OptionsOffset JS::NativeAliasTurboModule::Options::offset() const -{ - id const p = _v[@\\"offset\\"]; - return JS::NativeAliasTurboModule::OptionsOffset(p); -} +@protocol NativeAliasTurboModuleSpec +- (void)cropImage:(JS::NativeAliasTurboModule::Options &)cropData; -inline JS::NativeAliasTurboModule::OptionsSize JS::NativeAliasTurboModule::Options::size() const -{ - id const p = _v[@\\"size\\"]; - return JS::NativeAliasTurboModule::OptionsSize(p); -} +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'AliasTurboModule' + */ + class JSI_EXPORT NativeAliasTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeAliasTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook -inline folly::Optional JS::NativeAliasTurboModule::Options::displaySize() const -{ - id const p = _v[@\\"displaySize\\"]; - return (p == nil ? folly::none : folly::make_optional(JS::NativeAliasTurboModule::OptionsDisplaySize(p))); -} - - -inline NSString *JS::NativeAliasTurboModule::Options::resizeMode() const -{ - id const p = _v[@\\"resizeMode\\"]; - return RCTBridgingToString(p); -} - - -inline folly::Optional JS::NativeAliasTurboModule::Options::allowExternalStorage() const -{ - id const p = _v[@\\"allowExternalStorage\\"]; - return RCTBridgingToOptionalBool(p); -} - inline double JS::NativeAliasTurboModule::OptionsOffset::x() const { @@ -628,24 +542,40 @@ inline double JS::NativeAliasTurboModule::OptionsDisplaySize::height() const } - -@protocol NativeAliasTurboModuleSpec - -- (void) cropImage:(JS::NativeAliasTurboModule::Options &)cropData; -@end +inline JS::NativeAliasTurboModule::OptionsOffset JS::NativeAliasTurboModule::Options::offset() const +{ + id const p = _v[@\\"offset\\"]; + return JS::NativeAliasTurboModule::OptionsOffset(p); +} -namespace facebook { - namespace react { - /** - * ObjC++ class for module 'AliasTurboModule' - */ - class JSI_EXPORT NativeAliasTurboModuleSpecJSI : public ObjCTurboModule { - public: - NativeAliasTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - } // namespace react -} // namespace facebook +inline JS::NativeAliasTurboModule::OptionsSize JS::NativeAliasTurboModule::Options::size() const +{ + id const p = _v[@\\"size\\"]; + return JS::NativeAliasTurboModule::OptionsSize(p); +} + + +inline folly::Optional JS::NativeAliasTurboModule::Options::displaySize() const +{ + id const p = _v[@\\"displaySize\\"]; + return (p == nil ? folly::none : folly::make_optional(JS::NativeAliasTurboModule::OptionsDisplaySize(p))); +} + + +inline NSString *JS::NativeAliasTurboModule::Options::resizeMode() const +{ + id const p = _v[@\\"resizeMode\\"]; + return RCTBridgingToOptionalString(p); +} + + +inline folly::Optional JS::NativeAliasTurboModule::Options::allowExternalStorage() const +{ + id const p = _v[@\\"allowExternalStorage\\"]; + return RCTBridgingToOptionalBool(p); +} + ", } `; @@ -684,124 +614,6 @@ Map { -namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifierNodeLocation { - double longitude() const; - double latitude() const; - folly::Optional altitude() const; - folly::Optional heading() const; - folly::Optional speed() const; - - PhotoIdentifierNodeLocation(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNodeLocation) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNodeLocation:(id)json; -@end - - -namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifierNode { - JS::NativeCameraRollManager::PhotoIdentifierImage image() const; - NSString *type() const; - NSString *group_name() const; - double timestamp() const; - JS::NativeCameraRollManager::PhotoIdentifierNodeLocation location() const; - - PhotoIdentifierNode(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNode) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNode:(id)json; -@end - - -namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifiersPagePage_info { - bool has_next_page() const; - NSString *start_cursor() const; - NSString *end_cursor() const; - - PhotoIdentifiersPagePage_info(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPagePage_info) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPagePage_info:(id)json; -@end - - -namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifierImage { - NSString *uri() const; - double playableDuration() const; - double width() const; - double height() const; - folly::Optional isStored() const; - NSString *filename() const; - - PhotoIdentifierImage(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierImage) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierImage:(id)json; -@end - - -namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifier { - JS::NativeCameraRollManager::PhotoIdentifierNode node() const; - - PhotoIdentifier(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifier) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifier:(id)json; -@end - - -namespace JS { - namespace NativeCameraRollManager { - struct PhotoIdentifiersPage { - facebook::react::LazyVector edges() const; - JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info page_info() const; - - PhotoIdentifiersPage(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPage) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json; -@end - - namespace JS { namespace NativeCameraRollManager { struct GetPhotosParams { @@ -824,223 +636,31 @@ namespace JS { + (RCTManagedPointer *)JS_NativeCameraRollManager_GetPhotosParams:(id)json; @end -inline double JS::NativeCameraRollManager::GetPhotosParams::first() const -{ - id const p = _v[@\\"first\\"]; - return RCTBridgingToDouble(p); -} - - -inline NSString *JS::NativeCameraRollManager::GetPhotosParams::after() const -{ - id const p = _v[@\\"after\\"]; - return RCTBridgingToString(p); -} - - -inline NSString *JS::NativeCameraRollManager::GetPhotosParams::groupName() const -{ - id const p = _v[@\\"groupName\\"]; - return RCTBridgingToString(p); -} - - -inline NSString *JS::NativeCameraRollManager::GetPhotosParams::groupTypes() const -{ - id const p = _v[@\\"groupTypes\\"]; - return RCTBridgingToString(p); -} - - -inline NSString *JS::NativeCameraRollManager::GetPhotosParams::assetType() const -{ - id const p = _v[@\\"assetType\\"]; - return RCTBridgingToString(p); -} - - -inline folly::Optional JS::NativeCameraRollManager::GetPhotosParams::maxSize() const -{ - id const p = _v[@\\"maxSize\\"]; - return RCTBridgingToOptionalDouble(p); -} - - -inline folly::Optional> JS::NativeCameraRollManager::GetPhotosParams::mimeTypes() const -{ - id const p = _v[@\\"mimeTypes\\"]; - return RCTBridgingToOptionalVec(p, ^NSString *(id itemValue_0) { return RCTBridgingToString(itemValue_0); }); -} - - -inline facebook::react::LazyVector JS::NativeCameraRollManager::PhotoIdentifiersPage::edges() const -{ - id const p = _v[@\\"edges\\"]; - return RCTBridgingToVec(p, ^JS::NativeCameraRollManager::PhotoIdentifier(id itemValue_0) { return JS::NativeCameraRollManager::PhotoIdentifier(itemValue_0); }); -} - - -inline JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info JS::NativeCameraRollManager::PhotoIdentifiersPage::page_info() const -{ - id const p = _v[@\\"page_info\\"]; - return JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info(p); -} - - -inline JS::NativeCameraRollManager::PhotoIdentifierNode JS::NativeCameraRollManager::PhotoIdentifier::node() const -{ - id const p = _v[@\\"node\\"]; - return JS::NativeCameraRollManager::PhotoIdentifierNode(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifierImage::uri() const -{ - id const p = _v[@\\"uri\\"]; - return RCTBridgingToString(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierImage::playableDuration() const -{ - id const p = _v[@\\"playableDuration\\"]; - return RCTBridgingToDouble(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierImage::width() const -{ - id const p = _v[@\\"width\\"]; - return RCTBridgingToDouble(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierImage::height() const -{ - id const p = _v[@\\"height\\"]; - return RCTBridgingToDouble(p); -} - - -inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierImage::isStored() const -{ - id const p = _v[@\\"isStored\\"]; - return RCTBridgingToOptionalBool(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifierImage::filename() const -{ - id const p = _v[@\\"filename\\"]; - return RCTBridgingToString(p); -} - - -inline bool JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::has_next_page() const -{ - id const p = _v[@\\"has_next_page\\"]; - return RCTBridgingToBool(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::start_cursor() const -{ - id const p = _v[@\\"start_cursor\\"]; - return RCTBridgingToString(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifiersPagePage_info::end_cursor() const -{ - id const p = _v[@\\"end_cursor\\"]; - return RCTBridgingToString(p); -} - - -inline JS::NativeCameraRollManager::PhotoIdentifierImage JS::NativeCameraRollManager::PhotoIdentifierNode::image() const -{ - id const p = _v[@\\"image\\"]; - return JS::NativeCameraRollManager::PhotoIdentifierImage(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifierNode::type() const -{ - id const p = _v[@\\"type\\"]; - return RCTBridgingToString(p); -} - - -inline NSString *JS::NativeCameraRollManager::PhotoIdentifierNode::group_name() const -{ - id const p = _v[@\\"group_name\\"]; - return RCTBridgingToString(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierNode::timestamp() const -{ - id const p = _v[@\\"timestamp\\"]; - return RCTBridgingToDouble(p); -} - - -inline JS::NativeCameraRollManager::PhotoIdentifierNodeLocation JS::NativeCameraRollManager::PhotoIdentifierNode::location() const -{ - id const p = _v[@\\"location\\"]; - return JS::NativeCameraRollManager::PhotoIdentifierNodeLocation(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::longitude() const -{ - id const p = _v[@\\"longitude\\"]; - return RCTBridgingToDouble(p); -} - - -inline double JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::latitude() const -{ - id const p = _v[@\\"latitude\\"]; - return RCTBridgingToDouble(p); -} - - -inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::altitude() const -{ - id const p = _v[@\\"altitude\\"]; - return RCTBridgingToOptionalDouble(p); -} - - -inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::heading() const -{ - id const p = _v[@\\"heading\\"]; - return RCTBridgingToOptionalDouble(p); -} - - -inline folly::Optional JS::NativeCameraRollManager::PhotoIdentifierNodeLocation::speed() const -{ - id const p = _v[@\\"speed\\"]; - return RCTBridgingToOptionalDouble(p); -} - - - @protocol NativeCameraRollManagerSpec -- (void) getPhotos:(JS::NativeCameraRollManager::GetPhotosParams &)params - resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject; -- (void) saveToCameraRoll:(NSString *)uri - type:(NSString *)type - resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject; -- (void) deletePhotos:(NSArray *)assets - resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject; +- (void)getPhotos:(JS::NativeCameraRollManager::GetPhotosParams &)params + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)saveToCameraRoll:(NSString *)uri + type:(NSString *)type + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; +- (void)deletePhotos:(NSArray *)assets + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; + @end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'CameraRollManager' + */ + class JSI_EXPORT NativeCameraRollManagerSpecJSI : public ObjCTurboModule { + public: + NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook @@ -1088,59 +708,119 @@ namespace JS { + (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json; @end -inline NSString *JS::NativeExceptionsManager::ExceptionData::message() const -{ - id const p = _v[@\\"message\\"]; - return RCTBridgingToString(p); +@protocol NativeExceptionsManagerSpec + +- (void)reportFatalException:(NSString *)message + stack:(NSArray *)stack + exceptionId:(double)exceptionId; +- (void)reportSoftException:(NSString *)message + stack:(NSArray *)stack + exceptionId:(double)exceptionId; +- (void)reportException:(JS::NativeExceptionsManager::ExceptionData &)data; +- (void)updateExceptionMessage:(NSString *)message + stack:(NSArray *)stack + exceptionId:(double)exceptionId; +- (void)dismissRedbox; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'ExceptionsManager' + */ + class JSI_EXPORT NativeExceptionsManagerSpecJSI : public ObjCTurboModule { + public: + NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +namespace JS { + namespace NativeImagePickerIOS { + struct SpecOpenCameraDialogConfig { + bool unmirrorFrontFacingCamera() const; + bool videoMode() const; + + SpecOpenCameraDialogConfig(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } } +@interface RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig) ++ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json; +@end -inline NSString *JS::NativeExceptionsManager::ExceptionData::originalMessage() const +@protocol NativeImagePickerIOSSpec + +- (void)openCameraDialog:(JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig &)config + successCallback:(RCTResponseSenderBlock)successCallback + cancelCallback:(RCTResponseSenderBlock)cancelCallback; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'ImagePickerIOS' + */ + class JSI_EXPORT NativeImagePickerIOSSpecJSI : public ObjCTurboModule { + public: + NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + +inline double JS::NativeCameraRollManager::GetPhotosParams::first() const { - id const p = _v[@\\"originalMessage\\"]; - return RCTBridgingToString(p); -} - - -inline NSString *JS::NativeExceptionsManager::ExceptionData::name() const -{ - id const p = _v[@\\"name\\"]; - return RCTBridgingToString(p); -} - - -inline NSString *JS::NativeExceptionsManager::ExceptionData::componentStack() const -{ - id const p = _v[@\\"componentStack\\"]; - return RCTBridgingToString(p); -} - - -inline facebook::react::LazyVector JS::NativeExceptionsManager::ExceptionData::stack() const -{ - id const p = _v[@\\"stack\\"]; - return RCTBridgingToVec(p, ^JS::NativeExceptionsManager::StackFrame(id itemValue_0) { return JS::NativeExceptionsManager::StackFrame(itemValue_0); }); -} - - -inline double JS::NativeExceptionsManager::ExceptionData::id_() const -{ - id const p = _v[@\\"id_\\"]; + id const p = _v[@\\"first\\"]; return RCTBridgingToDouble(p); } -inline bool JS::NativeExceptionsManager::ExceptionData::isFatal() const +inline NSString *JS::NativeCameraRollManager::GetPhotosParams::after() const { - id const p = _v[@\\"isFatal\\"]; - return RCTBridgingToBool(p); + id const p = _v[@\\"after\\"]; + return RCTBridgingToOptionalString(p); } -inline id _Nullable JS::NativeExceptionsManager::ExceptionData::extraData() const +inline NSString *JS::NativeCameraRollManager::GetPhotosParams::groupName() const { - id const p = _v[@\\"extraData\\"]; - return p; + id const p = _v[@\\"groupName\\"]; + return RCTBridgingToOptionalString(p); +} + + +inline NSString *JS::NativeCameraRollManager::GetPhotosParams::groupTypes() const +{ + id const p = _v[@\\"groupTypes\\"]; + return RCTBridgingToOptionalString(p); +} + + +inline NSString *JS::NativeCameraRollManager::GetPhotosParams::assetType() const +{ + id const p = _v[@\\"assetType\\"]; + return RCTBridgingToOptionalString(p); +} + + +inline folly::Optional JS::NativeCameraRollManager::GetPhotosParams::maxSize() const +{ + id const p = _v[@\\"maxSize\\"]; + return RCTBridgingToOptionalDouble(p); +} + + +inline folly::Optional> JS::NativeCameraRollManager::GetPhotosParams::mimeTypes() const +{ + id const p = _v[@\\"mimeTypes\\"]; + return RCTBridgingToOptionalVec(p, ^NSString *(id itemValue_0) { return RCTBridgingToString(itemValue_0); }); } @@ -1179,39 +859,61 @@ inline folly::Optional JS::NativeExceptionsManager::StackFrame::collapse() } +inline NSString *JS::NativeExceptionsManager::ExceptionData::message() const +{ + id const p = _v[@\\"message\\"]; + return RCTBridgingToString(p); +} -@protocol NativeExceptionsManagerSpec -- (void) reportFatalException:(NSString *)message - stack:(NSArray *)stack - exceptionId:(double)exceptionId; -- (void) reportSoftException:(NSString *)message - stack:(NSArray *)stack - exceptionId:(double)exceptionId; -- (void) reportException:(JS::NativeExceptionsManager::ExceptionData &)data; -- (void) updateExceptionMessage:(NSString *)message - stack:(NSArray *)stack - exceptionId:(double)exceptionId; -- (void) dismissRedbox; -@end - - - -namespace JS { - namespace NativeImagePickerIOS { - struct SpecOpenCameraDialogConfig { - bool unmirrorFrontFacingCamera() const; - bool videoMode() const; - - SpecOpenCameraDialogConfig(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } + +inline NSString *JS::NativeExceptionsManager::ExceptionData::originalMessage() const +{ + id const p = _v[@\\"originalMessage\\"]; + return RCTBridgingToString(p); +} + + +inline NSString *JS::NativeExceptionsManager::ExceptionData::name() const +{ + id const p = _v[@\\"name\\"]; + return RCTBridgingToString(p); +} + + +inline NSString *JS::NativeExceptionsManager::ExceptionData::componentStack() const +{ + id const p = _v[@\\"componentStack\\"]; + return RCTBridgingToString(p); +} + + +inline facebook::react::LazyVector JS::NativeExceptionsManager::ExceptionData::stack() const +{ + id const p = _v[@\\"stack\\"]; + return RCTBridgingToVec(p, ^JS::NativeExceptionsManager::StackFrame(id itemValue_0) { return JS::NativeExceptionsManager::StackFrame(p); }); +} + + +inline double JS::NativeExceptionsManager::ExceptionData::id_() const +{ + id const p = _v[@\\"id_\\"]; + return RCTBridgingToDouble(p); +} + + +inline bool JS::NativeExceptionsManager::ExceptionData::isFatal() const +{ + id const p = _v[@\\"isFatal\\"]; + return RCTBridgingToBool(p); +} + + +inline id _Nullable JS::NativeExceptionsManager::ExceptionData::extraData() const +{ + id const p = _v[@\\"extraData\\"]; + return p; } -@interface RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig) -+ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json; -@end inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::unmirrorFrontFacingCamera() const { @@ -1226,40 +928,6 @@ inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::videoMode() co return RCTBridgingToBool(p); } - - -@protocol NativeImagePickerIOSSpec -- (void) openCameraDialog:(JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig &)config - successCallback:(RCTResponseSenderBlock)successCallback - cancelCallback:(RCTResponseSenderBlock)cancelCallback; -@end - - -namespace facebook { - namespace react { - /** - * ObjC++ class for module 'CameraRollManager' - */ - class JSI_EXPORT NativeCameraRollManagerSpecJSI : public ObjCTurboModule { - public: - NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - /** - * ObjC++ class for module 'ExceptionsManager' - */ - class JSI_EXPORT NativeExceptionsManagerSpecJSI : public ObjCTurboModule { - public: - NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - /** - * ObjC++ class for module 'ImagePickerIOS' - */ - class JSI_EXPORT NativeImagePickerIOSSpecJSI : public ObjCTurboModule { - public: - NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - } // namespace react -} // namespace facebook ", } `; @@ -1327,53 +995,53 @@ namespace JS { }; } } - -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 + +- (void)voidFunc; +- (NSNumber *)getBool:(BOOL)arg; +- (NSNumber *)getNumber:(double)arg; +- (NSString *)getString:(NSString *)arg; +- (NSArray *)getArray:(NSArray *)arg; +- (NSDictionary *)getObject:(NSDictionary *)arg; +- (NSNumber *)getRootTag:(double)arg; +- (NSDictionary *)getValue:(double)x + y:(NSString *)y + z:(NSDictionary *)z; +- (void)getValueWithCallback:(RCTResponseSenderBlock)callback; +- (void)getValueWithPromise:(BOOL)error + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject; - (facebook::react::ModuleConstants)constantsToExport; - (facebook::react::ModuleConstants)getConstants; -- (void) voidFunc; -- (BOOL) getBool:(BOOL)arg; -- (NSNumber *) getNumber:(double)arg; -- (NSString *) getString:(NSString *)arg; -- (NSArray> *) getArray:(NSArray *)arg; -- (NSDictionary *) getObject:(NSDictionary *)arg; -- (NSNumber *) getRootTag:(double)arg; -- (NSDictionary *) getValue:(double)x - y:(NSString *)y - z:(NSDictionary *)z; -- (void) getValueWithCallback:(RCTResponseSenderBlock)callback; -- (void) getValueWithPromise:(BOOL)error - resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject; + @end - - namespace facebook { namespace react { /** - * ObjC++ class for module 'SampleTurboModule' - */ + * ObjC++ class for module 'SampleTurboModule' + */ class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { public: NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; } // namespace react } // namespace facebook + + + +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(); +}) {} ", } `; @@ -1412,40 +1080,45 @@ Map { - - @protocol NativeSample2TurboModuleSpec -- (void) voidFunc; +- (void)voidFunc; + @end - - - - - -@protocol NativeSampleTurboModuleSpec -- (void) voidFunc; -@end - - namespace facebook { namespace react { /** - * ObjC++ class for module 'SampleTurboModule' - */ - class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { - public: - NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - /** - * ObjC++ class for module 'Sample2TurboModule' - */ + * ObjC++ class for module 'Sample2TurboModule' + */ class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule { public: NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; } // namespace react } // namespace facebook + + + +@protocol NativeSampleTurboModuleSpec + +- (void)voidFunc; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'SampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + + ", } `; @@ -1484,39 +1157,45 @@ Map { - - @protocol NativeSample2TurboModuleSpec -- (void) voidFunc; + +- (void)voidFunc; + @end - - - - - -@protocol NativeSampleTurboModuleSpec -- (void) voidFunc; -@end - - namespace facebook { namespace react { /** - * ObjC++ class for module 'SampleTurboModule' - */ - class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { - public: - NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); - }; - /** - * ObjC++ class for module 'Sample2TurboModule' - */ + * ObjC++ class for module 'Sample2TurboModule' + */ class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule { public: NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); }; } // namespace react } // namespace facebook + + + +@protocol NativeSampleTurboModuleSpec + +- (void)voidFunc; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'SampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react +} // namespace facebook + + + + ", } `; 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 192e19235d1..1d9e6034f4b 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 @@ -9,17 +9,21 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" -@implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultReturnType) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultReturnType:(id)json + +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultAE) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultAE:(id)json { - return facebook::react::managedPointer(json); + return facebook::react::managedPointer(json); } @end @@ -32,6 +36,14 @@ Map { @end +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + @implementation RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsA) + (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsA:(id)json { @@ -40,6 +52,14 @@ Map { @end +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecGetArraysOptionsArrayOfObjectsElement) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetArraysOptionsArrayOfObjectsElement:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + @implementation RCTCxxConvert (NativeSampleTurboModule_SpecGetArraysOptions) + (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecGetArraysOptions:(id)json { @@ -47,57 +67,52 @@ Map { } @end - -@implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultAE) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultAE:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty:(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); + + 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); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_optionals(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"optionals\\", @selector(optionals:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::optionals(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"optionals\\", @selector(optionals:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"optionalMethod\\", @selector(optionalMethod:callback:extras:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::optionalMethod(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"optionalMethod\\", @selector(optionalMethod:callback:extras:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getArrays(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"getArrays\\", @selector(getArrays:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getArrays(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getArrays\\", @selector(getArrays:), args, count); } + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"difficult\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_difficult}; - methodMap_[\\"optionals\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_optionals}; - methodMap_[\\"optionalMethod\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod}; - methodMap_[\\"getArrays\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArrays}; - setMethodArgConversionSelector(@\\"difficult\\", 0, @\\"JS_NativeSampleTurboModule_SpecDifficultA:\\"); - setMethodArgConversionSelector(@\\"optionals\\", 0, @\\"JS_NativeSampleTurboModule_SpecOptionalsA:\\"); - setMethodArgConversionSelector(@\\"getArrays\\", 0, @\\"JS_NativeSampleTurboModule_SpecGetArraysOptions:\\"); + + methodMap_[\\"difficult\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_difficult}; + setMethodArgConversionSelector(@\\"difficult\\", 0, @\\"JS_NativeSampleTurboModule_SpecDifficultA:\\"); + + + methodMap_[\\"optionals\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_optionals}; + setMethodArgConversionSelector(@\\"optionals\\", 0, @\\"JS_NativeSampleTurboModule_SpecOptionalsA:\\"); + + + methodMap_[\\"optionalMethod\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod}; + + + + methodMap_[\\"getArrays\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArrays}; + setMethodArgConversionSelector(@\\"getArrays\\", 0, @\\"JS_NativeSampleTurboModule_SpecGetArraysOptions:\\"); + + } } } // namespace react } // namespace facebook + ", } `; @@ -111,23 +126,29 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" + namespace facebook { namespace react { - + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - + + } } } // namespace react } // namespace facebook + ", } `; @@ -141,20 +162,16 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" -@implementation RCTCxxConvert (NativeAliasTurboModule_Options) -+ (RCTManagedPointer *)JS_NativeAliasTurboModule_Options:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - @implementation RCTCxxConvert (NativeAliasTurboModule_OptionsOffset) + (RCTManagedPointer *)JS_NativeAliasTurboModule_OptionsOffset:(id)json @@ -179,23 +196,33 @@ Map { } @end + +@implementation RCTCxxConvert (NativeAliasTurboModule_Options) ++ (RCTManagedPointer *)JS_NativeAliasTurboModule_Options:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + namespace facebook { namespace react { - - - static facebook::jsi::Value __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"cropImage\\", @selector(cropImage:), args, count); + + static facebook::jsi::Value __hostFunction_NativeAliasTurboModuleSpecJSI::cropImage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"cropImage\\", @selector(cropImage:), args, count); } + NativeAliasTurboModuleSpecJSI::NativeAliasTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - - methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage}; - setMethodArgConversionSelector(@\\"cropImage\\", 0, @\\"JS_NativeAliasTurboModule_Options:\\"); + + methodMap_[\\"cropImage\\"] = MethodMetadata {1, __hostFunction_NativeAliasTurboModuleSpecJSI_cropImage}; + setMethodArgConversionSelector(@\\"cropImage\\", 0, @\\"JS_NativeAliasTurboModule_SpecCropImageCropData:\\"); + + } } } // namespace react } // namespace facebook + ", } `; @@ -209,36 +236,16 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierImage) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierImage:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifier) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifier:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - - -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPage) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json -{ - return facebook::react::managedPointer(json); -} -@end - @implementation RCTCxxConvert (NativeCameraRollManager_GetPhotosParams) + (RCTManagedPointer *)JS_NativeCameraRollManager_GetPhotosParams:(id)json @@ -247,37 +254,43 @@ Map { } @end - -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNode) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNode:(id)json -{ - return facebook::react::managedPointer(json); -} -@end +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI::getPhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getPhotos\\", @selector(getPhotos:resolve:reject:), args, count); + } -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifiersPagePage_info) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPagePage_info:(id)json -{ - return facebook::react::managedPointer(json); -} -@end + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI::saveToCameraRoll(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"saveToCameraRoll\\", @selector(saveToCameraRoll:type:resolve:reject:), args, count); + } -@implementation RCTCxxConvert (NativeCameraRollManager_PhotoIdentifierNodeLocation) -+ (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifierNodeLocation:(id)json -{ - return facebook::react::managedPointer(json); -} -@end + static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI::deletePhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"deletePhotos\\", @selector(deletePhotos:resolve:reject:), args, count); + } -@implementation RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig) -+ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json -{ - return facebook::react::managedPointer(json); -} -@end + NativeCameraRollManagerSpecJSI::NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"getPhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos}; + setMethodArgConversionSelector(@\\"getPhotos\\", 0, @\\"JS_NativeCameraRollManager_SpecGetPhotosParams:\\"); + + + methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll}; + + + + methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos}; + + + } + } + } // namespace react +} // namespace facebook + @implementation RCTCxxConvert (NativeExceptionsManager_StackFrame) @@ -297,79 +310,87 @@ Map { namespace facebook { namespace react { - - - static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, PromiseKind, \\"getPhotos\\", @selector(getPhotos:resolve:reject:), args, count); - } - - static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, PromiseKind, \\"saveToCameraRoll\\", @selector(saveToCameraRoll:type:resolve:reject:), args, count); - } - - static facebook::jsi::Value __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, PromiseKind, \\"deletePhotos\\", @selector(deletePhotos:resolve:reject:), args, count); - } - - NativeCameraRollManagerSpecJSI::NativeCameraRollManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - methodMap_[\\"getPhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos}; - methodMap_[\\"saveToCameraRoll\\"] = MethodMetadata {2, __hostFunction_NativeCameraRollManagerSpecJSI_saveToCameraRoll}; - methodMap_[\\"deletePhotos\\"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_deletePhotos}; - setMethodArgConversionSelector(@\\"getPhotos\\", 0, @\\"JS_NativeCameraRollManager_GetPhotosParams:\\"); + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::reportFatalException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"reportFatalException\\", @selector(reportFatalException:stack:exceptionId:), args, count); } - static facebook::jsi::Value __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"openCameraDialog\\", @selector(openCameraDialog:successCallback:cancelCallback:), args, count); + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::reportSoftException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"reportSoftException\\", @selector(reportSoftException:stack:exceptionId:), args, count); } - NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - methodMap_[\\"openCameraDialog\\"] = MethodMetadata {3, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog}; - setMethodArgConversionSelector(@\\"openCameraDialog\\", 0, @\\"JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:\\"); + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::reportException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"reportException\\", @selector(reportException:), args, count); } - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"reportFatalException\\", @selector(reportFatalException:stack:exceptionId:), args, count); + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::updateExceptionMessage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"updateExceptionMessage\\", @selector(updateExceptionMessage:stack:exceptionId:), args, count); } - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"reportSoftException\\", @selector(reportSoftException:stack:exceptionId:), args, count); + + static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI::dismissRedbox(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"dismissRedbox\\", @selector(dismissRedbox), args, count); } - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_reportException(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"reportException\\", @selector(reportException:), args, count); - } - - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"updateExceptionMessage\\", @selector(updateExceptionMessage:stack:exceptionId:), args, count); - } - - static facebook::jsi::Value __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"dismissRedbox\\", @selector(dismissRedbox), args, count); - } NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"reportFatalException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException}; - methodMap_[\\"reportSoftException\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException}; - methodMap_[\\"reportException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportException}; - methodMap_[\\"updateExceptionMessage\\"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage}; - methodMap_[\\"dismissRedbox\\"] = MethodMetadata {0, __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox}; - setMethodArgConversionSelector(@\\"reportException\\", 0, @\\"JS_NativeExceptionsManager_ExceptionData:\\"); + + methodMap_[\\"reportFatalException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException}; + + + + methodMap_[\\"reportSoftException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportSoftException}; + + + + methodMap_[\\"reportException\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_reportException}; + setMethodArgConversionSelector(@\\"reportException\\", 0, @\\"JS_NativeExceptionsManager_SpecReportExceptionData:\\"); + + + methodMap_[\\"updateExceptionMessage\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_updateExceptionMessage}; + + + + methodMap_[\\"dismissRedbox\\"] = MethodMetadata {1, __hostFunction_NativeExceptionsManagerSpecJSI_dismissRedbox}; + + + } } } // namespace react } // namespace facebook + + + +@implementation RCTCxxConvert (NativeImagePickerIOS_SpecOpenCameraDialogConfig) ++ (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeImagePickerIOSSpecJSI::openCameraDialog(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"openCameraDialog\\", @selector(openCameraDialog:successCallback:cancelCallback:), args, count); + } + + + NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"openCameraDialog\\"] = MethodMetadata {1, __hostFunction_NativeImagePickerIOSSpecJSI_openCameraDialog}; + setMethodArgConversionSelector(@\\"openCameraDialog\\", 0, @\\"JS_NativeImagePickerIOS_SpecOpenCameraDialogConfig:\\"); + + } + } + } // namespace react +} // namespace facebook + ", } `; @@ -383,87 +404,142 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" + +@implementation RCTCxxConvert (NativeSampleTurboModule_Constants) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_Constants:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + namespace facebook { namespace react { - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getBool\\", @selector(getBool:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, BooleanKind, \\"getBool\\", @selector(getBool:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); } - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); } + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", getConstants, args, count); + } + + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; - methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getBool}; - methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber}; - methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getString}; - methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArray}; - methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObject}; - methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag}; - methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; - methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback}; - methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise}; + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + + + + methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getBool}; + + + + methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber}; + + + + methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getString}; + + + + methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArray}; + + + + methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObject}; + + + + methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag}; + + + + methodMap_[\\"getValue\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; + + + + methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback}; + + + + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; + + + + methodMap_[\\"getConstants\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; + + + } } } // namespace react } // namespace facebook + ", } `; @@ -477,40 +553,57 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" namespace facebook { namespace react { - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + + static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; - } - - - static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); - } NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + + + } } } // namespace react } // namespace facebook + + + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + } + + + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + + + } + } + } // namespace react +} // namespace facebook + ", } `; @@ -524,38 +617,57 @@ Map { * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated by codegen project: GenerateModuleMm.js + * @generated by an internal genrule from Flow types. + * + * We create an umbrella header (and corresponding implementation) here since + * Cxx compilation in BUCK has a limitation: source-code producing genrule()s + * must have a single output. More files => more genrule()s => slower builds. */ -#include -#import +#import \\"SampleSpec.h\\" namespace facebook { namespace react { - - static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + + static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); } - NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; - } - - static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); - } NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + + + } } } // namespace react } // namespace facebook + + + +namespace facebook { + namespace react { + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI::voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + } + + + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"voidFunc\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + + + } + } + } // namespace react +} // namespace facebook + ", } `; 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 deleted file mode 100644 index 75bb7bfe5db..00000000000 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateStructs-test.js.snap +++ /dev/null @@ -1,284 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`GenerateStructs can generate fixture SIMPLE_CONSTANTS 1`] = ` -" - -namespace JS { - namespace NativeSampleTurboModule { - struct ConstantsDG { - - struct Builder { - struct Input { - RCTRequired h; - RCTRequired i; - RCTRequired j; - }; - - /** Initialize with a set of values */ - Builder(const Input i); - /** Initialize with an existing ConstantsDG */ - Builder(ConstantsDG i); - /** Builds the object. Generally used only by the infrastructure. */ - NSDictionary *buildUnsafeRawValue() const { return _factory(); }; - private: - NSDictionary *(^_factory)(void); - }; - - static ConstantsDG fromUnsafeRawValue(NSDictionary *const v) { return {v}; } - NSDictionary *unsafeRawValue() const { return _v; } - private: - ConstantsDG(NSDictionary *const v) : _v(v) {} - NSDictionary *_v; - }; - } -} - -inline JS::NativeSampleTurboModule::ConstantsDG::Builder::Builder(const Input i) : _factory(^{ - NSMutableDictionary *d = [NSMutableDictionary new]; - auto h = i.h.get(); - d[@\\"h\\"] = @(h); -auto i = i.i.get(); - d[@\\"i\\"] = @(i); -auto j = i.j.get(); - d[@\\"j\\"] = j; - return d; -}) {} -inline JS::NativeSampleTurboModule::ConstantsDG::Builder::Builder(ConstantsDG 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; - }; - } -} - -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; - RCTRequired k; - }; - - /** 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(); -auto k = i.k.get(); - d[@\\"k\\"] = @(k); - return d; -}) {} -inline JS::NativeSampleTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{ - return i.unsafeRawValue(); -}) {} -" -`; - -exports[`GenerateStructs can generate fixture SIMPLE_STRUCT 1`] = ` -" - -namespace JS { - namespace NativeSampleTurboModule { - struct SpecSampleFuncReturnTypeDG { - bool h() const; - double i() const; - NSString *j() const; - - SpecSampleFuncReturnTypeDG(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeSampleTurboModule_SpecSampleFuncReturnTypeDG) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecSampleFuncReturnTypeDG:(id)json; -@end - - -namespace JS { - namespace NativeSampleTurboModule { - struct SpecSampleFuncReturnTypeD { - bool e() const; - double f() const; - JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG g() const; - - SpecSampleFuncReturnTypeD(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeSampleTurboModule_SpecSampleFuncReturnTypeD) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecSampleFuncReturnTypeD:(id)json; -@end - - -namespace JS { - namespace NativeSampleTurboModule { - struct SpecSampleFuncReturnType { - bool a() const; - double b() const; - NSString *c() const; - JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD d() const; - double k() const; - - SpecSampleFuncReturnType(NSDictionary *const v) : _v(v) {} - private: - NSDictionary *_v; - }; - } -} - -@interface RCTCxxConvert (NativeSampleTurboModule_SpecSampleFuncReturnType) -+ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecSampleFuncReturnType:(id)json; -@end - -inline bool JS::NativeSampleTurboModule::SpecSampleFuncReturnType::a() const -{ - id const p = _v[@\\"a\\"]; - return RCTBridgingToBool(p); -} - - -inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnType::b() const -{ - id const p = _v[@\\"b\\"]; - return RCTBridgingToDouble(p); -} - - -inline NSString *JS::NativeSampleTurboModule::SpecSampleFuncReturnType::c() const -{ - id const p = _v[@\\"c\\"]; - return RCTBridgingToString(p); -} - - -inline JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD JS::NativeSampleTurboModule::SpecSampleFuncReturnType::d() const -{ - id const p = _v[@\\"d\\"]; - return JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD(p); -} - - -inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnType::k() const -{ - id const p = _v[@\\"k\\"]; - return RCTBridgingToDouble(p); -} - - -inline bool JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::e() const -{ - id const p = _v[@\\"e\\"]; - return RCTBridgingToBool(p); -} - - -inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::f() const -{ - id const p = _v[@\\"f\\"]; - return RCTBridgingToDouble(p); -} - - -inline JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeD::g() const -{ - id const p = _v[@\\"g\\"]; - return JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG(p); -} - - -inline bool JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG::h() const -{ - id const p = _v[@\\"h\\"]; - return RCTBridgingToBool(p); -} - - -inline double JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG::i() const -{ - id const p = _v[@\\"i\\"]; - return RCTBridgingToDouble(p); -} - - -inline NSString *JS::NativeSampleTurboModule::SpecSampleFuncReturnTypeDG::j() const -{ - id const p = _v[@\\"j\\"]; - return RCTBridgingToString(p); -} - -" -`;