From c0a06d2e6f7e1009366e8159589a1a8ce9ed9938 Mon Sep 17 00:00:00 2001 From: Christoph Purrer Date: Wed, 9 Nov 2022 13:23:05 -0800 Subject: [PATCH] react-native code-gen > C++ TurboModules struct support (#35265) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35265 This adds a templating layer for C++ TurboModules to automatically generate struct templates from TurboModule specs. You have to define concrete types for those templates to use them in your C++ TurboModule. E.g. for the JS flow type: ``` export type ObjectStruct = {| a: number, b: string, c?: ?string, |}; ``` code-gen will now generate the following template code: ``` #pragma mark - NativeCxxModuleExampleCxxBaseObjectStruct template struct NativeCxxModuleExampleCxxBaseObjectStruct { P0 a; P1 b; P2 c; bool operator==(const NativeCxxModuleExampleCxxBaseObjectStruct &other) const { return a == other.a && b == other.b && c == other.c; } }; template struct NativeCxxModuleExampleCxxBaseObjectStructBridging { static NativeCxxModuleExampleCxxBaseObjectStruct fromJs( jsi::Runtime &rt, const jsi::Object &value, const std::shared_ptr &jsInvoker) { NativeCxxModuleExampleCxxBaseObjectStruct result{ bridging::fromJs(rt, value.getProperty(rt, "a"), jsInvoker), bridging::fromJs(rt, value.getProperty(rt, "b"), jsInvoker), bridging::fromJs(rt, value.getProperty(rt, "c"), jsInvoker)}; return result; } static jsi::Object toJs( jsi::Runtime &rt, const NativeCxxModuleExampleCxxBaseObjectStruct &value) { auto result = facebook::jsi::Object(rt); result.setProperty(rt, "a", bridging::toJs(rt, value.a)); result.setProperty(rt, "b", bridging::toJs(rt, value.b)); if (value.c) { result.setProperty(rt, "c", bridging::toJs(rt, value.c.value())); } return result; } }; ``` and you can use it in our C++ TurboModule for example as: ``` using ObjectStruct = NativeCxxModuleExampleCxxBaseObjectStruct< int32_t, std::string, std::optional>; template <> struct Bridging : NativeCxxModuleExampleCxxBaseObjectStructBridging< int32_t, std::string, std::optional> {}; ``` or as ``` using ObjectStruct = NativeCxxModuleExampleCxxBaseObjectStruct< float, folly::StringPiece, std::optional>; template <> struct Bridging : NativeCxxModuleExampleCxxBaseObjectStructBridging< float, folly::StringPiece, std::optional> {}; ``` Or as ... Changelog: [Internal] Reviewed By: rshest Differential Revision: D41133761 fbshipit-source-id: fdf36e51073cb46c5234f6121842c79a884899c7 --- .../NativePerformanceObserver.h | 26 +- .../NativePerformanceObserver.js | 4 +- ...ePerformanceObserver_RawPerformanceEntry.h | 76 ---- .../src/generators/modules/GenerateModuleH.js | 82 +++- .../GenerateModuleH-test.js.snap | 353 ++++++++++++++++++ .../NativeCxxModuleExample.h | 36 +- .../NativeCxxModuleExample_ConstantsStruct.h | 37 -- .../NativeCxxModuleExample_ObjectStruct.h | 52 --- .../NativeCxxModuleExample_ValueStruct.h | 50 --- 9 files changed, 493 insertions(+), 223 deletions(-) delete mode 100644 Libraries/WebPerformance/NativePerformanceObserver_RawPerformanceEntry.h delete mode 100644 packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ConstantsStruct.h delete mode 100644 packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ObjectStruct.h delete mode 100644 packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ValueStruct.h diff --git a/Libraries/WebPerformance/NativePerformanceObserver.h b/Libraries/WebPerformance/NativePerformanceObserver.h index 9bd015d572ebf7..3a3250dcbcc6e7 100644 --- a/Libraries/WebPerformance/NativePerformanceObserver.h +++ b/Libraries/WebPerformance/NativePerformanceObserver.h @@ -13,10 +13,34 @@ #include #include #include -#include "NativePerformanceObserver_RawPerformanceEntry.h" namespace facebook::react { +#pragma mark - Structs + +using RawPerformanceEntry = NativePerformanceObserverCxxBaseRawPerformanceEntry< + std::string, + int32_t, + double, + double, + // For "event" entries only: + std::optional, + std::optional, + std::optional>; + +template <> +struct Bridging + : NativePerformanceObserverCxxBaseRawPerformanceEntryBridging< + std::string, + int32_t, + double, + double, + std::optional, + std::optional, + std::optional> {}; + +#pragma mark - implementation + class NativePerformanceObserver : public NativePerformanceObserverCxxSpec, std::enable_shared_from_this { diff --git a/Libraries/WebPerformance/NativePerformanceObserver.js b/Libraries/WebPerformance/NativePerformanceObserver.js index 78b86b099aea4c..b3d6fdefc8b7f7 100644 --- a/Libraries/WebPerformance/NativePerformanceObserver.js +++ b/Libraries/WebPerformance/NativePerformanceObserver.js @@ -18,7 +18,7 @@ export const RawPerformanceEntryTypeValues = { export type RawPerformanceEntryType = number; -export type RawPerformanceEntry = $ReadOnly<{ +export type RawPerformanceEntry = {| name: string, entryType: RawPerformanceEntryType, startTime: number, @@ -27,7 +27,7 @@ export type RawPerformanceEntry = $ReadOnly<{ processingStart?: number, processingEnd?: number, interactionId?: number, -}>; +|}; export interface Spec extends TurboModule { +startReporting: (entryType: string) => void; diff --git a/Libraries/WebPerformance/NativePerformanceObserver_RawPerformanceEntry.h b/Libraries/WebPerformance/NativePerformanceObserver_RawPerformanceEntry.h deleted file mode 100644 index 1469bf196e3156..00000000000000 --- a/Libraries/WebPerformance/NativePerformanceObserver_RawPerformanceEntry.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include - -namespace facebook::react { - -struct RawPerformanceEntry { - std::string name; - int32_t entryType; - double startTime; - double duration; - // For "event" entries only: - std::optional processingStart; - std::optional processingEnd; - std::optional interactionId; -}; - -template <> -struct Bridging { - static RawPerformanceEntry fromJs( - jsi::Runtime &rt, - const jsi::Object &value, - const std::shared_ptr &jsInvoker) { - RawPerformanceEntry result{ - bridging::fromJs( - rt, value.getProperty(rt, "name"), jsInvoker), - bridging::fromJs( - rt, value.getProperty(rt, "entryType"), jsInvoker), - bridging::fromJs( - rt, value.getProperty(rt, "startTime"), jsInvoker), - bridging::fromJs( - rt, value.getProperty(rt, "duration"), jsInvoker), - bridging::fromJs>( - rt, value.getProperty(rt, "processingStart"), jsInvoker), - bridging::fromJs>( - rt, value.getProperty(rt, "processingEnd"), jsInvoker), - bridging::fromJs>( - rt, value.getProperty(rt, "interactionId"), jsInvoker), - }; - return result; - } - - static jsi::Object toJs(jsi::Runtime &rt, const RawPerformanceEntry &value) { - auto result = facebook::jsi::Object(rt); - result.setProperty(rt, "name", bridging::toJs(rt, value.name)); - result.setProperty(rt, "entryType", bridging::toJs(rt, value.entryType)); - result.setProperty(rt, "startTime", bridging::toJs(rt, value.startTime)); - result.setProperty(rt, "duration", bridging::toJs(rt, value.duration)); - if (value.processingStart) { - result.setProperty( - rt, - "processingStart", - bridging::toJs(rt, value.processingStart.value())); - } - if (value.processingEnd) { - result.setProperty( - rt, "processingEnd", bridging::toJs(rt, value.processingEnd.value())); - } - if (value.interactionId) { - result.setProperty( - rt, "interactionId", bridging::toJs(rt, value.interactionId.value())); - } - return result; - } -}; - -} // namespace facebook::react diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js index 865f60b63f30c9..7076ab94131171 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js @@ -16,6 +16,7 @@ import type { NativeModuleTypeAnnotation, NativeModuleFunctionTypeAnnotation, NativeModulePropertyShape, + NativeModuleAliasMap, } from '../../CodegenSchema'; import type {AliasResolver} from './Utils'; @@ -28,8 +29,13 @@ type FilesOutput = Map; const ModuleClassDeclarationTemplate = ({ hasteModuleName, moduleProperties, -}: $ReadOnly<{hasteModuleName: string, moduleProperties: string[]}>) => { - return `class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule { + structs, +}: $ReadOnly<{ + hasteModuleName: string, + moduleProperties: string[], + structs: string, +}>) => { + return `${structs}class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule { protected: ${hasteModuleName}CxxSpecJSI(std::shared_ptr jsInvoker); @@ -186,6 +192,76 @@ function translatePrimitiveJSTypeToCpp( } } +function createStructs( + moduleName: string, + aliasMap: NativeModuleAliasMap, + resolveAlias: AliasResolver, +): string { + return Object.keys(aliasMap) + .map(alias => { + const value = aliasMap[alias]; + if (value.properties.length === 0) { + return ''; + } + const structName = `${moduleName}Base${alias}`; + const templateParameterWithTypename = value.properties + .map((v, i) => 'typename P' + i) + .join(', '); + const templateParameter = value.properties + .map((v, i) => 'P' + i) + .join(', '); + return `#pragma mark - ${structName} + +template <${templateParameterWithTypename}> +struct ${structName} { +${value.properties.map((v, i) => ' P' + i + ' ' + v.name).join(';\n')}; + bool operator==(const ${structName} &other) const { + return ${value.properties + .map(v => `${v.name} == other.${v.name}`) + .join(' && ')}; + } +}; + +template <${templateParameterWithTypename}> +struct ${structName}Bridging { + static ${structName}<${templateParameter}> fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + ${structName}<${templateParameter}> result{ +${value.properties + .map( + (v, i) => + ` bridging::fromJs(rt, value.getProperty(rt, "${v.name}"), jsInvoker)`, + ) + .join(',\n')}}; + return result; + } + + static jsi::Object toJs( + jsi::Runtime &rt, + const ${structName}<${templateParameter}> &value) { + auto result = facebook::jsi::Object(rt); +${value.properties + .map((v, i) => { + if (v.optional) { + return ` if (value.${v.name}) { + result.setProperty(rt, "${v.name}", bridging::toJs(rt, value.${v.name}.value())); + }`; + } else { + return ` result.setProperty(rt, "${v.name}", bridging::toJs(rt, value.${v.name}));`; + } + }) + .join('\n')} + return result; + } +}; + +`; + }) + .join('\n'); +} + function translatePropertyToCpp( prop: NativeModulePropertyShape, resolveAlias: AliasResolver, @@ -251,6 +327,7 @@ module.exports = { moduleNames: [moduleName], } = nativeModules[hasteModuleName]; const resolveAlias = createAliasResolver(aliases); + const structs = createStructs(moduleName, aliases, resolveAlias); return [ ModuleClassDeclarationTemplate({ @@ -258,6 +335,7 @@ module.exports = { moduleProperties: properties.map(prop => translatePropertyToCpp(prop, resolveAlias, true), ), + structs, }), ModuleSpecClassDeclarationTemplate({ hasteModuleName, diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap index 2e7955758b4d4e..679072d878ebe3 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap @@ -202,6 +202,36 @@ Map { namespace facebook { namespace react { +#pragma mark - SampleTurboModuleCxxBaseObjectAlias + +template +struct SampleTurboModuleCxxBaseObjectAlias { + P0 x; + bool operator==(const SampleTurboModuleCxxBaseObjectAlias &other) const { + return x == other.x; + } +}; + +template +struct SampleTurboModuleCxxBaseObjectAliasBridging { + static SampleTurboModuleCxxBaseObjectAlias fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + SampleTurboModuleCxxBaseObjectAlias result{ + bridging::fromJs(rt, value.getProperty(rt, \\"x\\"), jsInvoker)}; + return result; + } + + static jsi::Object toJs( + jsi::Runtime &rt, + const SampleTurboModuleCxxBaseObjectAlias &value) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, \\"x\\", bridging::toJs(rt, value.x)); + return result; + } +}; + class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { protected: NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -358,6 +388,54 @@ Map { namespace facebook { namespace react { +#pragma mark - AliasTurboModuleBaseOptions + +template +struct AliasTurboModuleBaseOptions { + P0 offset; + P1 size; + P2 displaySize; + P3 resizeMode; + P4 allowExternalStorage; + bool operator==(const AliasTurboModuleBaseOptions &other) const { + return offset == other.offset && size == other.size && displaySize == other.displaySize && resizeMode == other.resizeMode && allowExternalStorage == other.allowExternalStorage; + } +}; + +template +struct AliasTurboModuleBaseOptionsBridging { + static AliasTurboModuleBaseOptions fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + AliasTurboModuleBaseOptions result{ + bridging::fromJs(rt, value.getProperty(rt, \\"offset\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"size\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"displaySize\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"resizeMode\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"allowExternalStorage\\"), jsInvoker)}; + return result; + } + + static jsi::Object toJs( + jsi::Runtime &rt, + const AliasTurboModuleBaseOptions &value) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, \\"offset\\", bridging::toJs(rt, value.offset)); + result.setProperty(rt, \\"size\\", bridging::toJs(rt, value.size)); + if (value.displaySize) { + result.setProperty(rt, \\"displaySize\\", bridging::toJs(rt, value.displaySize.value())); + } + if (value.resizeMode) { + result.setProperty(rt, \\"resizeMode\\", bridging::toJs(rt, value.resizeMode.value())); + } + if (value.allowExternalStorage) { + result.setProperty(rt, \\"allowExternalStorage\\", bridging::toJs(rt, value.allowExternalStorage.value())); + } + return result; + } +}; + class JSI_EXPORT AliasTurboModuleCxxSpecJSI : public TurboModule { protected: AliasTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -435,6 +513,179 @@ Map { namespace facebook { namespace react { +#pragma mark - CameraRollManagerBasePhotoIdentifierImage + +template +struct CameraRollManagerBasePhotoIdentifierImage { + P0 uri; + P1 playableDuration; + P2 width; + P3 height; + P4 isStored; + P5 filename; + bool operator==(const CameraRollManagerBasePhotoIdentifierImage &other) const { + return uri == other.uri && playableDuration == other.playableDuration && width == other.width && height == other.height && isStored == other.isStored && filename == other.filename; + } +}; + +template +struct CameraRollManagerBasePhotoIdentifierImageBridging { + static CameraRollManagerBasePhotoIdentifierImage fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + CameraRollManagerBasePhotoIdentifierImage result{ + bridging::fromJs(rt, value.getProperty(rt, \\"uri\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"playableDuration\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"width\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"height\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"isStored\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"filename\\"), jsInvoker)}; + return result; + } + + static jsi::Object toJs( + jsi::Runtime &rt, + const CameraRollManagerBasePhotoIdentifierImage &value) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, \\"uri\\", bridging::toJs(rt, value.uri)); + result.setProperty(rt, \\"playableDuration\\", bridging::toJs(rt, value.playableDuration)); + result.setProperty(rt, \\"width\\", bridging::toJs(rt, value.width)); + result.setProperty(rt, \\"height\\", bridging::toJs(rt, value.height)); + if (value.isStored) { + result.setProperty(rt, \\"isStored\\", bridging::toJs(rt, value.isStored.value())); + } + result.setProperty(rt, \\"filename\\", bridging::toJs(rt, value.filename)); + return result; + } +}; + + +#pragma mark - CameraRollManagerBasePhotoIdentifier + +template +struct CameraRollManagerBasePhotoIdentifier { + P0 node; + bool operator==(const CameraRollManagerBasePhotoIdentifier &other) const { + return node == other.node; + } +}; + +template +struct CameraRollManagerBasePhotoIdentifierBridging { + static CameraRollManagerBasePhotoIdentifier fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + CameraRollManagerBasePhotoIdentifier result{ + bridging::fromJs(rt, value.getProperty(rt, \\"node\\"), jsInvoker)}; + return result; + } + + static jsi::Object toJs( + jsi::Runtime &rt, + const CameraRollManagerBasePhotoIdentifier &value) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, \\"node\\", bridging::toJs(rt, value.node)); + return result; + } +}; + + +#pragma mark - CameraRollManagerBasePhotoIdentifiersPage + +template +struct CameraRollManagerBasePhotoIdentifiersPage { + P0 edges; + P1 page_info; + bool operator==(const CameraRollManagerBasePhotoIdentifiersPage &other) const { + return edges == other.edges && page_info == other.page_info; + } +}; + +template +struct CameraRollManagerBasePhotoIdentifiersPageBridging { + static CameraRollManagerBasePhotoIdentifiersPage fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + CameraRollManagerBasePhotoIdentifiersPage result{ + bridging::fromJs(rt, value.getProperty(rt, \\"edges\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"page_info\\"), jsInvoker)}; + return result; + } + + static jsi::Object toJs( + jsi::Runtime &rt, + const CameraRollManagerBasePhotoIdentifiersPage &value) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, \\"edges\\", bridging::toJs(rt, value.edges)); + result.setProperty(rt, \\"page_info\\", bridging::toJs(rt, value.page_info)); + return result; + } +}; + + +#pragma mark - CameraRollManagerBaseGetPhotosParams + +template +struct CameraRollManagerBaseGetPhotosParams { + P0 first; + P1 after; + P2 groupName; + P3 groupTypes; + P4 assetType; + P5 maxSize; + P6 mimeTypes; + bool operator==(const CameraRollManagerBaseGetPhotosParams &other) const { + return first == other.first && after == other.after && groupName == other.groupName && groupTypes == other.groupTypes && assetType == other.assetType && maxSize == other.maxSize && mimeTypes == other.mimeTypes; + } +}; + +template +struct CameraRollManagerBaseGetPhotosParamsBridging { + static CameraRollManagerBaseGetPhotosParams fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + CameraRollManagerBaseGetPhotosParams result{ + bridging::fromJs(rt, value.getProperty(rt, \\"first\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"after\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"groupName\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"groupTypes\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"assetType\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"maxSize\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"mimeTypes\\"), jsInvoker)}; + return result; + } + + static jsi::Object toJs( + jsi::Runtime &rt, + const CameraRollManagerBaseGetPhotosParams &value) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, \\"first\\", bridging::toJs(rt, value.first)); + if (value.after) { + result.setProperty(rt, \\"after\\", bridging::toJs(rt, value.after.value())); + } + if (value.groupName) { + result.setProperty(rt, \\"groupName\\", bridging::toJs(rt, value.groupName.value())); + } + if (value.groupTypes) { + result.setProperty(rt, \\"groupTypes\\", bridging::toJs(rt, value.groupTypes.value())); + } + if (value.assetType) { + result.setProperty(rt, \\"assetType\\", bridging::toJs(rt, value.assetType.value())); + } + if (value.maxSize) { + result.setProperty(rt, \\"maxSize\\", bridging::toJs(rt, value.maxSize.value())); + } + if (value.mimeTypes) { + result.setProperty(rt, \\"mimeTypes\\", bridging::toJs(rt, value.mimeTypes.value())); + } + return result; + } +}; + class JSI_EXPORT NativeCameraRollManagerCxxSpecJSI : public TurboModule { protected: NativeCameraRollManagerCxxSpecJSI(std::shared_ptr jsInvoker); @@ -505,6 +756,108 @@ private: Delegate delegate_; }; +#pragma mark - ExceptionsManagerBaseStackFrame + +template +struct ExceptionsManagerBaseStackFrame { + P0 column; + P1 file; + P2 lineNumber; + P3 methodName; + P4 collapse; + bool operator==(const ExceptionsManagerBaseStackFrame &other) const { + return column == other.column && file == other.file && lineNumber == other.lineNumber && methodName == other.methodName && collapse == other.collapse; + } +}; + +template +struct ExceptionsManagerBaseStackFrameBridging { + static ExceptionsManagerBaseStackFrame fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + ExceptionsManagerBaseStackFrame result{ + bridging::fromJs(rt, value.getProperty(rt, \\"column\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"file\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"lineNumber\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"methodName\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"collapse\\"), jsInvoker)}; + return result; + } + + static jsi::Object toJs( + jsi::Runtime &rt, + const ExceptionsManagerBaseStackFrame &value) { + auto result = facebook::jsi::Object(rt); + if (value.column) { + result.setProperty(rt, \\"column\\", bridging::toJs(rt, value.column.value())); + } + result.setProperty(rt, \\"file\\", bridging::toJs(rt, value.file)); + if (value.lineNumber) { + result.setProperty(rt, \\"lineNumber\\", bridging::toJs(rt, value.lineNumber.value())); + } + result.setProperty(rt, \\"methodName\\", bridging::toJs(rt, value.methodName)); + if (value.collapse) { + result.setProperty(rt, \\"collapse\\", bridging::toJs(rt, value.collapse.value())); + } + return result; + } +}; + + +#pragma mark - ExceptionsManagerBaseExceptionData + +template +struct ExceptionsManagerBaseExceptionData { + P0 message; + P1 originalMessage; + P2 name; + P3 componentStack; + P4 stack; + P5 id; + P6 isFatal; + P7 extraData; + bool operator==(const ExceptionsManagerBaseExceptionData &other) const { + return message == other.message && originalMessage == other.originalMessage && name == other.name && componentStack == other.componentStack && stack == other.stack && id == other.id && isFatal == other.isFatal && extraData == other.extraData; + } +}; + +template +struct ExceptionsManagerBaseExceptionDataBridging { + static ExceptionsManagerBaseExceptionData fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + ExceptionsManagerBaseExceptionData result{ + bridging::fromJs(rt, value.getProperty(rt, \\"message\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"originalMessage\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"name\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"componentStack\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"stack\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"id\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"isFatal\\"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, \\"extraData\\"), jsInvoker)}; + return result; + } + + static jsi::Object toJs( + jsi::Runtime &rt, + const ExceptionsManagerBaseExceptionData &value) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, \\"message\\", bridging::toJs(rt, value.message)); + result.setProperty(rt, \\"originalMessage\\", bridging::toJs(rt, value.originalMessage)); + result.setProperty(rt, \\"name\\", bridging::toJs(rt, value.name)); + result.setProperty(rt, \\"componentStack\\", bridging::toJs(rt, value.componentStack)); + result.setProperty(rt, \\"stack\\", bridging::toJs(rt, value.stack)); + result.setProperty(rt, \\"id\\", bridging::toJs(rt, value.id)); + result.setProperty(rt, \\"isFatal\\", bridging::toJs(rt, value.isFatal)); + if (value.extraData) { + result.setProperty(rt, \\"extraData\\", bridging::toJs(rt, value.extraData.value())); + } + return result; + } +}; + class JSI_EXPORT NativeExceptionsManagerCxxSpecJSI : public TurboModule { protected: NativeExceptionsManagerCxxSpecJSI(std::shared_ptr jsInvoker); diff --git a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h index 467a150199c0da..e968db5848ee2e 100644 --- a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h +++ b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h @@ -18,12 +18,42 @@ #include #include #include -#include "NativeCxxModuleExample_ConstantsStruct.h" -#include "NativeCxxModuleExample_ObjectStruct.h" -#include "NativeCxxModuleExample_ValueStruct.h" namespace facebook::react { +#pragma mark - Structs +using ConstantsStruct = + NativeCxxModuleExampleCxxBaseConstantsStruct; + +template <> +struct Bridging + : NativeCxxModuleExampleCxxBaseConstantsStructBridging< + bool, + int32_t, + std::string> {}; + +using ObjectStruct = NativeCxxModuleExampleCxxBaseObjectStruct< + int32_t, + std::string, + std::optional>; + +template <> +struct Bridging + : NativeCxxModuleExampleCxxBaseObjectStructBridging< + int32_t, + std::string, + std::optional> {}; + +using ValueStruct = + NativeCxxModuleExampleCxxBaseValueStruct; + +template <> +struct Bridging : NativeCxxModuleExampleCxxBaseValueStructBridging< + double, + std::string, + ObjectStruct> {}; + +#pragma mark - implementation class NativeCxxModuleExample : public NativeCxxModuleExampleCxxSpec { public: diff --git a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ConstantsStruct.h b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ConstantsStruct.h deleted file mode 100644 index 4966c69d23551f..00000000000000 --- a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ConstantsStruct.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include - -namespace facebook::react { - -struct ConstantsStruct { - bool const1; - int32_t const2; - std::string const3; - bool operator==(const ConstantsStruct &other) const { - return const1 == other.const1 && const2 == other.const2 && - const3 == other.const3; - } -}; - -template <> -struct Bridging { - static jsi::Object toJs(jsi::Runtime &rt, const ConstantsStruct &value) { - auto result = facebook::jsi::Object(rt); - result.setProperty(rt, "const1", bridging::toJs(rt, value.const1)); - result.setProperty(rt, "const2", bridging::toJs(rt, value.const2)); - result.setProperty(rt, "const3", bridging::toJs(rt, value.const3)); - return result; - } -}; - -} // namespace facebook::react diff --git a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ObjectStruct.h b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ObjectStruct.h deleted file mode 100644 index e430a3cb36f5a0..00000000000000 --- a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ObjectStruct.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include - -namespace facebook::react { - -struct ObjectStruct { - int32_t a; - std::string b; - std::optional c; - bool operator==(const ObjectStruct &other) const { - return a == other.a && b == other.b && c == other.c; - } -}; - -template <> -struct Bridging { - static ObjectStruct fromJs( - jsi::Runtime &rt, - const jsi::Object &value, - const std::shared_ptr &jsInvoker) { - ObjectStruct result{ - bridging::fromJs(rt, value.getProperty(rt, "a"), jsInvoker), - bridging::fromJs( - rt, value.getProperty(rt, "b"), jsInvoker), - bridging::fromJs>( - rt, value.getProperty(rt, "c"), jsInvoker)}; - - return result; - } - - static jsi::Object toJs(jsi::Runtime &rt, const ObjectStruct &value) { - auto result = facebook::jsi::Object(rt); - result.setProperty(rt, "a", bridging::toJs(rt, value.a)); - result.setProperty(rt, "b", bridging::toJs(rt, value.b)); - if (value.c) { - result.setProperty(rt, "c", bridging::toJs(rt, value.c.value())); - } - return result; - } -}; - -} // namespace facebook::react diff --git a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ValueStruct.h b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ValueStruct.h deleted file mode 100644 index 7e44c92113b274..00000000000000 --- a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample_ValueStruct.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include -#include "NativeCxxModuleExample_ObjectStruct.h" - -namespace facebook::react { - -struct ValueStruct { - double x; - std::string y; - ObjectStruct z; - bool operator==(const ValueStruct &other) const { - return x == other.x && y == other.y && z == other.z; - } -}; - -template <> -struct Bridging { - static ValueStruct fromJs( - jsi::Runtime &rt, - const jsi::Object &value, - const std::shared_ptr &jsInvoker) { - ValueStruct result{ - bridging::fromJs(rt, value.getProperty(rt, "x"), jsInvoker), - bridging::fromJs( - rt, value.getProperty(rt, "y"), jsInvoker), - bridging::fromJs( - rt, value.getProperty(rt, "z"), jsInvoker)}; - return result; - } - - static jsi::Object toJs(jsi::Runtime &rt, const ValueStruct &value) { - auto result = facebook::jsi::Object(rt); - result.setProperty(rt, "x", bridging::toJs(rt, value.x)); - result.setProperty(rt, "y", bridging::toJs(rt, value.y)); - result.setProperty(rt, "z", bridging::toJs(rt, value.z)); - return result; - } -}; - -} // namespace facebook::react