From 8cff7d625b0496f25f81f9869db3c54bf62f3b17 Mon Sep 17 00:00:00 2001 From: Genki Kondo Date: Tue, 18 Apr 2023 13:35:45 -0700 Subject: [PATCH] Support events with mixed payloads in codegen (#36942) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/36942 Changelog: [General][Changed] - Support mixed props for events in codegen Reviewed By: javache Differential Revision: D44580879 fbshipit-source-id: 52f3b12795af767c038e2db7a4faf46cf2906b95 --- .../GenerateEventEmitterCpp-test.js.snap | 30 +++++-- .../GenerateEventEmitterH-test.js.snap | 36 ++++---- .../GeneratePropsCpp-test.js.snap | 1 + .../react-native-codegen/src/CodegenSchema.js | 1 + .../src/generators/components/CppHelpers.js | 22 +++-- .../components/GenerateEventEmitterCpp.js | 83 +++++++++++-------- .../components/GenerateEventEmitterH.js | 64 ++++++++------ .../components/__test_fixtures__/fixtures.js | 22 ++++- .../GenerateEventEmitterCpp-test.js.snap | 54 ++++++++++-- .../GenerateEventEmitterH-test.js.snap | 69 +++++++-------- .../GeneratePropsCpp-test.js.snap | 1 + .../__snapshots__/GenerateTests-test.js.snap | 1 + .../GenerateViewConfigJs-test.js.snap | 9 +- .../src/parsers/flow/components/events.js | 8 ++ .../parsers/typescript/components/events.js | 9 +- 15 files changed, 275 insertions(+), 135 deletions(-) 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 1cb94bde240eed..433dcad81d4097 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 @@ -14,6 +14,7 @@ Object { #include + namespace facebook { namespace react { @@ -37,6 +38,7 @@ Object { #include + namespace facebook { namespace react { @@ -60,6 +62,7 @@ Object { #include + namespace facebook { namespace react { @@ -83,6 +86,7 @@ Object { #include + namespace facebook { namespace react { @@ -106,6 +110,7 @@ Object { #include + namespace facebook { namespace react { @@ -129,6 +134,7 @@ Object { #include + namespace facebook { namespace react { @@ -152,6 +158,7 @@ Object { #include + namespace facebook { namespace react { @@ -161,12 +168,12 @@ void EventNestedObjectPropsNativeComponentViewEventEmitter::onChange(OnChange $e { auto location = jsi::Object(runtime); { - auto source = jsi::Object(runtime); - source.setProperty(runtime, \\"url\\", $event.location.source.url); - location.setProperty(runtime, \\"source\\", source); -} -location.setProperty(runtime, \\"x\\", $event.location.x); -location.setProperty(runtime, \\"y\\", $event.location.y); + auto source = jsi::Object(runtime); + source.setProperty(runtime, \\"url\\", $event.location.source.url); + location.setProperty(runtime, \\"source\\", source); + } + location.setProperty(runtime, \\"x\\", $event.location.x); + location.setProperty(runtime, \\"y\\", $event.location.y); $payload.setProperty(runtime, \\"location\\", location); } return $payload; @@ -193,6 +200,7 @@ Object { #include + namespace facebook { namespace react { @@ -272,6 +280,7 @@ Object { #include + namespace facebook { namespace react { @@ -295,6 +304,7 @@ Object { #include + namespace facebook { namespace react { @@ -318,6 +328,7 @@ Object { #include + namespace facebook { namespace react { @@ -341,6 +352,7 @@ Object { #include + namespace facebook { namespace react { @@ -372,6 +384,7 @@ Object { #include + namespace facebook { namespace react { @@ -395,6 +408,7 @@ Object { #include + namespace facebook { namespace react { @@ -418,6 +432,7 @@ Object { #include + namespace facebook { namespace react { @@ -441,6 +456,7 @@ Object { #include + namespace facebook { namespace react { @@ -464,6 +480,7 @@ Object { #include + namespace facebook { namespace react { @@ -487,6 +504,7 @@ Object { #include + namespace facebook { namespace react { 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 91ce1ab038e8b0..876d46a03a124e 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 @@ -16,6 +16,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT ArrayPropsNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -23,7 +24,6 @@ class JSI_EXPORT ArrayPropsNativeComponentViewEventEmitter : public ViewEventEmi using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -48,6 +48,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT BooleanPropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -55,7 +56,6 @@ class JSI_EXPORT BooleanPropNativeComponentViewEventEmitter : public ViewEventEm using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -80,6 +80,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT ColorPropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -87,7 +88,6 @@ class JSI_EXPORT ColorPropNativeComponentViewEventEmitter : public ViewEventEmit using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -112,6 +112,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT DimensionPropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -119,7 +120,6 @@ class JSI_EXPORT DimensionPropNativeComponentViewEventEmitter : public ViewEvent using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -144,6 +144,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT EdgeInsetsPropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -151,7 +152,6 @@ class JSI_EXPORT EdgeInsetsPropNativeComponentViewEventEmitter : public ViewEven using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -176,6 +176,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT EnumPropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -183,7 +184,6 @@ class JSI_EXPORT EnumPropNativeComponentViewEventEmitter : public ViewEventEmitt using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -208,6 +208,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT EventNestedObjectPropsNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -227,7 +228,6 @@ class JSI_EXPORT EventNestedObjectPropsNativeComponentViewEventEmitter : public struct OnChange { OnChangeLocation location; }; - void onChange(OnChange value) const; }; } // namespace react @@ -252,6 +252,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT EventPropsNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -296,7 +297,6 @@ class JSI_EXPORT EventPropsNativeComponentViewEventEmitter : public ViewEventEmi struct OnEventBubblingWithPaperName { }; - void onChange(OnChange value) const; void onEventDirect(OnEventDirect value) const; @@ -331,6 +331,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT FloatPropsNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -338,7 +339,6 @@ class JSI_EXPORT FloatPropsNativeComponentViewEventEmitter : public ViewEventEmi using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -363,6 +363,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT ImagePropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -370,7 +371,6 @@ class JSI_EXPORT ImagePropNativeComponentViewEventEmitter : public ViewEventEmit using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -395,6 +395,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT IntegerPropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -402,7 +403,6 @@ class JSI_EXPORT IntegerPropNativeComponentViewEventEmitter : public ViewEventEm using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -427,6 +427,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT InterfaceOnlyNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -436,7 +437,6 @@ class JSI_EXPORT InterfaceOnlyNativeComponentViewEventEmitter : public ViewEvent struct OnChange { bool value; }; - void onChange(OnChange value) const; }; } // namespace react @@ -461,6 +461,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT MixedPropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -468,7 +469,6 @@ class JSI_EXPORT MixedPropNativeComponentViewEventEmitter : public ViewEventEmit using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -493,6 +493,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT MultiNativePropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -500,7 +501,6 @@ class JSI_EXPORT MultiNativePropNativeComponentViewEventEmitter : public ViewEve using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -525,6 +525,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT NoPropsNoEventsNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -532,7 +533,6 @@ class JSI_EXPORT NoPropsNoEventsNativeComponentViewEventEmitter : public ViewEve using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -557,6 +557,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT ObjectPropsNativeComponentEventEmitter : public ViewEventEmitter { @@ -564,7 +565,6 @@ class JSI_EXPORT ObjectPropsNativeComponentEventEmitter : public ViewEventEmitte using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -589,6 +589,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT PointPropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -596,7 +597,6 @@ class JSI_EXPORT PointPropNativeComponentViewEventEmitter : public ViewEventEmit using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -621,6 +621,7 @@ Object { #include #include + namespace facebook { namespace react { class JSI_EXPORT StringPropNativeComponentViewEventEmitter : public ViewEventEmitter { @@ -628,7 +629,6 @@ class JSI_EXPORT StringPropNativeComponentViewEventEmitter : public ViewEventEmi using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react diff --git a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap index 08c596c6cc90c6..bcb7abfc4404e6 100644 --- a/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/__tests__/components/__snapshots__/GeneratePropsCpp-test.js.snap @@ -434,6 +434,7 @@ Object { */ #include +#include #include #include diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 6265482f91dbf8..361d54ef75c596 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -126,6 +126,7 @@ export type EventTypeAnnotation = | DoubleTypeAnnotation | FloatTypeAnnotation | Int32TypeAnnotation + | MixedTypeAnnotation | StringEnumTypeAnnotation | ObjectTypeAnnotation; diff --git a/packages/react-native-codegen/src/generators/components/CppHelpers.js b/packages/react-native-codegen/src/generators/components/CppHelpers.js index c7fbff186de863..e1fbfb79dc1d7b 100644 --- a/packages/react-native-codegen/src/generators/components/CppHelpers.js +++ b/packages/react-native-codegen/src/generators/components/CppHelpers.js @@ -9,7 +9,11 @@ */ 'use strict'; -import type {NamedShape, PropTypeAnnotation} from '../../CodegenSchema'; +import type { + EventTypeAnnotation, + NamedShape, + PropTypeAnnotation, +} from '../../CodegenSchema'; const {getEnumName, toSafeCppString} = require('../Utils'); @@ -23,7 +27,8 @@ function getCppTypeForAnnotation( | 'StringTypeAnnotation' | 'Int32TypeAnnotation' | 'DoubleTypeAnnotation' - | 'FloatTypeAnnotation', + | 'FloatTypeAnnotation' + | 'MixedTypeAnnotation', ): string { switch (type) { case 'BooleanTypeAnnotation': @@ -36,6 +41,8 @@ function getCppTypeForAnnotation( return 'double'; case 'FloatTypeAnnotation': return 'Float'; + case 'MixedTypeAnnotation': + return 'folly::dynamic'; default: (type: empty); throw new Error(`Received invalid typeAnnotation ${type}`); @@ -43,7 +50,9 @@ function getCppTypeForAnnotation( } function getImports( - properties: $ReadOnlyArray>, + properties: + | $ReadOnlyArray> + | $ReadOnlyArray>, ): Set { const imports: Set = new Set(); @@ -91,6 +100,10 @@ function getImports( addImportsForNativeName(typeAnnotation.elementType.name); } + if (typeAnnotation.type === 'MixedTypeAnnotation') { + imports.add('#include '); + } + if (typeAnnotation.type === 'ObjectTypeAnnotation') { const objectImports = getImports(typeAnnotation.properties); // $FlowFixMe[method-unbinding] added when improving typing for this parameters @@ -102,8 +115,7 @@ function getImports( } function generateEventStructName(parts: $ReadOnlyArray = []): string { - const additional = parts.map(toSafeCppString).join(''); - return `${additional}`; + return parts.map(toSafeCppString).join(''); } function generateStructName( diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js index dc3d4c631ab767..ff478d78feae4b 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterCpp.js @@ -11,7 +11,8 @@ 'use strict'; import type {EventTypeShape} from '../../CodegenSchema'; -const {generateEventStructName} = require('./CppHelpers.js'); +const {generateEventStructName} = require('./CppHelpers'); +const {indent} = require('../Utils'); import type { ComponentShape, @@ -32,9 +33,11 @@ type ComponentCollection = $ReadOnly<{ const FileTemplate = ({ events, libraryName, + extraIncludes, }: { events: string, libraryName: string, + extraIncludes: Set, }) => ` /** * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). @@ -46,6 +49,7 @@ const FileTemplate = ({ */ #include +${[...extraIncludes].join('\n')} namespace facebook { namespace react { @@ -98,26 +102,12 @@ function generateSetter( variableName: string, propertyName: string, propertyParts: $ReadOnlyArray, + valueMapper: string => string = value => value, ) { - const trailingPeriod = propertyParts.length === 0 ? '' : '.'; - const eventChain = `$event.${propertyParts.join( - '.', - )}${trailingPeriod}${propertyName});`; - - return `${variableName}.setProperty(runtime, "${propertyName}", ${eventChain}`; -} - -function generateEnumSetter( - variableName: string, - propertyName: string, - propertyParts: $ReadOnlyArray, -) { - const trailingPeriod = propertyParts.length === 0 ? '' : '.'; - const eventChain = `$event.${propertyParts.join( - '.', - )}${trailingPeriod}${propertyName})`; - - return `${variableName}.setProperty(runtime, "${propertyName}", toString(${eventChain});`; + const eventChain = `$event.${[...propertyParts, propertyName].join('.')}`; + return `${variableName}.setProperty(runtime, "${propertyName}", ${valueMapper( + eventChain, + )});`; } function generateObjectSetter( @@ -125,14 +115,19 @@ function generateObjectSetter( propertyName: string, propertyParts: $ReadOnlyArray, typeAnnotation: ObjectTypeAnnotation, + extraIncludes: Set, ) { return ` { auto ${propertyName} = jsi::Object(runtime); - ${generateSetters( - propertyName, - typeAnnotation.properties, - propertyParts.concat([propertyName]), + ${indent( + generateSetters( + propertyName, + typeAnnotation.properties, + propertyParts.concat([propertyName]), + extraIncludes, + ), + 2, )} ${variableName}.setProperty(runtime, "${propertyName}", ${propertyName}); } @@ -143,6 +138,7 @@ function generateSetters( parentPropertyName: string, properties: $ReadOnlyArray>, propertyParts: $ReadOnlyArray, + extraIncludes: Set, ): string { const propSetters = properties .map(eventProperty => { @@ -158,11 +154,20 @@ function generateSetters( eventProperty.name, propertyParts, ); + case 'MixedTypeAnnotation': + extraIncludes.add('#include '); + return generateSetter( + parentPropertyName, + eventProperty.name, + propertyParts, + prop => `jsi::valueFromDynamic(runtime, ${prop})`, + ); case 'StringEnumTypeAnnotation': - return generateEnumSetter( + return generateSetter( parentPropertyName, eventProperty.name, propertyParts, + prop => `toString(${prop})`, ); case 'ObjectTypeAnnotation': return generateObjectSetter( @@ -170,10 +175,13 @@ function generateSetters( eventProperty.name, propertyParts, typeAnnotation, + extraIncludes, ); default: (typeAnnotation.type: empty); - throw new Error('Received invalid event property type'); + throw new Error( + `Received invalid event property type ${typeAnnotation.type}`, + ); } }) .join('\n'); @@ -181,7 +189,11 @@ function generateSetters( return propSetters; } -function generateEvent(componentName: string, event: EventTypeShape): string { +function generateEvent( + componentName: string, + event: EventTypeShape, + extraIncludes: Set, +): string { // This is a gross hack necessary because native code is sending // events named things like topChange to JS which is then converted back to // call the onChange prop. We should be consistent throughout the system. @@ -195,7 +207,12 @@ function generateEvent(componentName: string, event: EventTypeShape): string { if (event.typeAnnotation.argument) { const implementation = ` auto $payload = jsi::Object(runtime); - ${generateSetters('$payload', event.typeAnnotation.argument.properties, [])} + ${generateSetters( + '$payload', + event.typeAnnotation.argument.properties, + [], + extraIncludes, + )} return $payload; `.trim(); @@ -244,23 +261,21 @@ module.exports = { .filter(Boolean) .reduce((acc, components) => Object.assign(acc, components), {}); - const fileName = 'EventEmitters.cpp'; - + const extraIncludes = new Set(); const componentEmitters = Object.keys(moduleComponents) .map(componentName => { const component = moduleComponents[componentName]; - return component.events - .map(event => { - return generateEvent(componentName, event); - }) + .map(event => generateEvent(componentName, event, extraIncludes)) .join('\n'); }) .join('\n'); + const fileName = 'EventEmitters.cpp'; const replacedTemplate = FileTemplate({ libraryName, events: componentEmitters, + extraIncludes, }); return new Map([[fileName, replacedTemplate]]); diff --git a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js index e2ee2a6adcfaac..fcb082d74b8c9b 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js +++ b/packages/react-native-codegen/src/generators/components/GenerateEventEmitterH.js @@ -13,6 +13,7 @@ const nullthrows = require('nullthrows'); const { + getImports, getCppTypeForAnnotation, generateEventStructName, } = require('./CppHelpers'); @@ -35,7 +36,13 @@ type ComponentCollection = $ReadOnly<{ ... }>; -const FileTemplate = ({componentEmitters}: {componentEmitters: string}) => ` +const FileTemplate = ({ + componentEmitters, + extraIncludes, +}: { + componentEmitters: string, + extraIncludes: Set, +}) => ` /** * This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen). * @@ -48,6 +55,7 @@ const FileTemplate = ({componentEmitters}: {componentEmitters: string}) => ` #include #include +${[...extraIncludes].join('\n')} namespace facebook { namespace react { @@ -71,7 +79,6 @@ class JSI_EXPORT ${className}EventEmitter : public ViewEventEmitter { using ViewEventEmitter::ViewEventEmitter; ${structs} - ${events} }; `.trim(); @@ -122,11 +129,11 @@ function getNativeTypeFromAnnotation( case 'Int32TypeAnnotation': case 'DoubleTypeAnnotation': case 'FloatTypeAnnotation': + case 'MixedTypeAnnotation': return getCppTypeForAnnotation(type); case 'StringEnumTypeAnnotation': - return generateEventStructName(nameParts.concat([eventProperty.name])); case 'ObjectTypeAnnotation': - return generateEventStructName(nameParts.concat([eventProperty.name])); + return generateEventStructName([...nameParts, eventProperty.name]); default: (type: empty); throw new Error(`Received invalid event property type ${type}`); @@ -182,14 +189,11 @@ function generateStruct( const {name, typeAnnotation} = property; switch (typeAnnotation.type) { case 'BooleanTypeAnnotation': - return; case 'StringTypeAnnotation': - return; case 'Int32TypeAnnotation': - return; case 'DoubleTypeAnnotation': - return; case 'FloatTypeAnnotation': + case 'MixedTypeAnnotation': return; case 'ObjectTypeAnnotation': generateStruct( @@ -282,29 +286,35 @@ module.exports = { .filter(Boolean) .reduce((acc, components) => Object.assign(acc, components), {}); - const moduleComponentsWithEvents = Object.keys(moduleComponents); + const extraIncludes = new Set(); + const componentEmitters = Object.keys(moduleComponents) + .map(componentName => { + const component = moduleComponents[componentName]; + + component.events.forEach(event => { + if (event.typeAnnotation.argument) { + const argIncludes = getImports( + event.typeAnnotation.argument.properties, + ); + // $FlowFixMe[method-unbinding] + argIncludes.forEach(extraIncludes.add, extraIncludes); + } + }); + + const replacedTemplate = ComponentTemplate({ + className: componentName, + structs: indent(generateStructs(componentName, component), 2), + events: generateEvents(componentName, component), + }); + + return replacedTemplate; + }) + .join('\n'); const fileName = 'EventEmitters.h'; - - const componentEmitters = - moduleComponentsWithEvents.length > 0 - ? Object.keys(moduleComponents) - .map(componentName => { - const component = moduleComponents[componentName]; - - const replacedTemplate = ComponentTemplate({ - className: componentName, - structs: indent(generateStructs(componentName, component), 2), - events: generateEvents(componentName, component), - }); - - return replacedTemplate; - }) - .join('\n') - : ''; - const replacedTemplate = FileTemplate({ componentEmitters, + extraIncludes, }); return new Map([[fileName, replacedTemplate]]); diff --git a/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js index 57997808f52192..e5401bb4e7146c 100644 --- a/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js @@ -123,7 +123,7 @@ const EVENTS_WITH_PAPER_NAME: SchemaType = { }, }, { - name: 'onDire tChange', + name: 'onDirectChange', paperTopLevelNameDeprecated: 'paperDirectChange', optional: true, bubblingType: 'direct', @@ -1255,6 +1255,26 @@ const EVENT_PROPS: SchemaType = { type: 'EventTypeAnnotation', }, }, + { + name: 'onEventWithMixedPropAttribute', + optional: true, + bubblingType: 'direct', + typeAnnotation: { + type: 'EventTypeAnnotation', + argument: { + type: 'ObjectTypeAnnotation', + properties: [ + { + name: 'value', + optional: false, + typeAnnotation: { + type: 'MixedTypeAnnotation', + }, + }, + ], + }, + }, + }, ], props: [ { diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap index 6241e0dd1de538..68fc88ff7a1818 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap @@ -14,6 +14,7 @@ Map { #include + namespace facebook { namespace react { @@ -37,6 +38,7 @@ Map { #include + namespace facebook { namespace react { @@ -60,6 +62,7 @@ Map { #include + namespace facebook { namespace react { @@ -83,6 +86,7 @@ Map { #include + namespace facebook { namespace react { @@ -106,6 +110,7 @@ Map { #include + namespace facebook { namespace react { @@ -129,6 +134,7 @@ Map { #include + namespace facebook { namespace react { @@ -152,6 +158,7 @@ Map { #include + namespace facebook { namespace react { @@ -175,6 +182,7 @@ Map { #include + namespace facebook { namespace react { @@ -198,6 +206,7 @@ Map { #include + namespace facebook { namespace react { @@ -207,12 +216,12 @@ void EventsNestedObjectNativeComponentEventEmitter::onChange(OnChange $event) co { auto location = jsi::Object(runtime); { - auto source = jsi::Object(runtime); - source.setProperty(runtime, \\"url\\", $event.location.source.url); - location.setProperty(runtime, \\"source\\", source); -} -location.setProperty(runtime, \\"x\\", $event.location.x); -location.setProperty(runtime, \\"y\\", $event.location.y); + auto source = jsi::Object(runtime); + source.setProperty(runtime, \\"url\\", $event.location.source.url); + location.setProperty(runtime, \\"source\\", source); + } + location.setProperty(runtime, \\"x\\", $event.location.x); + location.setProperty(runtime, \\"y\\", $event.location.y); $payload.setProperty(runtime, \\"location\\", location); } return $payload; @@ -238,6 +247,7 @@ Map { */ #include +#include namespace facebook { namespace react { @@ -274,6 +284,15 @@ void EventsNativeComponentEventEmitter::onOrientationChange(OnOrientationChange void EventsNativeComponentEventEmitter::onEnd() const { dispatchEvent(\\"end\\"); } + +void EventsNativeComponentEventEmitter::onEventWithMixedPropAttribute(OnEventWithMixedPropAttribute $event) const { + dispatchEvent(\\"eventWithMixedPropAttribute\\", [$event=std::move($event)](jsi::Runtime &runtime) { + auto $payload = jsi::Object(runtime); + $payload.setProperty(runtime, \\"value\\", jsi::valueFromDynamic(runtime, $event.value)); + return $payload; + }); +} + } // namespace react } // namespace facebook ", @@ -294,6 +313,7 @@ Map { #include + namespace facebook { namespace react { @@ -306,8 +326,8 @@ void InterfaceOnlyComponentEventEmitter::onChange(OnChange $event) const { } -void InterfaceOnlyComponentEventEmitter::onDire tChange(OnDire tChange $event) const { - dispatchEvent(\\"dire tChange\\", [$event=std::move($event)](jsi::Runtime &runtime) { +void InterfaceOnlyComponentEventEmitter::onDirectChange(OnDirectChange $event) const { + dispatchEvent(\\"directChange\\", [$event=std::move($event)](jsi::Runtime &runtime) { auto $payload = jsi::Object(runtime); $payload.setProperty(runtime, \\"value\\", $event.value); return $payload; @@ -334,6 +354,7 @@ Map { #include + namespace facebook { namespace react { @@ -357,6 +378,7 @@ Map { #include + namespace facebook { namespace react { @@ -380,6 +402,7 @@ Map { #include + namespace facebook { namespace react { @@ -404,6 +427,7 @@ Map { #include + namespace facebook { namespace react { @@ -427,6 +451,7 @@ Map { #include + namespace facebook { namespace react { @@ -450,6 +475,7 @@ Map { #include + namespace facebook { namespace react { @@ -473,6 +499,7 @@ Map { #include + namespace facebook { namespace react { @@ -496,6 +523,7 @@ Map { #include + namespace facebook { namespace react { @@ -519,6 +547,7 @@ Map { #include + namespace facebook { namespace react { @@ -550,6 +579,7 @@ Map { #include + namespace facebook { namespace react { @@ -573,6 +603,7 @@ Map { #include + namespace facebook { namespace react { @@ -596,6 +627,7 @@ Map { #include + namespace facebook { namespace react { @@ -619,6 +651,7 @@ Map { #include + namespace facebook { namespace react { @@ -642,6 +675,7 @@ Map { #include + namespace facebook { namespace react { @@ -665,6 +699,7 @@ Map { #include + namespace facebook { namespace react { @@ -688,6 +723,7 @@ Map { #include + namespace facebook { namespace react { @@ -711,6 +747,7 @@ Map { #include + namespace facebook { namespace react { @@ -735,6 +772,7 @@ Map { #include + namespace facebook { namespace react { diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap index 5cd372345ea4ac..e3f05af240c2d9 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap @@ -16,6 +16,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT ArrayPropsNativeComponentEventEmitter : public ViewEventEmitter { @@ -23,7 +24,6 @@ class JSI_EXPORT ArrayPropsNativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -48,6 +48,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT ArrayPropsNativeComponentEventEmitter : public ViewEventEmitter { @@ -55,7 +56,6 @@ class JSI_EXPORT ArrayPropsNativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -80,6 +80,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT BooleanPropNativeComponentEventEmitter : public ViewEventEmitter { @@ -87,7 +88,6 @@ class JSI_EXPORT BooleanPropNativeComponentEventEmitter : public ViewEventEmitte using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -112,6 +112,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT ColorPropNativeComponentEventEmitter : public ViewEventEmitter { @@ -119,7 +120,6 @@ class JSI_EXPORT ColorPropNativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -144,6 +144,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT CommandNativeComponentEventEmitter : public ViewEventEmitter { @@ -151,7 +152,6 @@ class JSI_EXPORT CommandNativeComponentEventEmitter : public ViewEventEmitter { using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -176,6 +176,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT CommandNativeComponentEventEmitter : public ViewEventEmitter { @@ -183,7 +184,6 @@ class JSI_EXPORT CommandNativeComponentEventEmitter : public ViewEventEmitter { using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -208,6 +208,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT DimensionPropNativeComponentEventEmitter : public ViewEventEmitter { @@ -215,7 +216,6 @@ class JSI_EXPORT DimensionPropNativeComponentEventEmitter : public ViewEventEmit using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -240,6 +240,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT DoublePropNativeComponentEventEmitter : public ViewEventEmitter { @@ -247,7 +248,6 @@ class JSI_EXPORT DoublePropNativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -272,6 +272,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT EventsNestedObjectNativeComponentEventEmitter : public ViewEventEmitter { @@ -291,7 +292,6 @@ class JSI_EXPORT EventsNestedObjectNativeComponentEventEmitter : public ViewEven struct OnChange { OnChangeLocation location; }; - void onChange(OnChange value) const; }; } // namespace react @@ -315,6 +315,7 @@ Map { #include #include +#include namespace facebook { namespace react { @@ -349,6 +350,9 @@ class JSI_EXPORT EventsNativeComponentEventEmitter : public ViewEventEmitter { OnOrientationChangeOrientation orientation; }; + struct OnEventWithMixedPropAttribute { + folly::dynamic value; + }; void onChange(OnChange value) const; void onEventDirect(OnEventDirect value) const; @@ -356,6 +360,8 @@ class JSI_EXPORT EventsNativeComponentEventEmitter : public ViewEventEmitter { void onOrientationChange(OnOrientationChange value) const; void onEnd() const; + + void onEventWithMixedPropAttribute(OnEventWithMixedPropAttribute value) const; }; } // namespace react } // namespace facebook @@ -379,6 +385,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT InterfaceOnlyComponentEventEmitter : public ViewEventEmitter { @@ -389,13 +396,12 @@ class JSI_EXPORT InterfaceOnlyComponentEventEmitter : public ViewEventEmitter { bool value; }; - struct OnDire tChange { + struct OnDirectChange { bool value; }; - void onChange(OnChange value) const; - void onDire tChange(OnDire tChange value) const; + void onDirectChange(OnDirectChange value) const; }; } // namespace react } // namespace facebook @@ -419,6 +425,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT ExcludedAndroidComponentEventEmitter : public ViewEventEmitter { @@ -426,7 +433,6 @@ class JSI_EXPORT ExcludedAndroidComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -451,6 +457,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT ExcludedAndroidIosComponentEventEmitter : public ViewEventEmitter { @@ -458,7 +465,6 @@ class JSI_EXPORT ExcludedAndroidIosComponentEventEmitter : public ViewEventEmitt using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -483,6 +489,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT ExcludedIosComponentEventEmitter : public ViewEventEmitter { @@ -490,7 +497,6 @@ class JSI_EXPORT ExcludedIosComponentEventEmitter : public ViewEventEmitter { using ViewEventEmitter::ViewEventEmitter; - }; class JSI_EXPORT MultiFileIncludedNativeComponentEventEmitter : public ViewEventEmitter { @@ -498,7 +504,6 @@ class JSI_EXPORT MultiFileIncludedNativeComponentEventEmitter : public ViewEvent using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -523,6 +528,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT FloatPropNativeComponentEventEmitter : public ViewEventEmitter { @@ -530,7 +536,6 @@ class JSI_EXPORT FloatPropNativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -555,6 +560,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT ImagePropNativeComponentEventEmitter : public ViewEventEmitter { @@ -562,7 +568,6 @@ class JSI_EXPORT ImagePropNativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -587,6 +592,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT InsetsPropNativeComponentEventEmitter : public ViewEventEmitter { @@ -594,7 +600,6 @@ class JSI_EXPORT InsetsPropNativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -619,6 +624,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT Int32EnumPropsNativeComponentEventEmitter : public ViewEventEmitter { @@ -626,7 +632,6 @@ class JSI_EXPORT Int32EnumPropsNativeComponentEventEmitter : public ViewEventEmi using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -651,6 +656,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT IntegerPropNativeComponentEventEmitter : public ViewEventEmitter { @@ -658,7 +664,6 @@ class JSI_EXPORT IntegerPropNativeComponentEventEmitter : public ViewEventEmitte using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -683,6 +688,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT InterfaceOnlyComponentEventEmitter : public ViewEventEmitter { @@ -692,7 +698,6 @@ class JSI_EXPORT InterfaceOnlyComponentEventEmitter : public ViewEventEmitter { struct OnChange { bool value; }; - void onChange(OnChange value) const; }; } // namespace react @@ -717,6 +722,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT MixedPropNativeComponentEventEmitter : public ViewEventEmitter { @@ -724,7 +730,6 @@ class JSI_EXPORT MixedPropNativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -749,6 +754,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT ImageColorPropNativeComponentEventEmitter : public ViewEventEmitter { @@ -756,7 +762,6 @@ class JSI_EXPORT ImageColorPropNativeComponentEventEmitter : public ViewEventEmi using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -781,6 +786,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT NoPropsNoEventsComponentEventEmitter : public ViewEventEmitter { @@ -788,7 +794,6 @@ class JSI_EXPORT NoPropsNoEventsComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -813,6 +818,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT ObjectPropsEventEmitter : public ViewEventEmitter { @@ -820,7 +826,6 @@ class JSI_EXPORT ObjectPropsEventEmitter : public ViewEventEmitter { using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -845,6 +850,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT PointPropNativeComponentEventEmitter : public ViewEventEmitter { @@ -852,7 +858,6 @@ class JSI_EXPORT PointPropNativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -877,6 +882,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT StringEnumPropsNativeComponentEventEmitter : public ViewEventEmitter { @@ -884,7 +890,6 @@ class JSI_EXPORT StringEnumPropsNativeComponentEventEmitter : public ViewEventEm using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -909,6 +914,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT StringPropComponentEventEmitter : public ViewEventEmitter { @@ -916,7 +922,6 @@ class JSI_EXPORT StringPropComponentEventEmitter : public ViewEventEmitter { using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -941,6 +946,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT MultiFile1NativeComponentEventEmitter : public ViewEventEmitter { @@ -948,7 +954,6 @@ class JSI_EXPORT MultiFile1NativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; class JSI_EXPORT MultiFile2NativeComponentEventEmitter : public ViewEventEmitter { @@ -956,7 +961,6 @@ class JSI_EXPORT MultiFile2NativeComponentEventEmitter : public ViewEventEmitter using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react @@ -981,6 +985,7 @@ Map { #include #include + namespace facebook { namespace react { class JSI_EXPORT MultiComponent1NativeComponentEventEmitter : public ViewEventEmitter { @@ -988,7 +993,6 @@ class JSI_EXPORT MultiComponent1NativeComponentEventEmitter : public ViewEventEm using ViewEventEmitter::ViewEventEmitter; - }; class JSI_EXPORT MultiComponent2NativeComponentEventEmitter : public ViewEventEmitter { @@ -996,7 +1000,6 @@ class JSI_EXPORT MultiComponent2NativeComponentEventEmitter : public ViewEventEm using ViewEventEmitter::ViewEventEmitter; - }; } // namespace react diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap index 0853ba4c34c038..2dd8e73764b4c6 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap @@ -707,6 +707,7 @@ Map { */ #include +#include #include #include diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap index 8eeed7604d0d42..d931c4753b08a3 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap @@ -913,6 +913,7 @@ Map { #include #include #include +#include #include #include #include diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap index 1826f646289b8e..bc616a220e0b6a 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap @@ -410,6 +410,10 @@ export const __INTERNAL_VIEW_CONFIG = { topOrientationChange: { registrationName: 'onOrientationChange', }, + + topEventWithMixedPropAttribute: { + registrationName: 'onEventWithMixedPropAttribute', + }, }, validAttributes: { @@ -420,6 +424,7 @@ export const __INTERNAL_VIEW_CONFIG = { onEventDirect: true, onOrientationChange: true, onEnd: true, + onEventWithMixedPropAttribute: true, }), }, }; @@ -465,14 +470,14 @@ export const __INTERNAL_VIEW_CONFIG = { directEventTypes: { paperDirectChange: { - registrationName: 'onDire tChange', + registrationName: 'onDirectChange', }, }, validAttributes: { ...ConditionallyIgnoredEventHandlers({ onChange: true, - onDire tChange: true, + onDirectChange: true, }), }, }; diff --git a/packages/react-native-codegen/src/parsers/flow/components/events.js b/packages/react-native-codegen/src/parsers/flow/components/events.js index 9361f0c005056f..fefa09cefb9f60 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/events.js +++ b/packages/react-native-codegen/src/parsers/flow/components/events.js @@ -93,6 +93,14 @@ function getPropertyType( options: typeAnnotation.types.map(option => option.value), }, }; + case 'UnsafeMixed': + return { + name, + optional, + typeAnnotation: { + type: 'MixedTypeAnnotation', + }, + }; default: (type: empty); throw new Error(`Unable to determine event type for "${name}": ${type}`); diff --git a/packages/react-native-codegen/src/parsers/typescript/components/events.js b/packages/react-native-codegen/src/parsers/typescript/components/events.js index dfd295f6ddce5d..a92931afb136db 100644 --- a/packages/react-native-codegen/src/parsers/typescript/components/events.js +++ b/packages/react-native-codegen/src/parsers/typescript/components/events.js @@ -86,7 +86,6 @@ function getPropertyType( properties: typeAnnotation.members.map(buildPropertiesForEvent), }, }; - case 'TSUnionType': return { name, @@ -96,6 +95,14 @@ function getPropertyType( options: typeAnnotation.types.map(option => option.literal.value), }, }; + case 'UnsafeMixed': + return { + name, + optional, + typeAnnotation: { + type: 'MixedTypeAnnotation', + }, + }; default: (type: empty); throw new Error(`Unable to determine event type for "${name}": ${type}`);