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<NativeProps>('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:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[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
This commit is contained in:
Tom Van Laerhoven 2024-11-20 16:25:34 -08:00 committed by Facebook GitHub Bot
parent aafe696453
commit 13780126d3
4 changed files with 26 additions and 2 deletions

View File

@ -23,6 +23,7 @@ type OnChangeEvent = $ReadOnly<{|
source: {url: string, ...}, source: {url: string, ...},
x: Int32, x: Int32,
y: Int32, y: Int32,
arrayOfObjects: $ReadOnlyArray<{value: $ReadOnly<{str: string}>}>,
... ...
}, },
|}>; |}>;

View File

@ -161,6 +161,20 @@ void EventNestedObjectPropsNativeComponentViewEventEmitter::onChange(OnChange $e
} }
location.setProperty(runtime, \\"x\\", $event.location.x); location.setProperty(runtime, \\"x\\", $event.location.x);
location.setProperty(runtime, \\"y\\", $event.location.y); 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); $payload.setProperty(runtime, \\"location\\", location);
} }
return $payload; return $payload;

View File

@ -199,10 +199,19 @@ class EventNestedObjectPropsNativeComponentViewEventEmitter : public ViewEventEm
std::string url; std::string url;
}; };
struct OnChangeLocationArrayOfObjectsValue {
std::string str;
};
struct OnChangeLocationArrayOfObjects {
OnChangeLocationArrayOfObjectsValue value;
};
struct OnChangeLocation { struct OnChangeLocation {
OnChangeLocationSource source; OnChangeLocationSource source;
int x; int x;
int y; int y;
std::vector<OnChangeLocationArrayOfObjects> arrayOfObjects;
}; };
struct OnChange { struct OnChange {

View File

@ -104,7 +104,7 @@ function generateSetter(
) { ) {
const eventChain = usingEvent const eventChain = usingEvent
? `$event.${[...propertyParts, propertyName].join('.')}` ? `$event.${[...propertyParts, propertyName].join('.')}`
: [propertyParts, propertyName].join('.'); : [...propertyParts, propertyName].join('.');
return `${variableName}.setProperty(runtime, "${propertyName}", ${valueMapper( return `${variableName}.setProperty(runtime, "${propertyName}", ${valueMapper(
eventChain, eventChain,
)});`; )});`;
@ -157,7 +157,7 @@ function generateArraySetter(
): string { ): string {
const eventChain = usingEvent const eventChain = usingEvent
? `$event.${[...propertyParts, propertyName].join('.')}` ? `$event.${[...propertyParts, propertyName].join('.')}`
: [propertyParts, propertyName].join('.'); : [...propertyParts, propertyName].join('.');
const indexVar = `${propertyName}Index`; const indexVar = `${propertyName}Index`;
const innerLoopVar = `${propertyName}Value`; const innerLoopVar = `${propertyName}Value`;
return ` return `