-
Notifications
You must be signed in to change notification settings - Fork 25k
Make C++ struct generator type-safe #35656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
This pull request was exported from Phabricator. Differential Revision: D42082423 |
Base commit: 03b17d9 |
Base commit: 03b17d9 |
|
PR build artifact for 95917ee is ready. |
|
PR build artifact for 95917ee is ready. |
Summary: Pull Request resolved: facebook#35656 Changelog: [Internal] ## Change: facebook#35265 added a struct generator - but it is not type safe :-( E.g. you can write a TM Spec type as: ``` export type CustomType = { key: string; enabled: boolean; time?: number; } ``` And a C++ type as: ``` using CustomType = NativeSampleModuleBaseCustomType<float, bool, std::optional<int32_t>>; template <> struct Bridging<CustomType> : NativeSampleModuleBaseCustomTypeBridging<float, bool, std::optional<int32_t>> {}; ``` and it will still compile :-( - which should not. The reason is that the generated structs don't validate the members type :-( ``` template <typename P0, typename P1, typename P2> struct NativeSampleModuleBaseCustomType { P0 key; P1 enabled; P2 time; bool operator==(const NativeSampleModuleBaseCustomType &other) const { return key == other.key && enabled == other.enabled && time == other.time; } }; template <typename P0, typename P1, typename P2> struct NativeSampleModuleBaseCustomTypeBridging { static NativeSampleModuleBaseCustomType<P0, P1, P2> fromJs( jsi::Runtime &rt, const jsi::Object &value, const std::shared_ptr<CallInvoker> &jsInvoker) { NativeSampleModuleBaseCustomType<P0, P1, P2> result{ bridging::fromJs<P0>(rt, value.getProperty(rt, "key"), jsInvoker), bridging::fromJs<P1>(rt, value.getProperty(rt, "enabled"), jsInvoker), bridging::fromJs<P2>(rt, value.getProperty(rt, "time"), jsInvoker)}; return result; } static jsi::Object toJs( jsi::Runtime &rt, const NativeSampleModuleBaseCustomType<P0, P1, P2> &value) { auto result = facebook::jsi::Object(rt); result.setProperty(rt, "key", bridging::toJs(rt, value.key)); result.setProperty(rt, "enabled", bridging::toJs(rt, value.enabled)); if (value.time) { result.setProperty(rt, "time", bridging::toJs(rt, value.time.value())); } keyToJs(rt, value.key); return result; } }; ``` This fixes that, by simply emitting conversion functions for each member such as ``` #ifdef DEBUG static bool keyToJs(jsi::Runtime &rt, P0 value) { return bridging::toJs(rt, value); } static double enabledToJs(jsi::Runtime &rt, P1 value) { return bridging::toJs(rt, value); } static jsi::String timeToJs(jsi::Runtime &rt, P2 value) { return bridging::toJs(rt, value); } #endif ``` Differential Revision: D42082423 fbshipit-source-id: c7857944ba5d5a57623fc627df4d885867b025cf
|
This pull request was exported from Phabricator. Differential Revision: D42082423 |
95917ee to
8ce46eb
Compare
|
PR build artifact for 8ce46eb is ready. |
|
PR build artifact for 8ce46eb is ready. |
|
This pull request has been merged in c7e1e00. |
Summary: Pull Request resolved: facebook#35656 Changelog: [Internal] ## Change: facebook#35265 added a struct generator - but it is not type safe :-( E.g. you can write a TM Spec type as: ``` export type CustomType = { key: string; enabled: boolean; time?: number; } ``` And a C++ type as: ``` using CustomType = NativeSampleModuleBaseCustomType<float, bool, std::optional<int32_t>>; template <> struct Bridging<CustomType> : NativeSampleModuleBaseCustomTypeBridging<float, bool, std::optional<int32_t>> {}; ``` and it will still compile :-( - which should not. The reason is that the generated structs don't validate the members type :-( ``` template <typename P0, typename P1, typename P2> struct NativeSampleModuleBaseCustomType { P0 key; P1 enabled; P2 time; bool operator==(const NativeSampleModuleBaseCustomType &other) const { return key == other.key && enabled == other.enabled && time == other.time; } }; template <typename P0, typename P1, typename P2> struct NativeSampleModuleBaseCustomTypeBridging { static NativeSampleModuleBaseCustomType<P0, P1, P2> fromJs( jsi::Runtime &rt, const jsi::Object &value, const std::shared_ptr<CallInvoker> &jsInvoker) { NativeSampleModuleBaseCustomType<P0, P1, P2> result{ bridging::fromJs<P0>(rt, value.getProperty(rt, "key"), jsInvoker), bridging::fromJs<P1>(rt, value.getProperty(rt, "enabled"), jsInvoker), bridging::fromJs<P2>(rt, value.getProperty(rt, "time"), jsInvoker)}; return result; } static jsi::Object toJs( jsi::Runtime &rt, const NativeSampleModuleBaseCustomType<P0, P1, P2> &value) { auto result = facebook::jsi::Object(rt); result.setProperty(rt, "key", bridging::toJs(rt, value.key)); result.setProperty(rt, "enabled", bridging::toJs(rt, value.enabled)); if (value.time) { result.setProperty(rt, "time", bridging::toJs(rt, value.time.value())); } keyToJs(rt, value.key); return result; } }; ``` This fixes that, by simply emitting conversion functions for each member such as ``` #ifdef DEBUG static bool keyToJs(jsi::Runtime &rt, P0 value) { return bridging::toJs(rt, value); } static double enabledToJs(jsi::Runtime &rt, P1 value) { return bridging::toJs(rt, value); } static jsi::String timeToJs(jsi::Runtime &rt, P2 value) { return bridging::toJs(rt, value); } #endif ``` Reviewed By: cipolleschi Differential Revision: D42082423 fbshipit-source-id: 5133f14e2aa8351e9bbbf614117a3d5894b17fa6
Summary:
Changelog: [Internal]
Change:
#35265 added a struct generator - but it is not type safe :-(
E.g. you can write a TM Spec type as:
And a C++ type as:
and it will still compile :-( - which should not.
The reason is that the generated structs don't validate the members type :-(
This fixes that, by simply emitting conversion functions for each member such as
Differential Revision: D42082423