From 13780126d3cb17ad00c2954f9830a3623812dc3e Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Wed, 20 Nov 2024 16:25:34 -0800 Subject: [PATCH] Fix generated EventEmitter code for nested objects in arrays. (#47514) Summary: This PR fixes the code for generating EventEmitter C++ code in case nested objects in arrays are used. ```typescript export interface NativeProps extends ViewProps { onEvent: DirectEventHandler< Readonly<{ payloadArray: Readonly< { obj: Readonly<{ str: string }> }[] > }> >; } export default codegenNativeComponent('SomeComponent'); ``` In this case the generated `EventEmitters.cpp` code would contain: ```c obj.setProperty(runtime, "str", payloadArrayValue,obj.str); ``` while ```c obj.setProperty(runtime, "str", payloadArrayValue.obj.str); ``` is expected. ## Changelog: [GENERAL] [FIXED] - Codegen: Support nested objects in arrays Pull Request resolved: https://github.com/facebook/react-native/pull/47514 Test Plan: Tested with the reproduction case above to verify correct output. Reviewed By: javache Differential Revision: D65848670 Pulled By: elicwhite fbshipit-source-id: 0021e87bc7213fff615465cab8554cc1a2159522 --- .../EventNestedObjectPropsNativeComponent.js | 1 + .../GenerateEventEmitterCpp-test.js.snap | 14 ++++++++++++++ .../GenerateEventEmitterH-test.js.snap | 9 +++++++++ .../components/GenerateEventEmitterCpp.js | 4 ++-- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/react-native-codegen/e2e/__test_fixtures__/components/EventNestedObjectPropsNativeComponent.js b/packages/react-native-codegen/e2e/__test_fixtures__/components/EventNestedObjectPropsNativeComponent.js index 8e0b0fc5d7c..6d8471c4598 100644 --- a/packages/react-native-codegen/e2e/__test_fixtures__/components/EventNestedObjectPropsNativeComponent.js +++ b/packages/react-native-codegen/e2e/__test_fixtures__/components/EventNestedObjectPropsNativeComponent.js @@ -23,6 +23,7 @@ type OnChangeEvent = $ReadOnly<{| source: {url: string, ...}, x: Int32, y: Int32, + arrayOfObjects: $ReadOnlyArray<{value: $ReadOnly<{str: string}>}>, ... }, |}>; diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterCpp-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterCpp-test.js.snap index a53541759bf..cd64459983a 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterCpp-test.js.snap @@ -161,6 +161,20 @@ void EventNestedObjectPropsNativeComponentViewEventEmitter::onChange(OnChange $e } location.setProperty(runtime, \\"x\\", $event.location.x); location.setProperty(runtime, \\"y\\", $event.location.y); + + auto arrayOfObjects = jsi::Array(runtime, $event.location.arrayOfObjects.size()); + size_t arrayOfObjectsIndex = 0; + for (auto arrayOfObjectsValue : $event.location.arrayOfObjects) { + auto arrayOfObjectsObject = jsi::Object(runtime); + { + auto value = jsi::Object(runtime); + value.setProperty(runtime, \\"str\\", arrayOfObjectsValue.value.str); + arrayOfObjectsObject.setProperty(runtime, \\"value\\", value); + } + arrayOfObjects.setValueAtIndex(runtime, arrayOfObjectsIndex++, arrayOfObjectsObject); + } + location.setProperty(runtime, \\"arrayOfObjects\\", arrayOfObjects); + $payload.setProperty(runtime, \\"location\\", location); } return $payload; diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterH-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterH-test.js.snap index 9ae54de91b3..d44312f48b6 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterH-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GenerateEventEmitterH-test.js.snap @@ -199,10 +199,19 @@ class EventNestedObjectPropsNativeComponentViewEventEmitter : public ViewEventEm std::string url; }; + struct OnChangeLocationArrayOfObjectsValue { + std::string str; + }; + + struct OnChangeLocationArrayOfObjects { + OnChangeLocationArrayOfObjectsValue value; + }; + struct OnChangeLocation { OnChangeLocationSource source; int x; int y; + std::vector arrayOfObjects; }; struct OnChange { diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js index 2f2a829d199..d6fbdbaa952 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js @@ -104,7 +104,7 @@ function generateSetter( ) { const eventChain = usingEvent ? `$event.${[...propertyParts, propertyName].join('.')}` - : [propertyParts, propertyName].join('.'); + : [...propertyParts, propertyName].join('.'); return `${variableName}.setProperty(runtime, "${propertyName}", ${valueMapper( eventChain, )});`; @@ -157,7 +157,7 @@ function generateArraySetter( ): string { const eventChain = usingEvent ? `$event.${[...propertyParts, propertyName].join('.')}` - : [propertyParts, propertyName].join('.'); + : [...propertyParts, propertyName].join('.'); const indexVar = `${propertyName}Index`; const innerLoopVar = `${propertyName}Value`; return `