From ceb1d0dea694739f357d86296b94f5834e5ee7f7 Mon Sep 17 00:00:00 2001 From: Vitali Zaidman Date: Mon, 13 Feb 2023 15:09:44 -0800 Subject: [PATCH] Generate enum types that would be allowed to be used as well as string/number in c++ turbo modules generators (#36030) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/36030 Generate enum types in c++ turbo modules. For enums in the ts schema file such as: ``` export enum NumEnum { ONE = 1, TWO = 2, } ``` This would export enums and the relevant Bridging to js and from js code to the spec H files such as: ``` #pragma mark - SampleTurboModuleCxxNumEnum enum SampleTurboModuleCxxNumEnum { ONE, TWO }; template <> struct Bridging { static SampleTurboModuleCxxNumEnum fromJs(jsi::Runtime &rt, int32_t value) { if (value == 1) { return SampleTurboModuleCxxNumEnum::ONE; } else if (value == 2) { return SampleTurboModuleCxxNumEnum::TWO; } else { throw jsi::JSError(rt, "No appropriate enum member found for value"); } } static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxNumEnum value) { if (value == SampleTurboModuleCxxNumEnum::ONE) { return bridging::toJs(rt, 1); } else if (value == SampleTurboModuleCxxNumEnum::TWO) { return bridging::toJs(rt, 2); } else { throw jsi::JSError(rt, "No appropriate enum member found for enum value"); } } }; ``` That code would allow us to use these enums in the cxx files like this: ``` NativeCxxModuleExampleCxxEnumInt getNumEnum( jsi::Runtime &rt, NativeCxxModuleExampleCxxEnumInt arg); ``` Changelog: [General] [Added] Generate enum types that would be allowed to be used as well as string/number in c++ turbo modules generators Reviewed By: christophpurrer Differential Revision: D42884147 fbshipit-source-id: d34d1fc7ba268b570821dc108444196f69a431b2 --- .../GenerateModuleH-test.js.snap | 374 +++++++++++++++--- .../src/generators/Utils.js | 20 + .../components/ComponentsGeneratorUtils.js | 3 +- .../src/generators/components/CppHelpers.js | 19 +- .../components/GenerateEventEmitterH.js | 3 +- .../generators/components/GeneratePropsH.js | 4 +- .../generators/components/GenerateTests.js | 4 +- .../generators/modules/GenerateModuleCpp.js | 10 +- .../src/generators/modules/GenerateModuleH.js | 173 +++++++- .../src/generators/modules/Utils.js | 6 + .../modules/__test_fixtures__/fixtures.js | 136 ++++++- .../GenerateModuleCpp-test.js.snap | 8 + .../GenerateModuleH-test.js.snap | 230 ++++++++++- .../GenerateModuleHObjCpp-test.js.snap | 1 + .../GenerateModuleJavaSpec-test.js.snap | 4 + .../GenerateModuleJniCpp-test.js.snap | 6 + .../GenerateModuleMm-test.js.snap | 7 + .../NativeCxxModuleExample.cpp | 16 +- .../NativeCxxModuleExample.h | 22 +- .../NativeCxxModuleExample.js | 23 +- .../NativeCxxModuleExampleExample.js | 10 +- 21 files changed, 973 insertions(+), 106 deletions(-) diff --git a/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleH-test.js.snap b/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleH-test.js.snap index 20b3a737fbee08..541b349dbba853 100644 --- a/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleH-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/modules/__snapshots__/GenerateModuleH-test.js.snap @@ -18,7 +18,8 @@ exports[`GenerateModuleH can generate a header file NativeModule specs 1`] = ` namespace facebook { namespace react { -class JSI_EXPORT NativeArrayTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeArrayTurboModuleCxxSpecJSI : public TurboModule { protected: NativeArrayTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -79,7 +80,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeBooleanTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeBooleanTurboModuleCxxSpecJSI : public TurboModule { protected: NativeBooleanTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -131,7 +133,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeCallbackTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeCallbackTurboModuleCxxSpecJSI : public TurboModule { protected: NativeCallbackTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -183,7 +186,135 @@ private: Delegate delegate_; }; -#pragma mark - NativeEnumTurboModuleBaseStateType + +#pragma mark - NativeEnumTurboModuleStatusRegularEnum + +enum NativeEnumTurboModuleStatusRegularEnum { Active, Paused, Off }; + +template <> +struct Bridging { + static NativeEnumTurboModuleStatusRegularEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) { + std::string value = rawValue.utf8(rt); + if (value == \\"Active\\") { + return NativeEnumTurboModuleStatusRegularEnum::Active; + } else if (value == \\"Paused\\") { + return NativeEnumTurboModuleStatusRegularEnum::Paused; + } else if (value == \\"Off\\") { + return NativeEnumTurboModuleStatusRegularEnum::Off; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusRegularEnum value) { + if (value == NativeEnumTurboModuleStatusRegularEnum::Active) { + return bridging::toJs(rt, \\"Active\\"); + } else if (value == NativeEnumTurboModuleStatusRegularEnum::Paused) { + return bridging::toJs(rt, \\"Paused\\"); + } else if (value == NativeEnumTurboModuleStatusRegularEnum::Off) { + return bridging::toJs(rt, \\"Off\\"); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + +#pragma mark - NativeEnumTurboModuleStatusStrEnum + +enum NativeEnumTurboModuleStatusStrEnum { Active, Paused, Off }; + +template <> +struct Bridging { + static NativeEnumTurboModuleStatusStrEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) { + std::string value = rawValue.utf8(rt); + if (value == \\"active\\") { + return NativeEnumTurboModuleStatusStrEnum::Active; + } else if (value == \\"paused\\") { + return NativeEnumTurboModuleStatusStrEnum::Paused; + } else if (value == \\"off\\") { + return NativeEnumTurboModuleStatusStrEnum::Off; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusStrEnum value) { + if (value == NativeEnumTurboModuleStatusStrEnum::Active) { + return bridging::toJs(rt, \\"active\\"); + } else if (value == NativeEnumTurboModuleStatusStrEnum::Paused) { + return bridging::toJs(rt, \\"paused\\"); + } else if (value == NativeEnumTurboModuleStatusStrEnum::Off) { + return bridging::toJs(rt, \\"off\\"); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + +#pragma mark - NativeEnumTurboModuleStatusNumEnum + +enum NativeEnumTurboModuleStatusNumEnum { Active, Paused, Off }; + +template <> +struct Bridging { + static NativeEnumTurboModuleStatusNumEnum fromJs(jsi::Runtime &rt, int32_t value) { + + if (value == 2) { + return NativeEnumTurboModuleStatusNumEnum::Active; + } else if (value == 1) { + return NativeEnumTurboModuleStatusNumEnum::Paused; + } else if (value == 0) { + return NativeEnumTurboModuleStatusNumEnum::Off; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusNumEnum value) { + if (value == NativeEnumTurboModuleStatusNumEnum::Active) { + return bridging::toJs(rt, 2); + } else if (value == NativeEnumTurboModuleStatusNumEnum::Paused) { + return bridging::toJs(rt, 1); + } else if (value == NativeEnumTurboModuleStatusNumEnum::Off) { + return bridging::toJs(rt, 0); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + +#pragma mark - NativeEnumTurboModuleStatusFractionEnum + +enum NativeEnumTurboModuleStatusFractionEnum { Active, Paused, Off }; + +template <> +struct Bridging { + static NativeEnumTurboModuleStatusFractionEnum fromJs(jsi::Runtime &rt, float value) { + + if (value == 0.2f) { + return NativeEnumTurboModuleStatusFractionEnum::Active; + } else if (value == 0.1f) { + return NativeEnumTurboModuleStatusFractionEnum::Paused; + } else if (value == 0f) { + return NativeEnumTurboModuleStatusFractionEnum::Off; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusFractionEnum value) { + if (value == NativeEnumTurboModuleStatusFractionEnum::Active) { + return bridging::toJs(rt, 0.2f); + } else if (value == NativeEnumTurboModuleStatusFractionEnum::Paused) { + return bridging::toJs(rt, 0.1f); + } else if (value == NativeEnumTurboModuleStatusFractionEnum::Off) { + return bridging::toJs(rt, 0f); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + #pragma mark - NativeEnumTurboModuleBaseStateType template struct NativeEnumTurboModuleBaseStateType { @@ -260,7 +391,7 @@ struct NativeEnumTurboModuleBaseStateTypeWithEnumsBridging { static jsi::String strToJs(jsi::Runtime &rt, P2 value) { return bridging::toJs(rt, value); } - static double numToJs(jsi::Runtime &rt, P3 value) { + static int numToJs(jsi::Runtime &rt, P3 value) { return bridging::toJs(rt, value); } static double fractionToJs(jsi::Runtime &rt, P4 value) { @@ -289,9 +420,9 @@ protected: public: virtual jsi::String getStatusRegular(jsi::Runtime &rt, jsi::Object statusProp) = 0; virtual jsi::String getStatusStr(jsi::Runtime &rt, jsi::Object statusProp) = 0; - virtual double getStatusNum(jsi::Runtime &rt, jsi::Object statusProp) = 0; + virtual int getStatusNum(jsi::Runtime &rt, jsi::Object statusProp) = 0; virtual double getStatusFraction(jsi::Runtime &rt, jsi::Object statusProp) = 0; - virtual jsi::Object getStateType(jsi::Runtime &rt, jsi::String a, jsi::String b, double c, double d) = 0; + virtual jsi::Object getStateType(jsi::Runtime &rt, jsi::String a, jsi::String b, int c, double d) = 0; virtual jsi::Object getStateTypeWithEnums(jsi::Runtime &rt, jsi::Object paramOfTypeWithEnums) = 0; }; @@ -330,12 +461,12 @@ private: return bridging::callFromJs( rt, &T::getStatusStr, jsInvoker_, instance_, std::move(statusProp)); } - double getStatusNum(jsi::Runtime &rt, jsi::Object statusProp) override { + int getStatusNum(jsi::Runtime &rt, jsi::Object statusProp) override { static_assert( bridging::getParameterCount(&T::getStatusNum) == 2, \\"Expected getStatusNum(...) to have 2 parameters\\"); - return bridging::callFromJs( + return bridging::callFromJs( rt, &T::getStatusNum, jsInvoker_, instance_, std::move(statusProp)); } double getStatusFraction(jsi::Runtime &rt, jsi::Object statusProp) override { @@ -346,7 +477,7 @@ private: return bridging::callFromJs( rt, &T::getStatusFraction, jsInvoker_, instance_, std::move(statusProp)); } - jsi::Object getStateType(jsi::Runtime &rt, jsi::String a, jsi::String b, double c, double d) override { + jsi::Object getStateType(jsi::Runtime &rt, jsi::String a, jsi::String b, int c, double d) override { static_assert( bridging::getParameterCount(&T::getStateType) == 5, \\"Expected getStateType(...) to have 5 parameters\\"); @@ -370,7 +501,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeNullableTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeNullableTurboModuleCxxSpecJSI : public TurboModule { protected: NativeNullableTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -458,7 +590,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeNumberTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeNumberTurboModuleCxxSpecJSI : public TurboModule { protected: NativeNumberTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -510,7 +643,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeObjectTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeObjectTurboModuleCxxSpecJSI : public TurboModule { protected: NativeObjectTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -589,7 +723,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeOptionalObjectTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeOptionalObjectTurboModuleCxxSpecJSI : public TurboModule { protected: NativeOptionalObjectTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -632,7 +767,8 @@ private: Delegate delegate_; }; -#pragma mark - NativePartialAnnotationTurboModuleBaseSomeObj + + #pragma mark - NativePartialAnnotationTurboModuleBaseSomeObj template struct NativePartialAnnotationTurboModuleBaseSomeObj { @@ -747,7 +883,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativePromiseTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativePromiseTurboModuleCxxSpecJSI : public TurboModule { protected: NativePromiseTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -799,7 +936,8 @@ private: Delegate delegate_; }; -#pragma mark - SampleTurboModuleBaseAnimal + + #pragma mark - SampleTurboModuleBaseAnimal template struct SampleTurboModuleBaseAnimal { @@ -987,7 +1125,8 @@ private: Delegate delegate_; }; -#pragma mark - SampleTurboModuleArraysBaseAnimal + + #pragma mark - SampleTurboModuleArraysBaseAnimal template struct SampleTurboModuleArraysBaseAnimal { @@ -1175,7 +1314,8 @@ private: Delegate delegate_; }; -#pragma mark - SampleTurboModuleNullableBaseAnimal + + #pragma mark - SampleTurboModuleNullableBaseAnimal template struct SampleTurboModuleNullableBaseAnimal { @@ -1363,7 +1503,8 @@ private: Delegate delegate_; }; -#pragma mark - SampleTurboModuleNullableAndOptionalBaseAnimal + + #pragma mark - SampleTurboModuleNullableAndOptionalBaseAnimal template struct SampleTurboModuleNullableAndOptionalBaseAnimal { @@ -1553,7 +1694,8 @@ private: Delegate delegate_; }; -#pragma mark - SampleTurboModuleOptionalBaseAnimal + + #pragma mark - SampleTurboModuleOptionalBaseAnimal template struct SampleTurboModuleOptionalBaseAnimal { @@ -1743,7 +1885,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeStringTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeStringTurboModuleCxxSpecJSI : public TurboModule { protected: NativeStringTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -1818,7 +1961,8 @@ exports[`GenerateModuleH can generate a header file NativeModule specs with assu namespace facebook { namespace react { -class JSI_EXPORT NativeArrayTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeArrayTurboModuleCxxSpecJSI : public TurboModule { protected: NativeArrayTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -1879,7 +2023,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeBooleanTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeBooleanTurboModuleCxxSpecJSI : public TurboModule { protected: NativeBooleanTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -1931,7 +2076,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeCallbackTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeCallbackTurboModuleCxxSpecJSI : public TurboModule { protected: NativeCallbackTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -1983,7 +2129,135 @@ private: Delegate delegate_; }; -#pragma mark - NativeEnumTurboModuleBaseStateType + +#pragma mark - NativeEnumTurboModuleStatusRegularEnum + +enum NativeEnumTurboModuleStatusRegularEnum { Active, Paused, Off }; + +template <> +struct Bridging { + static NativeEnumTurboModuleStatusRegularEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) { + std::string value = rawValue.utf8(rt); + if (value == \\"Active\\") { + return NativeEnumTurboModuleStatusRegularEnum::Active; + } else if (value == \\"Paused\\") { + return NativeEnumTurboModuleStatusRegularEnum::Paused; + } else if (value == \\"Off\\") { + return NativeEnumTurboModuleStatusRegularEnum::Off; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusRegularEnum value) { + if (value == NativeEnumTurboModuleStatusRegularEnum::Active) { + return bridging::toJs(rt, \\"Active\\"); + } else if (value == NativeEnumTurboModuleStatusRegularEnum::Paused) { + return bridging::toJs(rt, \\"Paused\\"); + } else if (value == NativeEnumTurboModuleStatusRegularEnum::Off) { + return bridging::toJs(rt, \\"Off\\"); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + +#pragma mark - NativeEnumTurboModuleStatusStrEnum + +enum NativeEnumTurboModuleStatusStrEnum { Active, Paused, Off }; + +template <> +struct Bridging { + static NativeEnumTurboModuleStatusStrEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) { + std::string value = rawValue.utf8(rt); + if (value == \\"active\\") { + return NativeEnumTurboModuleStatusStrEnum::Active; + } else if (value == \\"paused\\") { + return NativeEnumTurboModuleStatusStrEnum::Paused; + } else if (value == \\"off\\") { + return NativeEnumTurboModuleStatusStrEnum::Off; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::String toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusStrEnum value) { + if (value == NativeEnumTurboModuleStatusStrEnum::Active) { + return bridging::toJs(rt, \\"active\\"); + } else if (value == NativeEnumTurboModuleStatusStrEnum::Paused) { + return bridging::toJs(rt, \\"paused\\"); + } else if (value == NativeEnumTurboModuleStatusStrEnum::Off) { + return bridging::toJs(rt, \\"off\\"); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + +#pragma mark - NativeEnumTurboModuleStatusNumEnum + +enum NativeEnumTurboModuleStatusNumEnum { Active, Paused, Off }; + +template <> +struct Bridging { + static NativeEnumTurboModuleStatusNumEnum fromJs(jsi::Runtime &rt, int32_t value) { + + if (value == 2) { + return NativeEnumTurboModuleStatusNumEnum::Active; + } else if (value == 1) { + return NativeEnumTurboModuleStatusNumEnum::Paused; + } else if (value == 0) { + return NativeEnumTurboModuleStatusNumEnum::Off; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusNumEnum value) { + if (value == NativeEnumTurboModuleStatusNumEnum::Active) { + return bridging::toJs(rt, 2); + } else if (value == NativeEnumTurboModuleStatusNumEnum::Paused) { + return bridging::toJs(rt, 1); + } else if (value == NativeEnumTurboModuleStatusNumEnum::Off) { + return bridging::toJs(rt, 0); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + +#pragma mark - NativeEnumTurboModuleStatusFractionEnum + +enum NativeEnumTurboModuleStatusFractionEnum { Active, Paused, Off }; + +template <> +struct Bridging { + static NativeEnumTurboModuleStatusFractionEnum fromJs(jsi::Runtime &rt, float value) { + + if (value == 0.2f) { + return NativeEnumTurboModuleStatusFractionEnum::Active; + } else if (value == 0.1f) { + return NativeEnumTurboModuleStatusFractionEnum::Paused; + } else if (value == 0f) { + return NativeEnumTurboModuleStatusFractionEnum::Off; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::Value toJs(jsi::Runtime &rt, NativeEnumTurboModuleStatusFractionEnum value) { + if (value == NativeEnumTurboModuleStatusFractionEnum::Active) { + return bridging::toJs(rt, 0.2f); + } else if (value == NativeEnumTurboModuleStatusFractionEnum::Paused) { + return bridging::toJs(rt, 0.1f); + } else if (value == NativeEnumTurboModuleStatusFractionEnum::Off) { + return bridging::toJs(rt, 0f); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + #pragma mark - NativeEnumTurboModuleBaseStateType template struct NativeEnumTurboModuleBaseStateType { @@ -2060,7 +2334,7 @@ struct NativeEnumTurboModuleBaseStateTypeWithEnumsBridging { static jsi::String strToJs(jsi::Runtime &rt, P2 value) { return bridging::toJs(rt, value); } - static double numToJs(jsi::Runtime &rt, P3 value) { + static int numToJs(jsi::Runtime &rt, P3 value) { return bridging::toJs(rt, value); } static double fractionToJs(jsi::Runtime &rt, P4 value) { @@ -2089,9 +2363,9 @@ protected: public: virtual jsi::String getStatusRegular(jsi::Runtime &rt, jsi::Object statusProp) = 0; virtual jsi::String getStatusStr(jsi::Runtime &rt, jsi::Object statusProp) = 0; - virtual double getStatusNum(jsi::Runtime &rt, jsi::Object statusProp) = 0; + virtual int getStatusNum(jsi::Runtime &rt, jsi::Object statusProp) = 0; virtual double getStatusFraction(jsi::Runtime &rt, jsi::Object statusProp) = 0; - virtual jsi::Object getStateType(jsi::Runtime &rt, jsi::String a, jsi::String b, double c, double d) = 0; + virtual jsi::Object getStateType(jsi::Runtime &rt, jsi::String a, jsi::String b, int c, double d) = 0; virtual jsi::Object getStateTypeWithEnums(jsi::Runtime &rt, jsi::Object paramOfTypeWithEnums) = 0; }; @@ -2130,12 +2404,12 @@ private: return bridging::callFromJs( rt, &T::getStatusStr, jsInvoker_, instance_, std::move(statusProp)); } - double getStatusNum(jsi::Runtime &rt, jsi::Object statusProp) override { + int getStatusNum(jsi::Runtime &rt, jsi::Object statusProp) override { static_assert( bridging::getParameterCount(&T::getStatusNum) == 2, \\"Expected getStatusNum(...) to have 2 parameters\\"); - return bridging::callFromJs( + return bridging::callFromJs( rt, &T::getStatusNum, jsInvoker_, instance_, std::move(statusProp)); } double getStatusFraction(jsi::Runtime &rt, jsi::Object statusProp) override { @@ -2146,7 +2420,7 @@ private: return bridging::callFromJs( rt, &T::getStatusFraction, jsInvoker_, instance_, std::move(statusProp)); } - jsi::Object getStateType(jsi::Runtime &rt, jsi::String a, jsi::String b, double c, double d) override { + jsi::Object getStateType(jsi::Runtime &rt, jsi::String a, jsi::String b, int c, double d) override { static_assert( bridging::getParameterCount(&T::getStateType) == 5, \\"Expected getStateType(...) to have 5 parameters\\"); @@ -2170,7 +2444,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeNullableTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeNullableTurboModuleCxxSpecJSI : public TurboModule { protected: NativeNullableTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -2258,7 +2533,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeNumberTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeNumberTurboModuleCxxSpecJSI : public TurboModule { protected: NativeNumberTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -2310,7 +2586,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeObjectTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeObjectTurboModuleCxxSpecJSI : public TurboModule { protected: NativeObjectTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -2389,7 +2666,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeOptionalObjectTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeOptionalObjectTurboModuleCxxSpecJSI : public TurboModule { protected: NativeOptionalObjectTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -2432,7 +2710,8 @@ private: Delegate delegate_; }; -#pragma mark - NativePartialAnnotationTurboModuleBaseSomeObj + + #pragma mark - NativePartialAnnotationTurboModuleBaseSomeObj template struct NativePartialAnnotationTurboModuleBaseSomeObj { @@ -2547,7 +2826,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativePromiseTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativePromiseTurboModuleCxxSpecJSI : public TurboModule { protected: NativePromiseTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -2599,7 +2879,8 @@ private: Delegate delegate_; }; -#pragma mark - SampleTurboModuleBaseAnimal + + #pragma mark - SampleTurboModuleBaseAnimal template struct SampleTurboModuleBaseAnimal { @@ -2787,7 +3068,8 @@ private: Delegate delegate_; }; -#pragma mark - SampleTurboModuleArraysBaseAnimal + + #pragma mark - SampleTurboModuleArraysBaseAnimal template struct SampleTurboModuleArraysBaseAnimal { @@ -2975,7 +3257,8 @@ private: Delegate delegate_; }; -#pragma mark - SampleTurboModuleNullableBaseAnimal + + #pragma mark - SampleTurboModuleNullableBaseAnimal template struct SampleTurboModuleNullableBaseAnimal { @@ -3163,7 +3446,8 @@ private: Delegate delegate_; }; -#pragma mark - SampleTurboModuleNullableAndOptionalBaseAnimal + + #pragma mark - SampleTurboModuleNullableAndOptionalBaseAnimal template struct SampleTurboModuleNullableAndOptionalBaseAnimal { @@ -3353,7 +3637,8 @@ private: Delegate delegate_; }; -#pragma mark - SampleTurboModuleOptionalBaseAnimal + + #pragma mark - SampleTurboModuleOptionalBaseAnimal template struct SampleTurboModuleOptionalBaseAnimal { @@ -3543,7 +3828,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeStringTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeStringTurboModuleCxxSpecJSI : public TurboModule { protected: NativeStringTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); diff --git a/packages/react-native-codegen/src/generators/Utils.js b/packages/react-native-codegen/src/generators/Utils.js index bd1ec2f6b30a6c..da692692daafac 100644 --- a/packages/react-native-codegen/src/generators/Utils.js +++ b/packages/react-native-codegen/src/generators/Utils.js @@ -27,7 +27,27 @@ function indent(nice: string, spaces: number): string { .join('\n'); } +function toPascalCase(inString: string): string { + if (inString.length === 0) { + return inString; + } + + return inString[0].toUpperCase() + inString.slice(1); +} + +function toSafeCppString(input: string): string { + return input.split('-').map(toPascalCase).join(''); +} + +function getEnumName(moduleName: string, origEnumName: string): string { + const uppercasedPropName = toSafeCppString(origEnumName); + return `${moduleName}${uppercasedPropName}`; +} + module.exports = { capitalize, indent, + toPascalCase, + toSafeCppString, + getEnumName, }; diff --git a/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js b/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js index e9f4c057bed558..046b9ed27919b4 100644 --- a/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js +++ b/packages/react-native-codegen/src/generators/components/ComponentsGeneratorUtils.js @@ -25,11 +25,12 @@ import type { const { getCppTypeForAnnotation, getEnumMaskName, - getEnumName, generateStructName, getImports, } = require('./CppHelpers.js'); +const {getEnumName} = require('../Utils'); + function getNativeTypeFromAnnotation( componentName: string, prop: diff --git a/packages/react-native-codegen/src/generators/components/CppHelpers.js b/packages/react-native-codegen/src/generators/components/CppHelpers.js index 0bc7dd754eecc6..cb3090df08cdfa 100644 --- a/packages/react-native-codegen/src/generators/components/CppHelpers.js +++ b/packages/react-native-codegen/src/generators/components/CppHelpers.js @@ -11,17 +11,7 @@ 'use strict'; import type {NamedShape, PropTypeAnnotation} from '../../CodegenSchema'; -function upperCaseFirst(inString: string): string { - if (inString.length === 0) { - return inString; - } - - return inString[0].toUpperCase() + inString.slice(1); -} - -function toSafeCppString(input: string): string { - return input.split('-').map(upperCaseFirst).join(''); -} +const {getEnumName, toSafeCppString} = require('../Utils'); function toIntEnumValueName(propName: string, value: number): string { return `${toSafeCppString(propName)}${value}`; @@ -124,11 +114,6 @@ function generateStructName( return `${componentName}${additional}Struct`; } -function getEnumName(componentName: string, propName: string): string { - const uppercasedPropName = toSafeCppString(propName); - return `${componentName}${uppercasedPropName}`; -} - function getEnumMaskName(enumName: string): string { return `${enumName}Mask`; } @@ -224,10 +209,8 @@ function convertDefaultTypeToString( module.exports = { convertDefaultTypeToString, getCppTypeForAnnotation, - getEnumName, getEnumMaskName, getImports, - toSafeCppString, toIntEnumValueName, generateStructName, generateEventStructName, diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js index f61ca1ac091aa4..e1ae0d51b440b3 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js @@ -14,10 +14,9 @@ const nullthrows = require('nullthrows'); const { getCppTypeForAnnotation, - toSafeCppString, generateEventStructName, } = require('./CppHelpers'); -const {indent} = require('../Utils'); +const {indent, toSafeCppString} = require('../Utils'); import type { ComponentShape, diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js index cd0546a8b21251..15a7fcc425a174 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js @@ -19,12 +19,12 @@ const { const { convertDefaultTypeToString, getEnumMaskName, - getEnumName, - toSafeCppString, generateStructName, toIntEnumValueName, } = require('./CppHelpers.js'); +const {getEnumName, toSafeCppString} = require('../Utils'); + import type { ExtendsPropsShape, NamedShape, diff --git a/packages/react-native-codegen/src/generators/components/GenerateTests.js b/packages/react-native-codegen/src/generators/components/GenerateTests.js index 0a292e15fff64e..95f51da618d3dc 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateTests.js +++ b/packages/react-native-codegen/src/generators/components/GenerateTests.js @@ -12,7 +12,9 @@ import type {ComponentShape, PropTypeAnnotation} from '../../CodegenSchema'; import type {SchemaType} from '../../CodegenSchema'; -const {getImports, toSafeCppString} = require('./CppHelpers'); +const {getImports} = require('./CppHelpers'); + +const {toSafeCppString} = require('../Utils'); type FilesOutput = Map; type PropValueType = string | number | boolean; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js index 5b366e953530ae..cef441f6fe1862 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleCpp.js @@ -18,6 +18,7 @@ import type { NativeModuleFunctionTypeAnnotation, NativeModuleParamTypeAnnotation, NativeModuleTypeAnnotation, + NativeModuleEnumMap, } from '../../CodegenSchema'; import type {AliasResolver} from './Utils'; @@ -114,9 +115,11 @@ ${modules} type Param = NamedShape>; function serializeArg( + moduleName: string, arg: Param, index: number, resolveAlias: AliasResolver, + enumMap: NativeModuleEnumMap, ): string { const {typeAnnotation: nullableTypeAnnotation, optional} = arg; const [typeAnnotation, nullable] = @@ -208,9 +211,11 @@ function serializeArg( } function serializePropertyIntoHostFunction( + moduleName: string, hasteModuleName: string, property: NativeModulePropertyShape, resolveAlias: AliasResolver, + enumMap: NativeModuleEnumMap, ): string { const [propertyTypeAnnotation] = unwrapNullable(property.typeAnnotation); @@ -220,7 +225,7 @@ function serializePropertyIntoHostFunction( methodName: property.name, returnTypeAnnotation: propertyTypeAnnotation.returnTypeAnnotation, args: propertyTypeAnnotation.params.map((p, i) => - serializeArg(p, i, resolveAlias), + serializeArg(moduleName, p, i, resolveAlias, enumMap), ), }); } @@ -239,15 +244,18 @@ module.exports = { const nativeModule = nativeModules[hasteModuleName]; const { aliasMap, + enumMap, spec: {properties}, moduleName, } = nativeModule; const resolveAlias = createAliasResolver(aliasMap); const hostFunctions = properties.map(property => serializePropertyIntoHostFunction( + moduleName, hasteModuleName, property, resolveAlias, + enumMap, ), ); diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js index a3156c4d7e49c9..56e1a09fcfc626 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleH.js @@ -17,10 +17,20 @@ import type { NativeModuleFunctionTypeAnnotation, NativeModulePropertyShape, NativeModuleAliasMap, + NativeModuleEnumMap, + NativeModuleEnumMembers, + NativeModuleEnumMemberType, } from '../../CodegenSchema'; import type {AliasResolver} from './Utils'; -const {createAliasResolver, getModules} = require('./Utils'); + +const {getEnumName, toSafeCppString} = require('../Utils'); + +const { + createAliasResolver, + getModules, + getAreEnumMembersInteger, +} = require('./Utils'); const {indent} = require('../Utils'); const {unwrapNullable} = require('../../parsers/parsers-commons'); @@ -30,12 +40,15 @@ const ModuleClassDeclarationTemplate = ({ hasteModuleName, moduleProperties, structs, + enums, }: $ReadOnly<{ hasteModuleName: string, moduleProperties: string[], structs: string, + enums: string, }>) => { - return `${structs}class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule { + return `${enums} + ${structs}class JSI_EXPORT ${hasteModuleName}CxxSpecJSI : public TurboModule { protected: ${hasteModuleName}CxxSpecJSI(std::shared_ptr jsInvoker); @@ -112,10 +125,12 @@ ${modules.join('\n\n')} }; function translatePrimitiveJSTypeToCpp( + moduleName: string, nullableTypeAnnotation: Nullable, optional: boolean, createErrorMessage: (typeName: string) => string, resolveAlias: AliasResolver, + enumMap: NativeModuleEnumMap, ) { const [typeAnnotation, nullable] = unwrapNullable( nullableTypeAnnotation, @@ -157,7 +172,11 @@ function translatePrimitiveJSTypeToCpp( case 'EnumDeclaration': switch (realTypeAnnotation.memberType) { case 'NumberTypeAnnotation': - return wrap('double'); + return getAreEnumMembersInteger( + enumMap[realTypeAnnotation.name].members, + ) + ? wrap('int') + : wrap('double'); case 'StringTypeAnnotation': return wrap('jsi::String'); default: @@ -192,10 +211,11 @@ function translatePrimitiveJSTypeToCpp( } } -function createStructs( +function createStructsString( moduleName: string, aliasMap: NativeModuleAliasMap, resolveAlias: AliasResolver, + enumMap: NativeModuleEnumMap, ): string { return Object.keys(aliasMap) .map(alias => { @@ -213,11 +233,13 @@ function createStructs( const paramemterConversion = value.properties .map((v, i) => { const translatedParam = translatePrimitiveJSTypeToCpp( + moduleName, v.typeAnnotation, false, typeName => `Unsupported type for param "${v.name}". Found: ${typeName}`, resolveAlias, + enumMap, ); return ` static ${translatedParam} ${v.name}ToJs(jsi::Runtime &rt, P${i} value) { return bridging::toJs(rt, value); @@ -281,9 +303,128 @@ ${paramemterConversion} .join('\n'); } +type NativeEnumMemberValueType = 'std::string' | 'int32_t' | 'float'; + +const EnumTemplate = ({ + enumName, + values, + fromCases, + toCases, + nativeEnumMemberType, +}: { + enumName: string, + values: string, + fromCases: string, + toCases: string, + nativeEnumMemberType: NativeEnumMemberValueType, +}) => { + const fromValue = + nativeEnumMemberType === 'std::string' + ? 'const jsi::String &rawValue' + : `${nativeEnumMemberType} value`; + + const fromValueConvertion = + nativeEnumMemberType === 'std::string' + ? 'std::string value = rawValue.utf8(rt);' + : ''; + + const toValue = + nativeEnumMemberType === 'std::string' ? 'jsi::String' : 'jsi::Value'; + + return ` +#pragma mark - ${enumName} + +enum ${enumName} { ${values} }; + +template <> +struct Bridging<${enumName}> { + static ${enumName} fromJs(jsi::Runtime &rt, ${fromValue}) { + ${fromValueConvertion} + ${fromCases} + } + + static ${toValue} toJs(jsi::Runtime &rt, ${enumName} value) { + ${toCases} + } +};`; +}; + +function generateEnum( + moduleName: string, + origEnumName: string, + members: NativeModuleEnumMembers, + memberType: NativeModuleEnumMemberType, +): string { + const enumName = getEnumName(moduleName, origEnumName); + + const nativeEnumMemberType: NativeEnumMemberValueType = + memberType === 'StringTypeAnnotation' + ? 'std::string' + : getAreEnumMembersInteger(members) + ? 'int32_t' + : 'float'; + + const getMemberValueAppearance = (value: string) => + memberType === 'StringTypeAnnotation' + ? `"${value}"` + : `${value}${nativeEnumMemberType === 'float' ? 'f' : ''}`; + + const fromCases = + members + .map( + member => `if (value == ${getMemberValueAppearance(member.value)}) { + return ${enumName}::${toSafeCppString(member.name)}; + }`, + ) + .join(' else ') + + ` else { + throw jsi::JSError(rt, "No appropriate enum member found for value"); + }`; + + const toCases = + members + .map( + member => `if (value == ${enumName}::${toSafeCppString(member.name)}) { + return bridging::toJs(rt, ${getMemberValueAppearance(member.value)}); + }`, + ) + .join(' else ') + + ` else { + throw jsi::JSError(rt, "No appropriate enum member found for enum value"); + }`; + + return EnumTemplate({ + enumName, + values: members.map(member => member.name).join(', '), + fromCases, + toCases, + nativeEnumMemberType, + }); +} + +function createEnums( + moduleName: string, + enumMap: NativeModuleEnumMap, + resolveAlias: AliasResolver, +): string { + return Object.entries(enumMap) + .map(([enumName, enumNode]) => { + return generateEnum( + moduleName, + enumName, + enumNode.members, + enumNode.memberType, + ); + }) + .filter(Boolean) + .join('\n'); +} + function translatePropertyToCpp( + moduleName: string, prop: NativeModulePropertyShape, resolveAlias: AliasResolver, + enumMap: NativeModuleEnumMap, abstract: boolean = false, ) { const [propTypeAnnotation] = @@ -295,20 +436,24 @@ function translatePropertyToCpp( const paramTypes = propTypeAnnotation.params.map(param => { const translatedParam = translatePrimitiveJSTypeToCpp( + moduleName, param.typeAnnotation, param.optional, typeName => `Unsupported type for param "${param.name}" in ${prop.name}. Found: ${typeName}`, resolveAlias, + enumMap, ); return `${translatedParam} ${param.name}`; }); const returnType = translatePrimitiveJSTypeToCpp( + moduleName, propTypeAnnotation.returnTypeAnnotation, false, typeName => `Unsupported return type for ${prop.name}. Found: ${typeName}`, resolveAlias, + enumMap, ); // The first param will always be the runtime reference. @@ -342,25 +487,39 @@ module.exports = { const modules = Object.keys(nativeModules).flatMap(hasteModuleName => { const { aliasMap, + enumMap, spec: {properties}, moduleName, } = nativeModules[hasteModuleName]; const resolveAlias = createAliasResolver(aliasMap); - const structs = createStructs(moduleName, aliasMap, resolveAlias); + const structs = createStructsString( + moduleName, + aliasMap, + resolveAlias, + enumMap, + ); + const enums = createEnums(moduleName, enumMap, resolveAlias); return [ ModuleClassDeclarationTemplate({ hasteModuleName, moduleProperties: properties.map(prop => - translatePropertyToCpp(prop, resolveAlias, true), + translatePropertyToCpp( + moduleName, + prop, + resolveAlias, + enumMap, + true, + ), ), structs, + enums, }), ModuleSpecClassDeclarationTemplate({ hasteModuleName, moduleName, moduleProperties: properties.map(prop => - translatePropertyToCpp(prop, resolveAlias), + translatePropertyToCpp(moduleName, prop, resolveAlias, enumMap), ), }), ]; diff --git a/packages/react-native-codegen/src/generators/modules/Utils.js b/packages/react-native-codegen/src/generators/modules/Utils.js index b89df46a01f896..8d172d32abc814 100644 --- a/packages/react-native-codegen/src/generators/modules/Utils.js +++ b/packages/react-native-codegen/src/generators/modules/Utils.js @@ -15,6 +15,7 @@ import type { NativeModuleAliasMap, NativeModuleObjectTypeAnnotation, NativeModuleSchema, + NativeModuleEnumMembers, } from '../../CodegenSchema'; const invariant = require('invariant'); @@ -47,7 +48,12 @@ function getModules( ); } +function getAreEnumMembersInteger(members: NativeModuleEnumMembers): boolean { + return !members.some(m => `${m.value}`.includes('.')); +} + module.exports = { createAliasResolver, getModules, + getAreEnumMembersInteger, }; diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js index 5764facb3bc32e..8f96919d4c3843 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js @@ -31,7 +31,57 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { NativeSampleTurboModule: { type: 'NativeModule', aliasMap: {}, - enumMap: {}, + enumMap: { + NumEnum: { + type: 'EnumDeclarationWithMembers', + name: 'NumEnum', + memberType: 'NumberTypeAnnotation', + members: [ + { + name: 'ONE', + value: '1', + }, + { + name: 'TWO', + value: '2', + }, + ], + }, + FloatEnum: { + type: 'EnumDeclarationWithMembers', + name: 'FloatEnum', + memberType: 'NumberTypeAnnotation', + members: [ + { + name: 'POINT_ZERO', + value: '0.0', + }, + { + name: 'POINT_ONE', + value: '0.1', + }, + { + name: 'POINT_TWO', + value: '0.2', + }, + ], + }, + StringEnum: { + type: 'EnumDeclarationWithMembers', + name: 'StringEnum', + memberType: 'StringTypeAnnotation', + members: [ + { + name: 'HELLO', + value: 'hello', + }, + { + name: 'GoodBye', + value: 'goodbye', + }, + ], + }, + }, spec: { properties: [ { @@ -235,6 +285,19 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { ], }, }, + { + name: 'getEnumReturn', + optional: false, + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + type: 'EnumDeclaration', + name: 'NumEnum', + memberType: 'NumberTypeAnnotation', + }, + params: [], + }, + }, { name: 'getValueWithCallback', optional: false, @@ -309,6 +372,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { name: 'enumInt', optional: false, typeAnnotation: { + name: 'NumEnum', type: 'EnumDeclaration', memberType: 'NumberTypeAnnotation', }, @@ -317,6 +381,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { name: 'enumFloat', optional: false, typeAnnotation: { + name: 'FloatEnum', type: 'EnumDeclaration', memberType: 'NumberTypeAnnotation', }, @@ -325,6 +390,7 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { name: 'enumString', optional: false, typeAnnotation: { + name: 'StringEnum', type: 'EnumDeclaration', memberType: 'StringTypeAnnotation', }, @@ -1516,7 +1582,57 @@ const CXX_ONLY_NATIVE_MODULES: SchemaType = { ], }, }, - enumMap: {}, + enumMap: { + NumEnum: { + type: 'EnumDeclarationWithMembers', + name: 'NumEnum', + memberType: 'NumberTypeAnnotation', + members: [ + { + name: 'ONE', + value: '1', + }, + { + name: 'TWO', + value: '2', + }, + ], + }, + FloatEnum: { + type: 'EnumDeclarationWithMembers', + name: 'FloatEnum', + memberType: 'NumberTypeAnnotation', + members: [ + { + name: 'POINT_ZERO', + value: '0.0', + }, + { + name: 'POINT_ONE', + value: '0.1', + }, + { + name: 'POINT_TWO', + value: '0.2', + }, + ], + }, + StringEnum: { + type: 'EnumDeclarationWithMembers', + name: 'StringEnum', + memberType: 'StringTypeAnnotation', + members: [ + { + name: 'HELLO', + value: 'hello', + }, + { + name: 'GoodBye', + value: 'goodbye', + }, + ], + }, + }, spec: { properties: [ { @@ -1577,6 +1693,7 @@ const CXX_ONLY_NATIVE_MODULES: SchemaType = { name: 'enumInt', optional: false, typeAnnotation: { + name: 'NumEnum', type: 'EnumDeclaration', memberType: 'NumberTypeAnnotation', }, @@ -1585,6 +1702,7 @@ const CXX_ONLY_NATIVE_MODULES: SchemaType = { name: 'enumFloat', optional: false, typeAnnotation: { + name: 'FloatEnum', type: 'EnumDeclaration', memberType: 'NumberTypeAnnotation', }, @@ -1593,6 +1711,7 @@ const CXX_ONLY_NATIVE_MODULES: SchemaType = { name: 'enumString', optional: false, typeAnnotation: { + name: 'StringEnum', type: 'EnumDeclaration', memberType: 'StringTypeAnnotation', }, @@ -1645,6 +1764,19 @@ const CXX_ONLY_NATIVE_MODULES: SchemaType = { ], }, }, + { + name: 'getEnumReturn', + optional: false, + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + type: 'EnumDeclaration', + name: 'NumEnum', + memberType: 'NumberTypeAnnotation', + }, + params: [], + }, + }, ], }, moduleName: 'SampleTurboModuleCxx', diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap index 4a22ab252d743b..a07e0f5a717c27 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap @@ -121,6 +121,9 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnums(jsi: static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getUnion(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { return static_cast(&turboModule)->getUnion(rt, args[0].asNumber(), args[1].asNumber(), args[2].asObject(rt), args[3].asString(rt)); } +static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnumReturn(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getEnumReturn(rt); +} NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker) : TurboModule(\\"SampleTurboModuleCxx\\", jsInvoker) { @@ -128,6 +131,7 @@ NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared methodMap_[\\"getNullableNumberFromNullableAlias\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getNullableNumberFromNullableAlias}; methodMap_[\\"getEnums\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnums}; methodMap_[\\"getUnion\\"] = MethodMetadata {4, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getUnion}; + methodMap_[\\"getEnumReturn\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnumReturn}; } @@ -321,6 +325,9 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getRootTag(js static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValue(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { return static_cast(&turboModule)->getValue(rt, args[0].asNumber(), args[1].asString(rt), args[2].asObject(rt)); } +static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnumReturn(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + return static_cast(&turboModule)->getEnumReturn(rt); +} static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithCallback(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { static_cast(&turboModule)->getValueWithCallback(rt, args[0].asObject(rt).asFunction(rt)); return jsi::Value::undefined(); @@ -346,6 +353,7 @@ NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getObject}; methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getRootTag}; methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValue}; + methodMap_[\\"getEnumReturn\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getEnumReturn}; methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithCallback}; methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithPromise}; methodMap_[\\"getValueWithOptionalArg\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_getValueWithOptionalArg}; 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 82800da2235299..e0bd0a41e962bb 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 @@ -19,7 +19,8 @@ Map { namespace facebook { namespace react { -class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { protected: NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -80,7 +81,8 @@ Map { namespace facebook { namespace react { -class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { protected: NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -202,7 +204,95 @@ Map { namespace facebook { namespace react { -#pragma mark - SampleTurboModuleCxxBaseObjectAlias + +#pragma mark - SampleTurboModuleCxxNumEnum + +enum SampleTurboModuleCxxNumEnum { ONE, TWO }; + +template <> +struct Bridging { + static SampleTurboModuleCxxNumEnum fromJs(jsi::Runtime &rt, int32_t value) { + + if (value == 1) { + return SampleTurboModuleCxxNumEnum::ONE; + } else if (value == 2) { + return SampleTurboModuleCxxNumEnum::TWO; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxNumEnum value) { + if (value == SampleTurboModuleCxxNumEnum::ONE) { + return bridging::toJs(rt, 1); + } else if (value == SampleTurboModuleCxxNumEnum::TWO) { + return bridging::toJs(rt, 2); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + +#pragma mark - SampleTurboModuleCxxFloatEnum + +enum SampleTurboModuleCxxFloatEnum { POINT_ZERO, POINT_ONE, POINT_TWO }; + +template <> +struct Bridging { + static SampleTurboModuleCxxFloatEnum fromJs(jsi::Runtime &rt, float value) { + + if (value == 0.0f) { + return SampleTurboModuleCxxFloatEnum::POINT_ZERO; + } else if (value == 0.1f) { + return SampleTurboModuleCxxFloatEnum::POINT_ONE; + } else if (value == 0.2f) { + return SampleTurboModuleCxxFloatEnum::POINT_TWO; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleCxxFloatEnum value) { + if (value == SampleTurboModuleCxxFloatEnum::POINT_ZERO) { + return bridging::toJs(rt, 0.0f); + } else if (value == SampleTurboModuleCxxFloatEnum::POINT_ONE) { + return bridging::toJs(rt, 0.1f); + } else if (value == SampleTurboModuleCxxFloatEnum::POINT_TWO) { + return bridging::toJs(rt, 0.2f); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + +#pragma mark - SampleTurboModuleCxxStringEnum + +enum SampleTurboModuleCxxStringEnum { HELLO, GoodBye }; + +template <> +struct Bridging { + static SampleTurboModuleCxxStringEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) { + std::string value = rawValue.utf8(rt); + if (value == \\"hello\\") { + return SampleTurboModuleCxxStringEnum::HELLO; + } else if (value == \\"goodbye\\") { + return SampleTurboModuleCxxStringEnum::GoodBye; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::String toJs(jsi::Runtime &rt, SampleTurboModuleCxxStringEnum value) { + if (value == SampleTurboModuleCxxStringEnum::HELLO) { + return bridging::toJs(rt, \\"hello\\"); + } else if (value == SampleTurboModuleCxxStringEnum::GoodBye) { + return bridging::toJs(rt, \\"goodbye\\"); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + #pragma mark - SampleTurboModuleCxxBaseObjectAlias template struct SampleTurboModuleCxxBaseObjectAlias { @@ -246,8 +336,9 @@ protected: public: virtual jsi::Value getMixed(jsi::Runtime &rt, jsi::Value arg) = 0; virtual std::optional getNullableNumberFromNullableAlias(jsi::Runtime &rt, std::optional a) = 0; - virtual jsi::String getEnums(jsi::Runtime &rt, double enumInt, double enumFloat, jsi::String enumString) = 0; + virtual jsi::String getEnums(jsi::Runtime &rt, int enumInt, double enumFloat, jsi::String enumString) = 0; virtual jsi::Object getUnion(jsi::Runtime &rt, double chooseInt, double chooseFloat, jsi::Object chooseObject, jsi::String chooseString) = 0; + virtual int getEnumReturn(jsi::Runtime &rt) = 0; }; @@ -285,7 +376,7 @@ private: return bridging::callFromJs>( rt, &T::getNullableNumberFromNullableAlias, jsInvoker_, instance_, std::move(a)); } - jsi::String getEnums(jsi::Runtime &rt, double enumInt, double enumFloat, jsi::String enumString) override { + jsi::String getEnums(jsi::Runtime &rt, int enumInt, double enumFloat, jsi::String enumString) override { static_assert( bridging::getParameterCount(&T::getEnums) == 4, \\"Expected getEnums(...) to have 4 parameters\\"); @@ -301,6 +392,14 @@ private: return bridging::callFromJs( rt, &T::getUnion, jsInvoker_, instance_, std::move(chooseInt), std::move(chooseFloat), std::move(chooseObject), std::move(chooseString)); } + int getEnumReturn(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getEnumReturn) == 1, + \\"Expected getEnumReturn(...) to have 1 parameters\\"); + + return bridging::callFromJs( + rt, &T::getEnumReturn, jsInvoker_, instance_); + } private: T *instance_; @@ -334,7 +433,8 @@ Map { namespace facebook { namespace react { -class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { protected: NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -395,7 +495,8 @@ Map { namespace facebook { namespace react { -#pragma mark - AliasTurboModuleBaseOptions + + #pragma mark - AliasTurboModuleBaseOptions template struct AliasTurboModuleBaseOptions { @@ -539,7 +640,8 @@ Map { namespace facebook { namespace react { -#pragma mark - CameraRollManagerBasePhotoIdentifierImage + + #pragma mark - CameraRollManagerBasePhotoIdentifierImage template struct CameraRollManagerBasePhotoIdentifierImage { @@ -846,7 +948,8 @@ private: Delegate delegate_; }; -#pragma mark - ExceptionsManagerBaseStackFrame + + #pragma mark - ExceptionsManagerBaseStackFrame template struct ExceptionsManagerBaseStackFrame { @@ -1099,7 +1202,95 @@ Map { namespace facebook { namespace react { -class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { + +#pragma mark - SampleTurboModuleNumEnum + +enum SampleTurboModuleNumEnum { ONE, TWO }; + +template <> +struct Bridging { + static SampleTurboModuleNumEnum fromJs(jsi::Runtime &rt, int32_t value) { + + if (value == 1) { + return SampleTurboModuleNumEnum::ONE; + } else if (value == 2) { + return SampleTurboModuleNumEnum::TWO; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleNumEnum value) { + if (value == SampleTurboModuleNumEnum::ONE) { + return bridging::toJs(rt, 1); + } else if (value == SampleTurboModuleNumEnum::TWO) { + return bridging::toJs(rt, 2); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + +#pragma mark - SampleTurboModuleFloatEnum + +enum SampleTurboModuleFloatEnum { POINT_ZERO, POINT_ONE, POINT_TWO }; + +template <> +struct Bridging { + static SampleTurboModuleFloatEnum fromJs(jsi::Runtime &rt, float value) { + + if (value == 0.0f) { + return SampleTurboModuleFloatEnum::POINT_ZERO; + } else if (value == 0.1f) { + return SampleTurboModuleFloatEnum::POINT_ONE; + } else if (value == 0.2f) { + return SampleTurboModuleFloatEnum::POINT_TWO; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::Value toJs(jsi::Runtime &rt, SampleTurboModuleFloatEnum value) { + if (value == SampleTurboModuleFloatEnum::POINT_ZERO) { + return bridging::toJs(rt, 0.0f); + } else if (value == SampleTurboModuleFloatEnum::POINT_ONE) { + return bridging::toJs(rt, 0.1f); + } else if (value == SampleTurboModuleFloatEnum::POINT_TWO) { + return bridging::toJs(rt, 0.2f); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + +#pragma mark - SampleTurboModuleStringEnum + +enum SampleTurboModuleStringEnum { HELLO, GoodBye }; + +template <> +struct Bridging { + static SampleTurboModuleStringEnum fromJs(jsi::Runtime &rt, const jsi::String &rawValue) { + std::string value = rawValue.utf8(rt); + if (value == \\"hello\\") { + return SampleTurboModuleStringEnum::HELLO; + } else if (value == \\"goodbye\\") { + return SampleTurboModuleStringEnum::GoodBye; + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for value\\"); + } + } + + static jsi::String toJs(jsi::Runtime &rt, SampleTurboModuleStringEnum value) { + if (value == SampleTurboModuleStringEnum::HELLO) { + return bridging::toJs(rt, \\"hello\\"); + } else if (value == SampleTurboModuleStringEnum::GoodBye) { + return bridging::toJs(rt, \\"goodbye\\"); + } else { + throw jsi::JSError(rt, \\"No appropriate enum member found for enum value\\"); + } + } +}; + class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { protected: NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -1113,10 +1304,11 @@ public: virtual jsi::Object getObject(jsi::Runtime &rt, jsi::Object arg) = 0; virtual double getRootTag(jsi::Runtime &rt, double arg) = 0; virtual jsi::Object getValue(jsi::Runtime &rt, double x, jsi::String y, jsi::Object z) = 0; + virtual int getEnumReturn(jsi::Runtime &rt) = 0; virtual void getValueWithCallback(jsi::Runtime &rt, jsi::Function callback) = 0; virtual jsi::Value getValueWithPromise(jsi::Runtime &rt, bool error) = 0; virtual jsi::Value getValueWithOptionalArg(jsi::Runtime &rt, std::optional parameter) = 0; - virtual jsi::String getEnums(jsi::Runtime &rt, double enumInt, double enumFloat, jsi::String enumString) = 0; + virtual jsi::String getEnums(jsi::Runtime &rt, int enumInt, double enumFloat, jsi::String enumString) = 0; }; @@ -1210,6 +1402,14 @@ private: return bridging::callFromJs( rt, &T::getValue, jsInvoker_, instance_, std::move(x), std::move(y), std::move(z)); } + int getEnumReturn(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getEnumReturn) == 1, + \\"Expected getEnumReturn(...) to have 1 parameters\\"); + + return bridging::callFromJs( + rt, &T::getEnumReturn, jsInvoker_, instance_); + } void getValueWithCallback(jsi::Runtime &rt, jsi::Function callback) override { static_assert( bridging::getParameterCount(&T::getValueWithCallback) == 2, @@ -1234,7 +1434,7 @@ private: return bridging::callFromJs( rt, &T::getValueWithOptionalArg, jsInvoker_, instance_, std::move(parameter)); } - jsi::String getEnums(jsi::Runtime &rt, double enumInt, double enumFloat, jsi::String enumString) override { + jsi::String getEnums(jsi::Runtime &rt, int enumInt, double enumFloat, jsi::String enumString) override { static_assert( bridging::getParameterCount(&T::getEnums) == 4, \\"Expected getEnums(...) to have 4 parameters\\"); @@ -1275,7 +1475,8 @@ Map { namespace facebook { namespace react { -class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeSampleTurboModuleCxxSpecJSI : public TurboModule { protected: NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -1318,7 +1519,8 @@ private: Delegate delegate_; }; -class JSI_EXPORT NativeSampleTurboModule2CxxSpecJSI : public TurboModule { + + class JSI_EXPORT NativeSampleTurboModule2CxxSpecJSI : public TurboModule { protected: NativeSampleTurboModule2CxxSpecJSI(std::shared_ptr jsInvoker); 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 4e923454c77659..fdd04f630546b5 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 @@ -885,6 +885,7 @@ namespace JS { - (NSDictionary *)getValue:(double)x y:(NSString *)y z:(NSDictionary *)z; +- (NSNumber *)getEnumReturn; - (void)getValueWithCallback:(RCTResponseSenderBlock)callback; - (void)getValueWithPromise:(BOOL)error resolve:(RCTPromiseResolveBlock)resolve diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap index 93ec0208c32cf5..cc0c13d0f5653a 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap @@ -425,6 +425,10 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo @DoNotStrip public abstract WritableMap getValue(double x, String y, ReadableMap z); + @ReactMethod(isBlockingSynchronousMethod = true) + @DoNotStrip + public abstract double getEnumReturn(); + @ReactMethod @DoNotStrip public abstract void getValueWithCallback(Callback callback); diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniCpp-test.js.snap index bb1428ed7ae0cd..177f066876aa61 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniCpp-test.js.snap @@ -374,6 +374,11 @@ static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getVal return static_cast(turboModule).invokeJavaMethod(rt, ObjectKind, \\"getValue\\", \\"(DLjava/lang/String;Lcom/facebook/react/bridge/ReadableMap;)Lcom/facebook/react/bridge/WritableMap;\\", args, count, cachedMethodId); } +static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getEnumReturn(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + static jmethodID cachedMethodId = nullptr; + return static_cast(turboModule).invokeJavaMethod(rt, NumberKind, \\"getEnumReturn\\", \\"()D\\", args, count, cachedMethodId); +} + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { static jmethodID cachedMethodId = nullptr; return static_cast(turboModule).invokeJavaMethod(rt, VoidKind, \\"getValueWithCallback\\", \\"(Lcom/facebook/react/bridge/Callback;)V\\", args, count, cachedMethodId); @@ -405,6 +410,7 @@ NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const JavaTurboMo methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObject}; methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag}; methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; + methodMap_[\\"getEnumReturn\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_getEnumReturn}; methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback}; methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise}; methodMap_[\\"getValueWithOptionalArg\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithOptionalArg}; 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 867858ae3252a7..d9936be271e6d8 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 @@ -424,6 +424,10 @@ namespace facebook { return static_cast(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); } + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getEnumReturn(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, NumberKind, \\"getEnumReturn\\", @selector(getEnumReturn), 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); } @@ -471,6 +475,9 @@ namespace facebook { methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; + methodMap_[\\"getEnumReturn\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_getEnumReturn}; + + methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback}; diff --git a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.cpp b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.cpp index 200112714168ac..ba25084e06a69e 100644 --- a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.cpp +++ b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.cpp @@ -33,10 +33,24 @@ ConstantsStruct NativeCxxModuleExample::getConstants(jsi::Runtime &rt) { return ConstantsStruct{true, 69, "react-native"}; } -EnumInt NativeCxxModuleExample::getEnum(jsi::Runtime &rt, EnumInt arg) { +CustomEnumInt NativeCxxModuleExample::getCustomEnum( + jsi::Runtime &rt, + CustomEnumInt arg) { return arg; } +NativeCxxModuleExampleCxxEnumFloat NativeCxxModuleExample::getNumEnum( + jsi::Runtime &rt, + NativeCxxModuleExampleCxxEnumInt arg) { + return NativeCxxModuleExampleCxxEnumFloat::FB; +} + +NativeCxxModuleExampleCxxEnumStr NativeCxxModuleExample::getStrEnum( + jsi::Runtime &rt, + NativeCxxModuleExampleCxxEnumNone arg) { + return NativeCxxModuleExampleCxxEnumStr::SB; +} + std::map> NativeCxxModuleExample::getMap( jsi::Runtime &rt, std::map> arg) { diff --git a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h index bd36f16e7482a0..c9a8cc48cce2cc 100644 --- a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h +++ b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.h @@ -54,21 +54,21 @@ struct Bridging : NativeCxxModuleExampleCxxBaseValueStructBridging< ObjectStruct> {}; #pragma mark - enums -enum EnumInt { A = 23, B = 42 }; +enum CustomEnumInt { A = 23, B = 42 }; template <> -struct Bridging { - static EnumInt fromJs(jsi::Runtime &rt, int32_t value) { +struct Bridging { + static CustomEnumInt fromJs(jsi::Runtime &rt, int32_t value) { if (value == 23) { - return EnumInt::A; + return CustomEnumInt::A; } else if (value == 42) { - return EnumInt::B; + return CustomEnumInt::B; } else { throw jsi::JSError(rt, "Invalid enum value"); } } - static jsi::Value toJs(jsi::Runtime &rt, EnumInt value) { + static jsi::Value toJs(jsi::Runtime &rt, CustomEnumInt value) { return bridging::toJs(rt, static_cast(value)); } }; @@ -91,7 +91,15 @@ class NativeCxxModuleExample ConstantsStruct getConstants(jsi::Runtime &rt); - EnumInt getEnum(jsi::Runtime &rt, EnumInt arg); + CustomEnumInt getCustomEnum(jsi::Runtime &rt, CustomEnumInt arg); + + NativeCxxModuleExampleCxxEnumFloat getNumEnum( + jsi::Runtime &rt, + NativeCxxModuleExampleCxxEnumInt arg); + + NativeCxxModuleExampleCxxEnumStr getStrEnum( + jsi::Runtime &rt, + NativeCxxModuleExampleCxxEnumNone arg); std::map> getMap( jsi::Runtime &rt, diff --git a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.js b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.js index d4e320077f73c0..2e52bf1eaafa7e 100644 --- a/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.js +++ b/packages/rn-tester/NativeCxxModuleExample/NativeCxxModuleExample.js @@ -13,8 +13,23 @@ import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport'; import {TurboModuleRegistry} from 'react-native'; export enum EnumInt { - A = 23, - B = 42, + IA = 23, + IB = 42, +} + +export enum EnumFloat { + FA = 1.23, + FB = 4.56, +} + +export enum EnumNone { + NA, + NB, +} + +export enum EnumStr { + SA = 's---a', + SB = 's---b', } export type UnionFloat = 1.44 | 2.88 | 5.76; @@ -43,7 +58,9 @@ export interface Spec extends TurboModule { +getArray: (arg: Array) => Array; +getBool: (arg: boolean) => boolean; +getConstants: () => ConstantsStruct; - +getEnum: (arg: EnumInt) => EnumInt; + +getCustomEnum: (arg: EnumInt) => EnumInt; + +getNumEnum: (arg: EnumInt) => EnumFloat; + +getStrEnum: (arg: EnumNone) => EnumStr; +getMap: (arg: {[key: string]: ?number}) => {[key: string]: ?number}; +getNumber: (arg: number) => number; +getObject: (arg: ObjectStruct) => ObjectStruct; diff --git a/packages/rn-tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js b/packages/rn-tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js index 9c2946883c5702..cecbacba004548 100644 --- a/packages/rn-tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js +++ b/packages/rn-tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js @@ -22,6 +22,7 @@ import { import * as React from 'react'; import NativeCxxModuleExample, { EnumInt, + EnumNone, } from '../../../NativeCxxModuleExample/NativeCxxModuleExample'; type State = {| @@ -40,7 +41,9 @@ type Examples = | 'getArray' | 'getBool' | 'getConstants' - | 'getEnum' + | 'getCustomEnum' + | 'getNumEnum' + | 'getStrEnum' | 'getMap' | 'getNumber' | 'getObject' @@ -74,8 +77,9 @@ class NativeCxxModuleExampleExample extends React.Component<{||}, State> { ]), getBool: () => NativeCxxModuleExample?.getBool(true), getConstants: () => NativeCxxModuleExample?.getConstants(), - getEnum: () => NativeCxxModuleExample?.getEnum(EnumInt.A), - getMap: () => NativeCxxModuleExample?.getMap({a: 1, b: null, c: 3}), + getCustomEnum: () => NativeCxxModuleExample?.getCustomEnum(EnumInt.IB), + getNumEnum: () => NativeCxxModuleExample?.getNumEnum(EnumInt.IB), + getStrEnum: () => NativeCxxModuleExample?.getStrEnum(EnumNone.NB), getNumber: () => NativeCxxModuleExample?.getNumber(99.95), getObject: () => NativeCxxModuleExample?.getObject({a: 1, b: 'foo', c: null}),